Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone UIWebView到UIImage_Iphone_Objective C_Xcode_Uiwebview - Fatal编程技术网

Iphone UIWebView到UIImage

Iphone UIWebView到UIImage,iphone,objective-c,xcode,uiwebview,Iphone,Objective C,Xcode,Uiwebview,我尝试使用此方法从UIWebView捕获图像,但图像仅包含屏幕的可见区域。如何将UIWebView的全部内容(包括不可见区域,即整个网页)捕获到单个图像中 -(UIImage*)captureScreen:(UIView*) viewToCapture{ UIGraphicsBeginImageContext(viewToCapture.bounds.size); [viewToCapture.layer renderInContext:UIGraphicsGetCurrentConte

我尝试使用此方法从UIWebView捕获图像,但图像仅包含屏幕的可见区域。如何将UIWebView的全部内容(包括不可见区域,即整个网页)捕获到单个图像中

-(UIImage*)captureScreen:(UIView*) viewToCapture{
  UIGraphicsBeginImageContext(viewToCapture.bounds.size);
  [viewToCapture.layer renderInContext:UIGraphicsGetCurrentContext()];
  UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  return viewImage;
}
编辑(摘自作者的评论)

解决办法是打电话

webView.scalesPageToFit = YES;
在初始化中,以及

[webView sizeToFit]
当页面完成加载时

您当前仅捕获可见部分,因为您将图像上下文限制为可见部分。你应该把它限制在可用的范围内

UIView
有一个
scrollView
属性,该属性具有
contentSize
,告诉您滚动视图中的web视图的大小。您可以使用该大小设置图像上下文,如下所示:

-(UIImage*)captureScreen:(UIView*) viewToCapture{
    CGSize overallSize = overallSize;
    UIGraphicsBeginImageContext(viewToCapture.scrollView.contentSize);
    // Save the current bounds
    CGRect tmp = viewToCapture.bounds;
    viewToCapture.bounds = CGRectMake(0, 0, overallSize.width, overallSize.height);
    // Wait for the view to finish loading.
    // This is not very nice, but it should work. A better approach would be
    // to use a delegate, and run the capturing on the did finish load event.
    while (viewToCapture.loading) {
         [NSThread sleepForTimeInterval:0.1];
    }
    [viewToCapture.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    // Restore the bounds
    viewToCapture.bounds = tmp;
    return viewImage;
}

编辑:我用测试过的代码给出了新答案

将下面的
方法添加到
捕获
UIWebView
UIImage
中。它还将捕获
不可见区域

- (UIImage*)webviewToImage:(UIWebView*)webView
{
  int currentWebViewHeight = webView.scrollView.contentSize.height;
  int scrollByY = webView.frame.size.height;

  [webView.scrollView setContentOffset:CGPointMake(0, 0)];

  NSMutableArray* images = [[NSMutableArray alloc] init];

  CGRect screenRect = webView.frame;

  int pages = currentWebViewHeight/scrollByY;
  if (currentWebViewHeight%scrollByY > 0) {
      pages ++;
  } 

  for (int i = 0; i< pages; i++)
  {
    if (i == pages-1) {
        if (pages>1)
            screenRect.size.height = currentWebViewHeight - scrollByY;
    }

    if (IS_RETINA)
        UIGraphicsBeginImageContextWithOptions(screenRect.size, NO, 0);
    else
        UIGraphicsBeginImageContext( screenRect.size );
    if ([webView.layer respondsToSelector:@selector(setContentsScale:)]) {
        webView.layer.contentsScale = [[UIScreen mainScreen] scale];
    }
    //UIGraphicsBeginImageContext(screenRect.size);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [[UIColor blackColor] set];
    CGContextFillRect(ctx, screenRect);

    [webView.layer renderInContext:ctx];

    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    if (i == 0)
    {
        scrollByY = webView.frame.size.height;
    }
    else
    {
        scrollByY += webView.frame.size.height;
    }
    [webView.scrollView setContentOffset:CGPointMake(0, scrollByY)];
    [images addObject:newImage];
  }

  [webView.scrollView setContentOffset:CGPointMake(0, 0)];

  UIImage *resultImage;

  if(images.count > 1) {
    //join all images together..
    CGSize size;
    for(int i=0;i<images.count;i++) {

        size.width = MAX(size.width, ((UIImage*)[images objectAtIndex:i]).size.width );
        size.height += ((UIImage*)[images objectAtIndex:i]).size.height;
    }

    if (IS_RETINA)
        UIGraphicsBeginImageContextWithOptions(size, NO, 0);
    else
        UIGraphicsBeginImageContext(size);
    if ([webView.layer respondsToSelector:@selector(setContentsScale:)]) {
        webView.layer.contentsScale = [[UIScreen mainScreen] scale];
    }
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    [[UIColor blackColor] set];
    CGContextFillRect(ctx, screenRect);

    int y=0;
    for(int i=0;i<images.count;i++) {

        UIImage* img = [images objectAtIndex:i];
        [img drawAtPoint:CGPointMake(0,y)];
        y += img.size.height;
    }

    resultImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
  } else {

    resultImage = [images objectAtIndex:0];
  }
  [images removeAllObjects];
  return resultImage;
}
看看这个

或者用这个:):


这部分地解决了问题。生成的图像大小正确,但不可见区域全是白色。@Vad我认为问题与
viewToCapture.layer
有关。查看临时设置边界是否可以解决此问题(请参阅更新)。我认为问题在于,在您滚动到web视图之前,web视图不会显示所有内容。@如果您是对的,则在调用
renderContext:
时,web视图可能仍在加载其他内容。您能否添加
NSLog(@“%d”,viewToCapture.loading)
并查看它是否打印
1
0
?解决方案是在页面完成加载时调用[webView sizeToFit],webView.scalesPageToFit=YES;在初始化中。这会导致图像上的可见内容被拉伸,而不可见内容仍然全部为白色/空白。我测试了一个很长的页面,但当if(images.count>1){~UIGraphicsBeginImageContextWithOptions(size,NO,0)时,应用程序崩溃;由于内存压力。分割是个好主意,但我想在聚合图像时会产生内存压力。你有什么解决方案吗?
#define IS_RETINA ([[UIScreen mainScreen] respondsToSelector:@selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0))
    (UIImage*) imageFromWebview:(UIWebView*) webview{

//store the original framesize to put it back after the snapshot
CGRect originalFrame = webview.frame;

//get the width and height of webpage using js (you might need to use another call, this doesn't work always)
int webViewHeight = [[webview stringByEvaluatingJavaScriptFromString:@"document.body.scrollHeight;"] integerValue];
int webViewWidth = [[webview stringByEvaluatingJavaScriptFromString:@"document.body.scrollWidth;"] integerValue];

//set the webview's frames to match the size of the page
[webview setFrame:CGRectMake(0, 0, webViewWidth, webViewHeight)];

//make the snapshot
UIGraphicsBeginImageContextWithOptions(webview.frame.size, false, 0.0);
[webview.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

//set the webview's frame to the original size
[webview setFrame:originalFrame];

//and VOILA :)
return image;
}