一. 关于监听手机截图
1. 背景: 发现商品的售价页总是被人转发截图,为了方便用户添加截图分享的小功能
首先要注册用户截屏操作的通知
- (void)viewDidLoad { [super viewDidLoad]; //注册用户的截屏操作通知 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(userDidTakeScreenshot:) name:UIApplicationUserDidTakeScreenshotNotification object: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的截图分享,小程序分享的关于图片的总结.希望帮助到需要的人.