如何截取UIScrollView可见区域的截图?

如何获取UIScrollView可见区域的1:1截图? 内容可能大于或小于UIScrollView边界以及半隐藏(我已经实现了自定义滚动较小的内容,所以它不在左上angular)。 我已经在模拟器上达到了预期的效果,但是在设备本身没有达到:

-(UIImage *)imageFromCombinedContext:(UIView *)background { UIImage *image; CGRect vis = background.bounds; CGSize size = vis.size; UIGraphicsBeginImageContext(size); [background.layer affineTransform]; [background.layer renderInontext:UIGraphicsGetCurrentContext()]; image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); CGImageRef imref = CGImageCreateWithImageInRect([image CGImage], vis); image = [UIImage imageWithCGImage:imref]; CGImageRelease(imref); return image; } 

另一种方法是使用contentOffset来调整图层的可见区域并捕获UIScrollView的当前可见区域。

 UIScrollView *contentScrollView;....//scrollview instance UIGraphicsBeginImageContextWithOptions(contentScrollView.bounds.size, YES, [UIScreen mainScreen].scale); //this is the key CGPoint offset=contentScrollView.contentOffset; CGContextTranslateCTM(UIGraphicsGetCurrentContext(), -offset.x, -offset.y); [contentScrollView.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *visibleScrollViewImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

干杯:)

我自己find了一个解决scheme – 我截取了整个视图的截图,然后裁剪到UIScrollView框架的大小和位置。

 -(UIImage *)imageFromCombinedContext:(UIView *)background { UIImage *image; CGSize size = self.view.frame.size; UIGraphicsBeginImageContext(size); [background.layer affineTransform]; [self.view.layer.layer renderInContext:UIGraphicsGetCurrentContext()]; image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); CGImageRef imgRef = CGImageCreateWithImageInRect([image CGImage],background.frame); image = [UIImage imageWithCGImage:imref]; CGImageRelease(imref); return image; } 

杰弗瑞孙有正确的答案。 只要把你的滚动视图在另一个视图。 获取容器视图以在上下文中呈现。 完成。

在下面的代码中,cropView包含要捕获的滚动视图。 解决scheme就是这么简单。

正如我理解的问题,为什么我发现这个页面,滚动视图的整个内容是不需要的 – 只是可见的部分。

 func captureCrop() -> UIImage { UIGraphicsBeginImageContextWithOptions(self.cropView.frame.size, true, 0.0) self.cropView.layer.renderInContext(UIGraphicsGetCurrentContext()) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image; } 

迅速版本的Abduliam Rehmanius回答。

 func screenshot() -> UIImage { UIGraphicsBeginImageContextWithOptions(self.scrollCrop.bounds.size, true, UIScreen.mainScreen().scale); //this is the key let offset:CGPoint = self.scrollCrop.contentOffset; CGContextTranslateCTM(UIGraphicsGetCurrentContext(), -offset.x, -offset.y); self.scrollCrop.layer.renderInContext(UIGraphicsGetCurrentContext()!); let visibleScrollViewImage: UIImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return visibleScrollViewImage; } 

@Abduliam Rehmanius的答案性能不佳,因为如果UIScrollView包含一个大的内容区域,我们将绘制整个内容区域(甚至在可见边界之外)。 @ Concuror的答案有问题,它也将绘制在UIScrollView之上的任何东西。

我的解决scheme是将UIScrollView放在一个名为containerViewUIView containerView ,使用相同的边界,然后渲染containerView

 containerView.renderInContext(context) 

Swift 3.0:

  func captureScreen() -> UIImage? { UIGraphicsBeginImageContextWithOptions(self.yourScrollViewName.bounds.size, true, UIScreen.main.scale) let offset:CGPoint = self.yourScrollViewName.contentOffset; UIGraphicsGetCurrentContext()!.translateBy(x: -offset.x, y: -offset.y); self.yourScrollViewName.layer.render(in: UIGraphicsGetCurrentContext()!) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image } 

并将其用作:let Image = captureScreen()

在@Concuror代码上更新swift 3+,4

 func getImage(fromCombinedContext background: UIView) -> UIImage { var image: UIImage? let size: CGSize = view.frame.size UIGraphicsBeginImageContext(size) background.layer.affineTransform() view.layer.render(in: UIGraphicsGetCurrentContext()!) image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() let imgRef = image?.cgImage?.cropping(to: background.frame) image = UIImage(cgImage: imgRef!) // CGImageRelease(imgRef!) // Removing on Swift - 'CGImageRelease' is unavailable: Core Foundation objects are automatically memory managed return image ?? UIImage() }