以编程方式截取特定区域的屏幕截图
Posted
技术标签:
【中文标题】以编程方式截取特定区域的屏幕截图【英文标题】:Programmatically take a screenshot of specific area 【发布时间】:2012-01-31 22:27:41 【问题描述】:就像您在我的代码中看到的那样,我截取了一个屏幕截图并将其保存到相册中。
//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
拍照吗?
【问题讨论】:
这适用于桌面 OSX 还是仅适用于 iphone? 【参考方案1】:您需要进行两项更改才能只抓取屏幕的一部分:
-
创建较小的图像 - 使用您要捕获的矩形大小。
将要渲染的上下文的原点移动到要捕获的矩形的负 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 - 我已经让它工作了。虽然相册里没有。请参阅下面的我的改编作为 UIView 类别方法。 谢谢,这对我很有用。只是图像背景颜色是白色的小问题,我希望它透明。我怎样才能做到这一点。请帮忙 图像背景颜色为白色,因为我上传的是 jpeg 图像而不是 png 图像。上面的代码很完美:)【参考方案2】:我已经接受并测试了上面@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://***.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];
【讨论】:
这段代码当然是假设 ARC 并且在 ios6.1 上是最新的(一个有效的解决方案)。【参考方案3】:我解决了我的问题,但没有回答问题:
我创建了一个UIView
的子类并将我的UIWebView
移到其中,使其相对于子类位于0/0。然后使用WebView的大小:
UIGraphicsBeginImageContext(webview.frame.size);
以及上面的其他代码。
现在您可以将子类移动到您想要的每个位置。
注意:如果您有日期/时间标签之类的标签,您也必须移动它们,否则图片上将看不到它们。
所以创建一个
UIView
的子类并移动你想成为的每个IBOutlet
在里面的图片上看到。
问题仍然悬而未决: 那么是否可以对屏幕的特定区域进行拍照呢?
亲切的问候。 $h@rky
【讨论】:
【参考方案4】:- (void)drawRect:(CGRect)rect
UIGraphicsBeginImageContext(self.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
您可以将其称为您的视图:]
【讨论】:
在创建 web 视图时调用 drawRect 方法 - 所以我在开始时有一个灰色的图片。我从中得到的想法是将代码拖放到我的 Web 视图位于 0/0 的自定义 UIView 类中。那行得通,但我再也看不到标签了,因为它是“根视图”的一部分。以上是关于以编程方式截取特定区域的屏幕截图的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Android 上以编程方式截取屏幕截图? [复制]