iOS 关于监听手机截图,UIView生成UIImage, UIImage裁剪与压缩的总结
一. 关于监听手机截图
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, );
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, , -imageSize.width);
}else if (orientation == UIInterfaceOrientationLandscapeRight)
{
CGContextRotateCTM(context, -M_PI_2);
CGContextTranslateCTM(context, -imageSize.height, );
} 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 = ;
CGFloat min = ;
for (int i = ; i < ; ++i) {
compression = (max + min) / ;
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 = ;
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(, , size.width, size.height)];
resultImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
data = UIImageJPEGRepresentation(resultImage, compression);
}
return resultImage;
}
这些是最近APP的截图分享,小程序分享的关于图片的总结.希望帮助到需要的人.
iOS 关于监听手机截图,UIView生成UIImage, UIImage裁剪与压缩的总结的更多相关文章
- vue 监听手机键盘是否弹出及input是否聚焦成功
//定义移动端类型 function pageStats() { let u = navigator.userAgent, app = navigator.appVersion; let obj = ...
- 用BroadcastReceiver监听手机网络状态变化
android--解决方案--用BroadcastReceiver监听手机网络状态变化 标签: android网络状态监听方案 2015-01-20 15:23 1294人阅读 评论(3) 收藏 举报 ...
- Android监听手机网络变化
Android监听手机网络变化 手机网络状态发生变化会发送广播,利用广播接收者,监听手机网络变化 效果图 注册广播接收者 <?xml version="1.0" encodi ...
- Android初级教程使用服务注册广播接收者监听手机解锁屏变化
之前第七章广播与服务理论篇写到: 特殊的广播接收者(一般发广播次数频率很高) 安卓中有一些广播接收者,必须使用代码注册,清单文件注册是无效的 屏幕锁屏和解锁 电量改变 今天在这里就回顾一下,且用代码方 ...
- 知识点---js监听手机返回键,回到指定界面
方法一. $(function(){ pushHistory(); window.addEventListener(“popstate”, function(e) { window.location ...
- 使用ionic开发时用遇到监听手机返回按钮的问题~
当时用的是ionic开发一个app,需求是,当按下手机的返回按钮,在指定的页面双击退出,而在其他页面点击一次返回到上个页面: 其实用ionic自带的服务就可以解决: //双击退出 $ionicP ...
- JavaScript监听手机物理返回键的两种解决方法
JavaScript没有监听物理返回键的API,所以只能使用 popstate 事件监听. 有两个解决办法: 1.返回到指定的页面 pushHistory(); window.addEventList ...
- 监听 手机back键和顶部的回退
// 回退事件,监听 手机back键和顶部的回退 pushHistory(); window.addEventListener("popstate", function(e) { ...
- Android之——监听手机开机事件
转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47028535 本文中,主要通过监听开机广播来达到监听手机开机状态的操作.在Andr ...
随机推荐
- 新DevOps八荣八耻
昀哥 20181001以随时可扩容可缩容可重启可切换机房流量为荣,以不能迁移为耻. 以可配置为荣,以硬编码为耻. 以系统互备为荣,以系统单点为耻. 以交付时有监控报警为荣,以交付裸奔系统为耻. 以无状 ...
- ansible copy 模块的使用
copy copy 模块是将 ansible 管理主机上的文件拷贝上远程主机中,与 fetch 相反,如果目标路径不存在,则自动创建,如果 src 的目录带“/” 则复制该目录下的所有东西,如果 sr ...
- Python--开发简单爬虫
简单爬虫架构 动态运行流程 URL管理器的作用 URL管理器的3种实现方式 网页下载器的作用 Python网页下载器的种类 urllib2下载网页的3种方法 网页解析器的作用 Python的几种网页解 ...
- Entity Framework 查漏补缺 (一)
明确EF建立的数据库和对象之间的关系 EF也是一种ORM技术框架, 将对象模型和关系型数据库的数据结构对应起来,开发人员不在利用sql去操作数据相关结构和数据.以下是EF建立的数据库和对象之间关系 关 ...
- 装箱问题的CPLEX求解
装箱问题(Bin Packing Problem) 装箱问题即搬家公司问题.一个搬家公司有无限多的箱子,每个箱子的承重上限为W,当搬家公司进入一个房间时,所有物品都必须被装入箱子,每个物品的重量为wi ...
- 值得一看的35个Redis常用问题总结
1.什么是redis? Redis 是一个基于内存的高性能key-value数据库. 2.Reids的特点 Redis本质上是一个Key-Value类型的内存数据库,很像memcached,整个数据库 ...
- 搞懂MySQL InnoDB事务ACID实现原理
前言 说到数据库事务,想到的就是要么都做修改,要么都不做.或者是ACID的概念.其实事务的本质就是锁和并发和重做日志的结合体.那么,这一篇主要讲一下InnoDB中的事务到底是如何实现ACID的. 原子 ...
- 如何探测网络设备ACL规则
探测网络设备ACL规则 背景:在互联网企业的生产网络中,往往在网络入口处的网络设备上会有成千上万条ACL策略,这么多的ACL导致了网络管理员很难彻底梳理清楚其中的逻辑关系,从而不知道到底对外开放了哪些 ...
- async/Await使用和原理
await/async是.NetFramework4.5出现的,是语法糖,由编译器提供的功能! await/async 是C#保留关键字,通常是成对出现,一般的建议是:要么不用,要么用到底 async ...
- IT企业级应⽤开发模式演化
前端研发流程 传统To B类系统的研发模式 探索 & 思考设计模式库(DPL)设计语⾔设计语⾔详解基于MVVM模式的Web框架 & UI库优化后的开发模式实现价值实践 赋能 赋能授权( ...