如何截取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
放在一个名为containerView
的UIView
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() }