iOS 处理图片的一些小 Tip
如何把 GIF 动图保存到相册?
iOS 的相册是支持保存 GIF 和 APNG 动图的,只是不能直接播放。用 [ALAssetsLibrary writeImageDataToSavedPhotosAlbum:metadata:completionBlock] 可以直接把 APNG、GIF 的数据写入相册。如果图省事直接用 UIImageWriteToSavedPhotosAlbum() 写相册,那么图像会被强制转码为 PNG。
将 UIImage 保存到磁盘,用什么方式最好?
目前来说,保存 UIImage 有三种方式:1.直接用 NSKeyedArchiver 把 UIImage 序列化保存,2.用 UIImagePNGRepresentation() 先把图片转为 PNG 保存,3.用 UIImageJPEGRepresentation() 把图片压缩成 JPEG 保存。
实际上,NSKeyedArchiver 是调用了 UIImagePNGRepresentation 进行序列化的,用它来保存图片是消耗最大的。苹果对 JPEG 有硬编码和硬解码,保存成 JPEG 会大大缩减编码解码时间,也能减小文件体积。所以如果图片不包含透明像素时,UIImageJPEGRepresentation(0.9) 是最佳的图片保存方式,其次是 UIImagePNGRepresentation()。
UIImage 缓存是怎么回事?
通过 imageNamed 创建 UIImage 时,系统实际上只是在 Bundle 内查找到文件名,然后把这个文件名放到 UIImage 里返回,并没有进行实际的文件读取和解码。当 UIImage 第一次显示到屏幕上时,其内部的解码方法才会被调用,同时解码结果会保存到一个全局缓存去。据我观察,在图片解码后,App 第一次退到后台和收到内存警告时,该图片的缓存才会被清空,其他情况下缓存会一直存在。
我要是用 imageWithData 能不能避免缓存呢?
不能。通过数据创建 UIImage 时,UIImage 底层是调用 ImageIO 的 CGImageSourceCreateWithData() 方法。该方法有个参数叫 ShouldCache,在 64 位的设备上,这个参数是默认开启的。这个图片也是同样在第一次显示到屏幕时才会被解码,随后解码数据被缓存到 CGImage 内部。与 imageNamed 创建的图片不同,如果这个图片被释放掉,其内部的解码数据也会被立刻释放。
怎么能避免缓存呢?
1. 手动调用 CGImageSourceCreateWithData() 来创建图片,并把 ShouldCache 和 ShouldCacheImmediately 关掉。这么做会导致每次图片显示到屏幕时,解码方法都会被调用,造成很大的 CPU 占用。
2. 把图片用 CGContextDrawImage() 绘制到画布上,然后把画布的数据取出来当作图片。这也是常见的网络图片库的做法。
我能直接取到图片解码后的数据,而不是通过画布取到吗?
1.CGImageSourceCreateWithData(data) 创建 ImageSource。
2.CGImageSourceCreateImageAtIndex(source) 创建一个未解码的 CGImage。
3.CGImageGetDataProvider(image) 获取这个图片的数据源。
4.CGDataProviderCopyData(provider) 从数据源获取直接解码的数据。
ImageIO 解码发生在最后一步,这样获得的数据是没有经过颜色类型转换的原生数据(比如灰度图像)。
如何判断一个文件的图片类型?
通过读取文件或数据的头几个字节然后和对应图片格式标准进行比对。我在这里写了一个简单的函数,能很快速的判断图片格式。
怎样像浏览器那样边下载边显示图片?
首先,图片本身有 3 种常见的编码方式:
第一种是 baseline,即逐行扫描。默认情况下,JPEG、PNG、GIF 都是这种保存方式。
第二种是 interlaced,即隔行扫描。PNG 和 GIF 在保存时可以选择这种格式。
第三种是 progressive,即渐进式。JPEG 在保存时可以选择这种方式。
在下载图片时,首先用 CGImageSourceCreateIncremental(NULL) 创建一个空的图片源,随后在获得新数据时调用
CGImageSourceUpdateData(data, false) 来更新图片源,最后在用 CGImageSourceCreateImageAtIndex() 创建图片来显示。
你可以用 PINRemoteImage 或者我写的 YYWebImage 来实现这个效果。SDWebImage 并没有用 Incremental 方式解码,所以显示效果很差。
建议继续学习:
- 图片动态局部毛玻璃模糊效果的实现 (阅读:13592)
- 淘宝图片存储架构 (阅读:9840)
- 解决IE6从Nginx服务器下载图片不Cache的Bug (阅读:7101)
- When we`re only No.2, we try harder之聊天表情设计小探讨 (阅读:6511)
- 精于图片处理的10款jQuery插件 (阅读:6223)
- phpThumb:强大的缩微图类 (阅读:5462)
- js实现预加载图片让图片快速显示 (阅读:4963)
- 利用开源的Gearman框架构建分布式图片处理平台[原创] (阅读:4262)
- 使用数据库存放图片 (阅读:4189)
- 通过php+imagick 创建PDF图片预览 (阅读:3794)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:ibireme 来源: Garan no dou
- 标签: 图片
- 发布时间:2016-02-11 14:54:53
- [55] IOS安全–浅谈关于IOS加固的几种方法
- [54] 图书馆的世界纪录
- [54] Oracle MTS模式下 进程地址与会话信
- [53] android 开发入门
- [52] 如何拿下简短的域名
- [50] Go Reflect 性能
- [50] 【社会化设计】自我(self)部分――欢迎区
- [47] 读书笔记-壹百度:百度十年千倍的29条法则
- [36] 程序员技术练级攻略
- [31] 视觉调整-设计师 vs. 逻辑