iOS 图片加载与处理

一、图像从文件到屏幕的过程

图片显示分为三步:加载、解码、渲染

CPU 和 GPU 在渲染过程中的分工是什么?

图片渲染原理

CPU(中央处理器):计算frame、解压缩图片、将需要绘制的纹理图片通过数据总线交给GPU。

GPU(图形处理器):定点的计算与变换、像素点的填充计算和纹理混合、渲染到帧缓冲区。

图片显示到屏幕上是CPU和GPU共同完成的。

二、图片加载的工作流程

以 +(UIImage *)imageWithContentOfFile 为例:

图片加载的过程

图片解码是一个非常耗时的CPU操作,并且默认是在主线程进行的,所以当图片较多时对性能会造成很大的影响,特别是在快速滑动的列表上。

三、为什么要解压缩

既然是耗时操作,那么是否可以避免解压缩直接绘制图片到屏幕上,答案是否定的。图片解压缩的过程其实就是将图片的二进制数据转换成像素数据的过程,先了解一下位图, 什么是位图呢?

图像分为位图和矢量图。

矢量图是根据几何特性来绘制图形,矢量可以是一个点或一条线,文件占用空间较小,可自由无限制的重新组合 。

位图也称点阵图像,位图使用我们称为像素的一格一格的小点来描绘图像。

位图是一个像素数组, 每一个元素代表图片中的一个点. 我们在程序中使用的PNG和JPEG 图片就是位图.

事实上,不管是 JPEG  还是 PNG  图片,都是一种压缩的位图图形格式。只不过 PNG  图片是无损压缩,并且支持 alpha 通道,而 JPEG  图片则是有损压缩,可以指定 0-100% 的压缩比.

在将磁盘中的图片渲染到屏幕之前,必须先要得到图片的原始像素数据,才能执行后续的绘制操作,这就是为什么需要对图片解压缩的原因。

四、强制解压缩的原理

图片的解压缩不可避免,但是又不想让它在主线程执行,会影响应用的响应性,就要有更好的解决方案。

当未解压缩的图片将要渲染到屏幕时,系统会在主线程对图片进行解压缩,而如果图片已经解压缩了,系统就不会再对图片进行解压缩。因此,也就有了业内的解决方案,在子线程提前对图片进行强制解压缩。

而强制解压缩的原理就是对图片进行重新绘制,得到一张新的解压缩后的位图。其中,用到的最核心的函数是 CGBitmapContextCreate

CG_EXTERN CGContextRef __nullable CGBitmapContextCreate(void * __nullable data, size_t width, size_t height, size_t bitsPerComponent, size_t bytesPerRow, CGColorSpaceRef __nullable space, uint32_t bitmapInfo) CG_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);

1)像素格式

位图其实就是一个像素数组,而像素格式则是用来描述每个像素的组成格式,它包括以下信息:

Bits per component :一个像素中每个独立的颜色分量使用的 bit 数;

Bits per pixel : 一个像素使用的总 bit 数;

Bytes per row : 位图中的每一行使用的字节数。

对于位图来说,像素格式并不是随意组合的,目前只支持以下有限的17种特定组合:官方文档

2)位图的布局信息

像素格式是用来描述每个像素的组成格式的,比如每个像素使用的总bit数。而要想确保Quartz能够正确解析这些bit所代表的含义,还需要提供位图的布局信息 CGBitmapInfo:

CGBitmapInfo

包含了三方面信息:alpha的信息、颜色分量是否为浮点数、像素格式的字节顺序。

CGImageAlphaInfo

CGImageAlphaInfo包含的信息:

(1)是否包含 alpha ;

(2)如果包含 alpha ,那么 alpha 信息所处的位置,在像素的最低有效位,比如 RGBA ,还是最高有效位,比如 ARGB ;

(3)如果包含 alpha ,那么每个颜色分量是否已经乘以 alpha 的值,这种做法可以加速图片的渲染时间,因为它避免了渲染时的额外乘法运算。比如,对于 RGB 颜色空间,用已经乘以 alpha 的数据来渲染图片,每个像素都可以避免 3 次乘法运算,红色乘以 alpha ,绿色乘以 alpha 和蓝色乘以 alpha 。

3)参数选择

函数的参数具体的选择,官方文档有推荐,如图所示:

当没有alpha信息时,选用 kCGImageAlphaNoneSkipFirst,当有alpha通道时选择 kCGImageAlphaPremultipliedFirst,字节顺序采用 kCGBitmapByteOrder32Host。

4)开源库的实现

下图为各开源库图片解码时参数的选择,其中YYKit 和 SDWebImage 采用相同的参数。

五、图片缩略技术

将Data Buffers解码到 Image Buffers是一个CPU密集型的操作。同时它的大小是和与原始图像大小成比例,和 View 的大小无关。

如果一个浏览照片的应用展示多张照片时,没有经过任何处理,就直接读取图片,然后来展示。那 Decode  时,将会占用极大的内存和 CPU。而我们展示的图片的 View 的大小,其实是完全用不到这么大的原始图像的

图像是每个应用程序不可缺少的一部分。尤其面对高精度大图片的处理时,方式不当可能会出现OOM。

首先要知道 什么是压缩:

“压” 指文件体积变小,但是像素不变,长宽尺寸不变,那么质量可能下降

“缩” 指文件的尺寸变小,也就是像素数减少,而长宽尺寸变小,文件体积同样会减小。

1、图像的压处理:

图片的压处理,我们可以使用UIImageJPEGRepresentation或UIImagePNGRepresentation方法实现

2、图像的缩处理:

iOS的五种图片缩略技术以及性能探讨

原图大小为15.4MB,尤其测试条件单一,结果仅供参考。

3、超大图片处理

CATiledLayer 分片显示iOS大图展示的解决方法

六、性能优化

1、降采样

2、子线程解码和降采样

3、使用Image Asset Catalogs

4、合理的图片格式和尺寸的选用

5、UITableViewDataSourcePrefetching

6、分片显示


参考文章:

https://www.jianshu.com/p/de7b6aede888

https://juejin.im/post/5b1a7c2c5188257d5a30c820

https://www.jianshu.com/p/943dbe3ed608

https://honglu.me/2016/09/02/一张图片引发的深思/

https://longtimenoc.com/archives/ios如何避免图像解压缩的时间开销

http://blog.leichunfeng.com/blog/2017/02/20/talking-about-the-decompression-of-the-image-in-ios/

https://blog.csdn.net/y4x5m0nivsrjay3x92c/article/details/80327202

http://www.cocoachina.com/articles/25174

https://www.jianshu.com/p/fa48e8d5f9e4

https://www.jianshu.com/p/1a0a58cf6fab

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342