I want to capture a particular portion of iPhone screen. I used UIGraphicsBeginImageContextWithOptions
, but couldn't capture a portion of screen with this.
Please help me.

- 5,434
- 4
- 43
- 70

- 135
- 1
- 2
- 8
-
you want to capture a screen shot from your machine or you want to capture a area in your app through code? – mAc Oct 27 '11 at 11:59
-
2@mAc obviously he want to do it with code..if not why he use UIGraphicsBeginImageContextWithOptions – Krishnabhadra Oct 27 '11 at 12:30
6 Answers
you can use this code
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGRect rect = CGRectMake(250,61 ,410, 255);
CGImageRef imageRef = CGImageCreateWithImageInRect([viewImage CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef];
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
CGImageRelease(imageRef);
-
3this is helpful when you have to capture specific area of your screen. – priyanka Jul 16 '12 at 07:42
-
I got the particular part by this. But in some views, it is hiding its content. Can you give some idea why its happening? – Niharika Jan 03 '18 at 06:29
-
Just FYI for future Googlers: this code does not account for screen scale – Sam Spencer Nov 15 '18 at 18:47
You can take screen shot using UIGraphicsGetImageFromCurrentContext
. Wrote below code from memory, so errors possible. Please correct it yourself.
- (UIImage*)captureView:(UIView *)yourView {
CGRect rect = [[UIScreen mainScreen] bounds];
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[yourView.layer renderInContext:context];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

- 34,169
- 30
- 118
- 167
Here's a swift extension on UIView
that will either capture the entire view or a frame within the view. It takes into account the screen scale.
extension UIView {
func imageSnapshot() -> UIImage {
return self.imageSnapshotCroppedToFrame(nil)
}
func imageSnapshotCroppedToFrame(frame: CGRect?) -> UIImage {
let scaleFactor = UIScreen.mainScreen().scale
UIGraphicsBeginImageContextWithOptions(bounds.size, false, scaleFactor)
self.drawViewHierarchyInRect(bounds, afterScreenUpdates: true)
var image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
if let frame = frame {
// UIImages are measured in points, but CGImages are measured in pixels
let scaledRect = CGRectApplyAffineTransform(frame, CGAffineTransformMakeScale(scaleFactor, scaleFactor))
if let imageRef = CGImageCreateWithImageInRect(image.CGImage, scaledRect) {
image = UIImage(CGImage: imageRef)
}
}
return image
}
}

- 941
- 11
- 13
-
1Hi, jDutton. I loved your answer. Decided to update your code for Swift 3.0. – Jon Vogel Feb 16 '17 at 02:02
-
the answer by @Superdev is right on spot , what i want to add is a little trick if you want to capture a parent view and avoid subviews ( in particular overlay view ) what you can do is make this subview a property and use the following
CGFloat width = CGRectGetWidth(self.view.bounds);
CGFloat height = CGRectGetHeight(self.view.bounds);
_overlayView.hidden = YES;
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGRect rect = CGRectMake(0,0 ,width, height);
CGImageRef imageRef = CGImageCreateWithImageInRect([viewImage CGImage], rect);
UIImage *img = [UIImage imageWithCGImage:imageRef];
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
CGImageRelease(imageRef);
_overlayView.hidden = NO;
its a small trick , hope someone will find it useful

- 7,880
- 1
- 23
- 33
Another method to capture clear screenshot;
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
UIGraphicsBeginImageContextWithOptions(self.captureView.frame.size, NO, [UIScreen mainScreen].scale);
else
UIGraphicsBeginImageContext(self.captureView.frame.size);
[self.captureView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
[viewImage drawInRect:CGRectMake(0.0, 0.0, 640,960)];
//NSData*m_Imgdata=UIImagePNGRepresentation(viewImage);
NSData*m_Imgdata=UIImageJPEGRepresentation(viewImage, 1.0);
// UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
UIGraphicsEndImageContext();

- 562
- 7
- 13
SWIFT 3.0 Xcode8 Version come from @jDutton answer and work for me.
extension UIView {
func imageSnapshot() -> UIImage {
return self.imageSnapshotCroppedToFrame(frame: nil)
}
func imageSnapshotCroppedToFrame(frame: CGRect?) -> UIImage {
let scaleFactor = UIScreen.main.scale
UIGraphicsBeginImageContextWithOptions(bounds.size, false, scaleFactor)
self.drawHierarchy(in: bounds, afterScreenUpdates: true)
var image: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
if let frame = frame {
// UIImages are measured in points, but CGImages are measured in pixels
let scaledRect = frame.applying(CGAffineTransform(scaleX: scaleFactor, y: scaleFactor))
if let imageRef = image.cgImage!.cropping(to: scaledRect) {
image = UIImage(cgImage: imageRef)
}
}
return image
}
}
if you crash and get the following message:
GContextSaveGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
CGContextRestoreGState: invalid context 0x0. If you want to see the backtrace, please set CG_CONTEXT_SHOW_BACKTRACE environmental variable.
try this solution
Hope for saving your time!