iOS 处理图片的一些小 Tip

转载 2015年11月19日 14:52:20

http://blog.ibireme.com/2015/11/02/ios_image_tips/

如何把 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 种常见的编码方式:

image_baseline image_interlaced image_progressive

第一种是 baseline,即逐行扫描。默认情况下,JPEG、PNG、GIF 都是这种保存方式。
第二种是 interlaced,即隔行扫描。PNG 和 GIF 在保存时可以选择这种格式。
第三种是 progressive,即渐进式。JPEG 在保存时可以选择这种方式。
在下载图片时,首先用 CGImageSourceCreateIncremental(NULL) 创建一个空的图片源,随后在获得新数据时调用
CGImageSourceUpdateData(data, false) 来更新图片源,最后在用 CGImageSourceCreateImageAtIndex() 创建图片来显示。

你可以用 PINRemoteImage 或者我写的 YYWebImage 来实现这个效果。SDWebImage 并没有用 Incremental 方式解码,所以显示效果很差。


iOS 处理图片的一些小 Tip

首页  About  Archive  ACG  其他  吐槽  技术   日常  设计 iOS 处理图片的一些...
  • adsl2812358
  • adsl2812358
  • 2015年11月02日 19:06
  • 1013

关于Java编程的一些小知识

Q:   int n=Integer.parseInt("+5");          int n=Integer.parseInt("123ABC");         编译时正常,解析时就报错了,...
  • NBXX2005
  • NBXX2005
  • 2005年01月13日 23:24
  • 563

一些小tip

两个eclipse里很有用的快捷键:1. 输入main之后,按Alt+/,即可自动生成: publice static void main(String[ ] args ) { }2. 输入Syso之...
  • zhangzijun1984
  • zhangzijun1984
  • 2011年07月22日 10:27
  • 125

css一些小tip

1、字体对齐:text-align:center; 2、自动分配margin:margin:auto; 3、left/right/top/bottom,当position=absolute/r...
  • qq_16045605
  • qq_16045605
  • 2015年06月04日 13:56
  • 199

Ubuntu的一些小tip

安装java 下载对应的Jdk 在官网下载:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-213315...
  • felcon
  • felcon
  • 2017年01月05日 17:05
  • 307

java的一些小程序例子--3

输入两个实数,按照从小到大的顺序输出这两个数 import java.util.Scanner;   public class b{  public static void main(Strin...
  • qq_24928451
  • qq_24928451
  • 2015年03月20日 18:38
  • 290

java中的一些小知识点

最近在复习javaSE,因此整理了一些小知识点,这些知识点很简单,但是却也很重要...
  • qq_32933131
  • qq_32933131
  • 2017年03月15日 09:11
  • 191

第一次用Ajax写了个小功能

作为一个初识web的同学,玩儿php不得不学
  • liudeen1122
  • liudeen1122
  • 2014年06月04日 16:35
  • 271

剑指offer-46.孩子们的游戏(圆圈中最后剩下的数)

题目:每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定一...
  • I_love_blog
  • I_love_blog
  • 2017年05月06日 20:15
  • 200

剑指offer-孩子们的游戏(圆圈中最后剩下的数)

题目描述每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。HF作为牛客的资深元老,自然也准备了一些小游戏。其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。然后,他随机指定...
  • SoundSlow
  • SoundSlow
  • 2016年08月17日 11:17
  • 544
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS 处理图片的一些小 Tip
举报原因:
原因补充:

(最多只允许输入30个字)