推荐一个第三方好用的框架:SDScreenshotCapture
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
一、全屏截图
UIImage *getImageWithFullScreenshot(void) { // Source (Under MIT License): https://github.com/shinydevelopment/SDScreenshotCapture/blob/master/SDScreenshotCapture/SDScreenshotCapture.m#L35 BOOL ignoreOrientation = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0"); UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; CGSize imageSize = CGSizeZero; if (UIInterfaceOrientationIsPortrait(orientation) || ignoreOrientation) imageSize = [UIScreen mainScreen].bounds.size; else imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width); UIGraphicsBeginImageContextWithOptions(imageSize, NO, [UIScreen mainScreen].scale); 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); // Correct for the screen orientation if(!ignoreOrientation) { if(orientation == UIInterfaceOrientationLandscapeLeft) { CGContextRotateCTM(context, (CGFloat)M_PI_2); CGContextTranslateCTM(context, 0, -imageSize.width); } else if(orientation == UIInterfaceOrientationLandscapeRight) { CGContextRotateCTM(context, (CGFloat)-M_PI_2); CGContextTranslateCTM(context, -imageSize.height, 0); } else if(orientation == UIInterfaceOrientationPortraitUpsideDown) { CGContextRotateCTM(context, (CGFloat)M_PI); CGContextTranslateCTM(context, -imageSize.width, -imageSize.height); } } if([window respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) [window drawViewHierarchyInRect:window.bounds afterScreenUpdates:NO]; else [window.layer renderInContext:UIGraphicsGetCurrentContext()]; CGContextRestoreGState(context); } UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; }
二、修改部分区域截图
以下代码是UIWindow的Category
h文件
#import <UIKit/UIKit.h> @interface UIWindow (Category) - (UIImage *)screenshot; - (UIImage *)screenshotWithRect:(CGRect)rect; @end
m文件
#import "UIWindow+Category.h" @implementation UIWindow (Category) - (UIImage *)screenshot { return [self screenshotWithRect:self.bounds]; } - (UIImage *)screenshotWithRect:(CGRect)rect { // Source (Under MIT License): https://github.com/shinydevelopment/SDScreenshotCapture/blob/master/SDScreenshotCapture/SDScreenshotCapture.m#L35 BOOL ignoreOrientation = SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0"); UIInterfaceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; CGSize imageSize = CGSizeZero; CGFloat width = rect.size.width, height = rect.size.height; CGFloat x = rect.origin.x, y = rect.origin.y; // imageSize = CGSizeMake(width, height); // UIGraphicsBeginImageContextWithOptions(imageSize, NO, [UIScreen mainScreen].scale); if (UIInterfaceOrientationIsPortrait(orientation) || ignoreOrientation) { //imageSize = [UIScreen mainScreen].bounds.size; imageSize = CGSizeMake(width, height); x = rect.origin.x, y = rect.origin.y; } else { //imageSize = CGSizeMake([UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width); imageSize = CGSizeMake(height, width); x = rect.origin.y, y = rect.origin.x; } UIGraphicsBeginImageContextWithOptions(imageSize, NO, [UIScreen mainScreen].scale); CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSaveGState(context); CGContextTranslateCTM(context, self.center.x, self.center.y); CGContextConcatCTM(context, self.transform); CGContextTranslateCTM(context, -self.bounds.size.width * self.layer.anchorPoint.x, -self.bounds.size.height * self.layer.anchorPoint.y); // Correct for the screen orientation if(!ignoreOrientation) { if(orientation == UIInterfaceOrientationLandscapeLeft) { CGContextRotateCTM(context, (CGFloat)M_PI_2); CGContextTranslateCTM(context, 0, -self.bounds.size.height); CGContextTranslateCTM(context, -x, y); } else if(orientation == UIInterfaceOrientationLandscapeRight) { CGContextRotateCTM(context, (CGFloat)-M_PI_2); CGContextTranslateCTM(context, -self.bounds.size.width, 0); CGContextTranslateCTM(context, x, -y); } else if(orientation == UIInterfaceOrientationPortraitUpsideDown) { CGContextRotateCTM(context, (CGFloat)M_PI); CGContextTranslateCTM(context, -self.bounds.size.height, -self.bounds.size.width); CGContextTranslateCTM(context, x, y); } else { CGContextTranslateCTM(context, -x, -y); } } else { CGContextTranslateCTM(context, -x, -y); } //[self layoutIfNeeded]; if([self respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:NO]; else [self.layer renderInContext:UIGraphicsGetCurrentContext()]; CGContextRestoreGState(context); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); return image; } @end
注意:此代码在旋转后,裁剪区域是相对左上角为原点旋转的,一般使用不到旋转情况
View截图
h文件
@interface UIView (Screenshot) - (UIImage *)screenshot; - (UIImage *)screenshotWithRect:(CGRect)rect; @end
m文件
@implementation UIView (Screenshot) - (UIImage *)screenshot { return [self screenshotWithRect:self.bounds]; } - (UIImage *)screenshotWithRect:(CGRect)rect; { UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale); CGContextRef context = UIGraphicsGetCurrentContext(); if (context == NULL) { return nil; } CGContextSaveGState(context); CGContextTranslateCTM(context, -rect.origin.x, -rect.origin.y); //[self layoutIfNeeded]; if( [self respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) { [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:NO]; } else { [self.layer renderInContext:context]; } CGContextRestoreGState(context); UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); // NSData *imageData = UIImageJPEGRepresentation(image, 1); // convert to jpeg // image = [UIImage imageWithData:imageData scale:[UIScreen mainScreen].scale]; return image; }