How do I take a 1:1 screenshot of UIScrollView visible area? The content may be larger or smaller than UIScrollView bounds as well as half-hidden (I've implemented custom scrolling for smaller content, so it's not in the top-left corner). I've achieved desired result on simulator, but not on device itself:
-(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;
}
Swift version of Abduliam Rehmanius answer.
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;
}
Swift 4 version:
func screenshot() -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.scrollCrop.bounds.size, false, UIScreen.main.scale)
let offset = self.scrollCrop.contentOffset
let thisContext = UIGraphicsGetCurrentContext()
thisContext?.translateBy(x: -offset.x, y: -offset.y)
self.scrollCrop.layer.render(in: thisContext!)
let visibleScrollViewImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return visibleScrollViewImage
}
Another approach would be to use the contentOffset
to adjust the layer's visible area and capture only the currently visible area of 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();
Cheers :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With