iOS: what's the fastest, most performant way to make a screenshot programmatically?
I've found a better method that uses the snapshot API whenever possible.
I hope it helps.
class func screenshot() -> UIImage {
var imageSize = CGSize.zero
let orientation = UIApplication.shared.statusBarOrientation
if UIInterfaceOrientationIsPortrait(orientation) {
imageSize = UIScreen.main.bounds.size
} else {
imageSize = CGSize(width: UIScreen.main.bounds.size.height, height: UIScreen.main.bounds.size.width)
}
UIGraphicsBeginImageContextWithOptions(imageSize, false, 0)
for window in UIApplication.shared.windows {
window.drawHierarchy(in: window.bounds, afterScreenUpdates: true)
}
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image!
}
Wanna know more about iOS 7 Snapshots?
Objective-C version:
+ (UIImage *)screenshot
{
CGSize imageSize = CGSizeZero;
UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation;
if (UIInterfaceOrientationIsPortrait(orientation)) {
imageSize = [UIScreen mainScreen].bounds.size;
} else {
imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
}
UIGraphicsBeginImageContextWithOptions(imageSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
CGContextSaveGState(context);
CGContextTranslateCTM(context, window.center.x, window.center.y);
CGContextConcatCTM(context, window.transform);
CGContextTranslateCTM(context, -window.bounds.size.width * window.layer.anchorPoint.x, -window.bounds.size.height * window.layer.anchorPoint.y);
if (orientation == UIInterfaceOrientationLandscapeLeft) {
CGContextRotateCTM(context, M_PI_2);
CGContextTranslateCTM(context, 0, -imageSize.width);
} else if (orientation == UIInterfaceOrientationLandscapeRight) {
CGContextRotateCTM(context, -M_PI_2);
CGContextTranslateCTM(context, -imageSize.height, 0);
} else if (orientation == UIInterfaceOrientationPortraitUpsideDown) {
CGContextRotateCTM(context, M_PI);
CGContextTranslateCTM(context, -imageSize.width, -imageSize.height);
}
if ([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) {
[window drawViewHierarchyInRect:window.bounds afterScreenUpdates:YES];
} else {
[window.layer renderInContext:context];
}
CGContextRestoreGState(context);
}
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
Screenshot the top most layer/view
Check out this post: Why don't added sublayers show up in screenshot?
Seems that sublayers aren't handled by the renderInContext method.
When you want to capture a screenshot try storing a frame from the preview layer in a UIImageView then you should be able to manually put that frame underneath your mask and just screenshot the superview.
Why does my programmatically created screenshot look so bad on iOS 7?
New API has been added since iOS 7, that should provide efficient way of getting snapshot
snapshotViewAfterScreenUpdates:
renders the view into a UIView with unmodifiablecontent
resizableSnapshotViewFromRect:afterScreenUpdates:withCapInsets
: same thing, but with resizable insetsdrawViewHierarchyInRect:afterScreenUpdates:
: same thing if you need all subviews to be drawn too (like labels, buttons...)
You can use the UIView
returned for any UI effect, or render in into an image like you did if you need to export.
I don't know how good this new method performs VS the one you provided (although I remember Apple engineers saying this new API was more efficient)
iOS: can I take screenshot on global queue?
Any UI operation MUST be performed in the main thread.
Take screenshot from camera view
To solve this issue, I'had to switch the video call camera from back to front camera so that user could user the back camera to take photo, once he done with taking photo I switch back the video call to back camera.
How to get 2x image as screen shot?
-(UIImage*)getScreenShot:(CALayer*)layer
{
CGFloat scale = 1.0;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 40000
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]){
scale = [[UIScreen mainScreen] scale];
}
#endif
UIGraphicsBeginImageContextWithOptions(CGSizeMake(layer.frame.size.width*scale, layer.frame.size.height*scale), NO, 0.0);
[layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
How Do I Take a Screen Shot of a UIView?
I think you may want renderInContext
, not drawInContext
. drawInContext is more a method you would override...
Note that it may not work in all views, specifically a year or so ago when I tried to use this with the live camera view it did not work.
How to take an iPhone screenshot of entire view including parts off screen?
Just pasting some code I used in my app. It draws a view to an image (potentially scaling).
Maybe you could programmaticaly scroll the table and stitch the images together in the end or something similar:
+ (UIImage *)captureView: (UIView *)view inSize: (CGSize)size
{
UIGraphicsBeginImageContext(size);
CGSize viewSize = view.frame.size;
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextScaleCTM( context, size.width/viewSize.width, size.height/viewSize.height);
[view.layer renderInContext: UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}
Hope it helps
Related Topics
In iPhone App How to Detect the Screen Resolution of the Device
What Is the Height of Iphone's Onscreen Keyboard
Iad Is Shutting Down. Should I Remove the Iad Framework from All My Applications
How to Detect the Touch Event of an Uiimageview
No Avplayer Delegate? How to Track When Song Finished Playing? Objective C iPhone Development
Combine Framework: How to Process Each Element of Array Asynchronously Before Proceeding
iOS Perform Action After Period of Inactivity (No User Interaction)
Xmppframework - Implement Group Chat (Muc)
Allow Only Alphanumeric Characters for a Uitextfield
Passing Image to Another View Controller (Swift)
Comparing Nsdates Without Time Component
Extract Uiimage from Nsattributed String
How to Check If a View Controller Is Presented Modally or Pushed on a Navigation Stack
How to Create Layout Constraints Programmatically
Does H.264 Encoded Video with Bt.709 Matrix Include Any Gamma Adjustment