iOS 關於監聽手機截圖,UIView生成UIImage, UIImage裁剪與壓縮的總結
阿新 • • 發佈:2018-12-26
一. 關於監聽手機截圖
1. 背景: 發現商品的售價頁總是被人轉發截圖,為了方便使用者新增截圖分享的小功能
首先要註冊使用者截圖操作的通知
- (void)viewDidLoad { [super viewDidLoad]; //註冊使用者的截圖操作通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userDidTakeScreenshot:) name:UIApplicationUserDidTakeScreenshotNotificationobject:nil]; }
之後人為截圖
// 截圖響應 - (void)userDidTakeScreenshot:(NSNotification *)notification { //人為截圖, 模擬使用者截圖行為, 獲取所截圖片 _screenshotImg = [UIutils imageWithScreenshot]; // 這裡封裝了一下 獲得圖片就可以取分享啦 DhshareActionSheetScreenshot *shareAlert = [[DhshareActionSheetScreenshot alloc] init]; [shareAlert showWithImg:_screenshotImg]; }
人為截圖,在這裡可以對圖片進行一些操作,比如新增自己的APP二維碼啥的類似微博
/** * 擷取當前螢幕 並修改 */ + (UIImage *)imageWithScreenshot { 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; }
當然最後不要忘記登出通知,這裡要注意,根據需求來,如果商品詳情頁又可以跳轉到別的商品詳情頁最好這樣登出,
避免跳到別的商品詳情頁多次截圖
- (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationUserDidTakeScreenshotNotification object:nil]; }
二. UIView生成UIImag
UIView生成UIImage 時可以轉一下jpg格式,這樣圖片不會太大具體引數可以百度,螢幕密度我一般採用0.7;
// UIView生成圖片 +(UIImage*)convertViewToImage:(UIView*)v{ CGSize s = v.bounds.size; // 下面方法,第一個引數表示區域大小。第二個引數表示是否是非透明的。如果需要顯示半透明效果,需要傳NO,否則傳YES。第三個引數就是螢幕密度了 // NSLog(@"[UIScreen mainScreen].scale-%f",[UIScreen mainScreen].scale); // 3.0 高清圖 分享不了 用2.0即可 或者分享的時候壓縮圖片 UIGraphicsBeginImageContextWithOptions(s, YES, [UIScreen mainScreen].scale); [v.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage*image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); NSData * data = UIImageJPEGRepresentation(image, 0.7); UIImage* imagelast = [UIImage imageWithData:data]; return imagelast; }
三. UIImage的裁剪
// 圖片裁剪 + (UIImage *)ct_imageFromImage:(UIImage *)image inRect:(CGRect)rect{ //把像 素rect 轉化為 點rect(如無轉化則按原影象素取部分圖片) CGFloat scale = [UIScreen mainScreen].scale; CGFloat x= rect.origin.x*scale,y=rect.origin.y*scale,w=rect.size.width*scale,h=rect.size.height*scale; CGRect dianRect = CGRectMake(x, y, w, h); //擷取部分圖片並生成新圖片 CGImageRef sourceImageRef = [image CGImage]; CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, dianRect); UIImage *newImage = [UIImage imageWithCGImage:newImageRef scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]; NSData * data = UIImageJPEGRepresentation(newImage, 0.7); UIImage* imagelast = [UIImage imageWithData:data]; return imagelast; }
四. UIImage的壓縮
分享圖片時根據分享的應用不同對圖片大小是有限制的,微信是10M,但是qq小一些,
另外小程式分享的話也是有限制的128Kb,當截圖裁剪後無法滿足時就需要壓縮一下
先是密度壓縮然後大小壓縮,一般都可以解決的
// 圖片壓縮 + (UIImage *)compressImage:(UIImage *)image toByte:(NSUInteger)maxLength { // Compress by quality CGFloat compression = 0.7; //UIImage轉換為NSData NSData *data = UIImageJPEGRepresentation(image, compression); if (data.length < maxLength){ return image; } CGFloat max = 1; CGFloat min = 0; for (int i = 0; i < 6; ++i) { compression = (max + min) / 2; data = UIImageJPEGRepresentation(image, compression); if (data.length < maxLength * 0.9) { min = compression; } else if (data.length > maxLength) { max = compression; } else { break; } } UIImage *resultImage = [UIImage imageWithData:data]; if (data.length < maxLength){ return resultImage; } // Compress by size NSUInteger lastDataLength = 0; while (data.length > maxLength && data.length != lastDataLength) { lastDataLength = data.length; CGFloat ratio = (CGFloat)maxLength / data.length; CGSize size = CGSizeMake((NSUInteger)(resultImage.size.width * sqrtf(ratio)), (NSUInteger)(resultImage.size.height * sqrtf(ratio))); // Use NSUInteger to prevent white blank UIGraphicsBeginImageContext(size); [resultImage drawInRect:CGRectMake(0, 0, size.width, size.height)]; resultImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); data = UIImageJPEGRepresentation(resultImage, compression); } return resultImage; }
這些是最近APP的截圖分享,小程式分享的關於圖片的總結.希望幫助到需要的人.