如何从UIWebView获取包含屏幕外内容的整体图像

时间:2012-03-26 23:41:27

标签: iphone ios uiwebview uiimage

我使用一种方法从iOS应用程序中的各种视图中获取图像,以便让用户通过电子邮件发送屏幕。我绘制的大多数屏幕都工作正常,但是当我使用UIWebView的这种技术时,我只得到屏幕的可见部分。屏幕外的任何内容都不包含在渲染图像中。在Stack上一直在这里挖掘,但到目前为止我找不到任何作品?!

以下是我目前使用的方法:

-(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;
}

4 个答案:

答案 0 :(得分:5)

哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇哇它奏效了!

警告:不保证你不会遇到这个问题,我建议你在@autoreleasepool池中做这个,并考虑做一些扩展,就像我在示例中所做的那样,但是这个工作并且是我定居的:

-(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
}

答案 1 :(得分:1)

我刚刚为此创建了一个类别。当(并且仅当)Web视图缓存到内存中时,它才有效,否则页面的某些部分将显示为白色。

#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

答案 2 :(得分:0)

您可以缩小uiwebview以使所有内容都适合屏幕...但这仅在图像水平偏离屏幕时才有效。如果UIWebView比屏幕长,那么这不会做太多。

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

答案 3 :(得分:0)

WKWebView最近有一种更方便的方法

将此委托分配给webviews导航委托,并实现完成处理程序以获取图像

class WebviewDelegate: NSObject, WKNavigationDelegate {

    var completion: ((UIImage?) -> ())?

    func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
        webView.evaluateJavaScript("document.body.offsetHeight;") { (result, error) in
            if let height = result as? CGFloat {
                let config = WKSnapshotConfiguration()
                config.rect = CGRect(x: 0, y: 0, width: webView.scrollView.contentSize.width, height: height)

                webView.takeSnapshot(with: config) { (image, error) in
                    self.completion?(image)
                }
            }
        }
    }
}