以编程方式截取特定区域的屏幕截图

时间:2012-01-02 15:58:01

标签: objective-c uiwebview screenshot area

就像您在我的代码中看到的那样,我会截取屏幕截图并将其保存到相册中。

//for retina displays
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
    UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
} else {
    UIGraphicsBeginImageContext(self.view.bounds.size);
}
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);

一开始我使用了webview.size而不是self.view.bounds.size,因为视图位于0/0,所以它正常运行。但是现在我将WebView集中在一起,但是对于给定的大小,图片从0/0开始。

如何针对给定尺寸配置屏幕截图从另一个location(例如300/150)开始?

或者是否有其他方式来拍摄UIWebView

4 个答案:

答案 0 :(得分:23)

您需要进行两项更改才能获取部分屏幕:

  1. 创建一个较小的图像 - 使用您想要捕获的矩形的大小。
  2. 将您正在渲染的上下文的原点移动到您要捕获的矩形的负x / y。
  3. 之后,您只需将图层渲染到上下文中,就可以得到您想要的内容。像这样的东西应该这样做:

    CGRect grabRect = CGRectMake(40,40,300,200);
    
    //for retina displays
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
        UIGraphicsBeginImageContextWithOptions(grabRect.size, NO, [UIScreen mainScreen].scale);
    } else {
        UIGraphicsBeginImageContext(grabRect.size);
    }
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(ctx, -grabRect.origin.x, -grabRect.origin.y);
    [self.view.layer renderInContext:ctx];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
    

答案 1 :(得分:10)

我已经采取并测试了上面的@escrafford的答案,并让它工作得很好。我在UIView上将它作为类别方法的上下文中进行了测试,因此'grabRect'可以是参数化的。这是代码,作为返回UIImageView的UIView类别:

/**
 Takes a screenshot of a UIView at a specific point and size, as denoted by
 the provided croppingRect parameter. Returns a UIImageView of this cropped
 region.

 CREDIT: This is based on @escrafford's answer at http://stackoverflow.com/a/15304222/535054
*/
- (UIImageView *)rp_screenshotImageViewWithCroppingRect:(CGRect)croppingRect {
    // For dealing with Retina displays as well as non-Retina, we need to check
    // the scale factor, if it is available. Note that we use the size of teh cropping Rect
    // passed in, and not the size of the view we are taking a screenshot of.
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
        UIGraphicsBeginImageContextWithOptions(croppingRect.size, YES, [UIScreen mainScreen].scale);
    } else {
        UIGraphicsBeginImageContext(croppingRect.size);
    }

    // Create a graphics context and translate it the view we want to crop so
    // that even in grabbing (0,0), that origin point now represents the actual
    // cropping origin desired:
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(ctx, -croppingRect.origin.x, -croppingRect.origin.y);
    [self.layer renderInContext:ctx];

    // Retrieve a UIImage from the current image context:
    UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // Return the image in a UIImageView:
    return [[UIImageView alloc] initWithImage:snapshotImage];
}

答案 2 :(得分:2)

我解决了我的问题,但没有回答这个问题:

我创建了一个UIView的子类,并在那里移动了UIWebView,因此它相对于子类位于0/0。然后使用WebView的大小:

UIGraphicsBeginImageContext(webview.frame.size);

以及上面的其他代码。

现在您可以将子类移动到您想要的每个位置。

注意:如果您有日期/时间标签等标签,则必须移动它们,否则您将无法在图片上看到它们。

  

因此,创建UIView的子类并移动您想要的每个IBOutlet   在那里的照片上看到。

问题仍然存在: 那么可以拍摄一下屏幕特定区域的照片吗?

亲切的问候。 $ H @ RKY

答案 3 :(得分:0)

- (void)drawRect:(CGRect)rect {
  UIGraphicsBeginImageContext(self.bounds.size);    
  [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
  UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
  UIGraphicsEndImageContext();
  UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);  
}

您可以将此调用给您的观点:]