How to get FULL image from UIWebView including offscreen content

I have a method that I use to get images from different views in an iOS app in order to allow users to create email screens. Most of the screens I draw on work fine, but when I use this technique with the UIWebView, I only get the visible portion of the screen. Anything outside the screen is not displayed in the displayed image. Dug around here on the Stack but so far nothing I've found working ?!

Here's the method I'm currently using:

-(NSData *)getImageFromView:(UIView *)view
{
    NSData *pngImg;
    CGFloat max, scale = 1.0;
    CGSize size = [view bounds].size;

    // Scale down larger images else we run into mem issues with mail widget
    max = (size.width > size.height) ? size.width : size.height;
    if( max > 960 )
        scale = 960/max;

    UIGraphicsBeginImageContextWithOptions( size, YES, scale );

    CGContextRef context = UIGraphicsGetCurrentContext();
    [view.layer renderInContext:context];    
    pngImg = UIImagePNGRepresentation( UIGraphicsGetImageFromCurrentImageContext() );

    UIGraphicsEndImageContext();    
    return pngImg;
}

      

+3


source to share


3 answers


Wow, the answer was stupidly simple ... digging all over the place looking at various print / PDF related stuff ... then it occurred to me why not just set the view IN CONTEXT to sizeThatFits. It worked!

WARNING. Don't guarantee you don't run into memory issues with this, and I suggest you do it in the @autoreleasepool and consider doing some sort of scaling like I do in the example, but THIS WORKS and this is it.



-(NSData *)getImageFromView:(UIView *)view  // Mine is UIWebView but should work for any
{
    NSData *pngImg;
    CGFloat max, scale = 1.0;
    CGSize viewSize = [view bounds].size;

    // Get the size of the the FULL Content, not just the bit that is visible
    CGSize size = [view sizeThatFits:CGSizeZero];

    // Scale down if on iPad to something more reasonable
    max = (viewSize.width > viewSize.height) ? viewSize.width : viewSize.height;
    if( max > 960 )
        scale = 960/max;

    UIGraphicsBeginImageContextWithOptions( size, YES, scale );

    // Set the view to the FULL size of the content.
    [view setFrame: CGRectMake(0, 0, size.width, size.height)];

    CGContextRef context = UIGraphicsGetCurrentContext();
    [view.layer renderInContext:context];    
    pngImg = UIImagePNGRepresentation( UIGraphicsGetImageFromCurrentImageContext() );

    UIGraphicsEndImageContext();
    return pngImg;    // Voila an image of the ENTIRE CONTENT, not just visible bit
}

      

+5


source


I created a category for this a while ago. It works if (and only if) the web view is cached in memory, otherwise parts of the page will appear white.



#import "UIWebView+Screenshot.h"
#import <QuartzCore/QuartzCore.h>

@implementation UIWebView (Screenshot)

- (UIImage *)screenshot {
UIImage *img = nil;

    UIGraphicsBeginImageContextWithOptions(self.scrollView.contentSize, self.scrollView.opaque, 0.0);
    {
        CGPoint savedContentOffset = self.scrollView.contentOffset;
        CGRect savedFrame = self.scrollView.frame;

        self.scrollView.contentOffset = CGPointZero;
        self.scrollView.frame = CGRectMake(0, 0, self.scrollView.contentSize.width, self.scrollView.contentSize.height);
        [self.scrollView.layer renderInContext: UIGraphicsGetCurrentContext()];
        img = UIGraphicsGetImageFromCurrentImageContext();

        self.scrollView.contentOffset = savedContentOffset;
        self.scrollView.frame = savedFrame;
    }
    UIGraphicsEndImageContext();

    return img;
}

@end

      

+1


source


You can enlarge the uiwebview image so that all content is on screen ... but this will only work if the image is not displayed horizontally. If the UIWebView is longer than the screen, it won't do much.

[webview.scrollView setZoomScale:webview.scrollView.minimumZoomScale animated:NO];

      

0


source







All Articles