iOS 关于监听手机截图,UIView生成UIImage, UIImage裁剪与压缩的总结
程序员文章站
2022-03-25 07:58:48
一. 关于监听手机截图 1. 背景: 发现商品的售价页总是被人转发截图,为了方便用户添加截图分享的小功能 首先要注册用户截屏操作的通知 之后人为截图 人为截图,在这里可以对图片进行一些操作,比如添加自己的APP二维码啥的类似微博 当然最后不要忘记注销通知,这里要注意,根据需求来,如果商品详情页又可以 ......
一. 关于监听手机截图
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的截图分享,小程序分享的关于图片的总结.希望帮助到需要的人.
上一篇: 4种PHP异步执行的常用方式
下一篇: 利用ASP制作EXECL报表方法(一)