编程实现对特定区域进行截屏

16

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

//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开始。

如何配置截图从另一个位置(例如300/150)开始呢?

或者还有其他方法可以对UIWebView进行截图吗?


这个能在桌面版的OSX上运行还是只能在iPhone上? - Noitidart
4个回答

22

为了只截取屏幕的一部分,您需要进行两个更改:

  1. 创建一个较小的图像 - 使用您想要捕获的矩形的大小。
  2. 将您正在渲染的上下文的原点移动为您想要捕获的矩形的负x/y。

之后,您只需像以前一样将该层渲染到上下文中,您应该可以得到您要查找的内容。类似这样的内容应该就可以了:

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);

这让我的应用程序崩溃了。你有什么想法吗?我已经添加了QuartzCore框架并把这段代码放在一个函数中,但还是不行。 - rebellion
@rebellion - 我已经让它工作了。虽然不在照片集中。请看下面我对UIView类别方法的改编。 - idStar
谢谢,这对我非常有帮助。只是有一个小问题,图片的背景颜色是白色,我想要透明的。我该怎么做呢?请帮忙。 - iMemon
1
图片的背景颜色是白色,因为我上传的是jpeg格式的图片而不是png格式的图片。上面的代码是完美的 :) - iMemon

9

我已经采用并测试了@escrafford上面的答案,成功地让它工作。 我在将其变为UIView类别方法的上下文中进行了测试,以便可以对“grabRect”进行参数化。 下面是该代码,作为一个UIView类别,返回一个UIImageView:

/**
 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 https://dev59.com/62oy5IYBdhLWcg3wN7UX#15304222
*/
- (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];
}

这段代码当然是假设使用ARC,并且在iOS6.1上是当前的(一个可行的解决方案)。 - idStar

2
我解决了我的问题,但没有回答这个问题:
我创建了一个UIView的子类并将我的UIWebView移到了其中,使得它相对于子类位于0/0。然后使用WebView的大小:
UIGraphicsBeginImageContext(webview.frame.size);

现在你可以将子类移动到任何想要的位置。

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

因此,请创建一个UIView的子类,并将您希望在图片上看到的每个IBOutlet放入其中。

问题仍然存在: 那么,是否可能拍摄屏幕的特定区域?

祝好。$h@rky


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

您可以在视图中调用此函数:]

当Web视图创建时,将调用drawRect方法 - 因此我在开始时有一张灰色图片。我从中得到的想法是将代码拖放到我的自定义UIView类中,在那里我的Web视图位于0/0。这很有效,但我不再看到标签,因为它是“根视图”的一部分。 - Sharky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接