什么是位图数据?
A bitmap image (or sampled image) is an array of pixels (or samples). Each pixel represents a single point in the image. JPEG, TIFF, and PNG graphics files are examples of bitmap images.
其实,位图就是一个像素数组,数组中的每个像素就代表着图片中的一个点。我们在应用中经常用到的 JPEG 和 PNG 图片就是位图。
什么是像素
像素是点样本。像素只存在于那个点上。对于彩色图片来说,一个像素也许包含着3个样本,每个样本都是在采样点对一种主元色的采样。不过我们依然可以认为这是对颜色的点采样。但是我们不能认为像素是个方块——或者任何其它不是点的东西。对像素造成影响的范围(译者注:在每个采样点,滤波器的影响范围,也就是后面说的足迹)可以被建模为一个方块,但也绝不是像素本身。一副图像是二维的点样本(像素)的数组。神奇的采样理论告诉我们,我们可以用合适的重建滤波器,将离散的实体重建为连续的。
iOS从磁盘加载一张图片,使用UIImageVIew显示在屏幕上,需要经过以下步骤:
- 从磁盘拷贝数据到内核缓冲区
- 从内核缓冲区复制数据到用户空间
3.生成UIImageView,把图像数据赋值给UIImageView - 如果图像数据为未解码的PNG/JPG,解码为位图数据
- CATransaction捕获到UIImageView layer树的变化
- 主线程Runloop提交CATransaction,开始进行图像渲染
6.1 如果数据没有字节对齐,Core Animation会再拷贝一份数据,进行字节对齐。
6.2 GPU处理位图数据,进行渲染。
<pre>
解压缩后的图片大小 = 图片的像素宽 30 * 图片的像素高 30 * 每个像素所占的字节数 4
</pre>
FastImageCache是Path团队开发的一个开源库,用于提升图片的加载和渲染速度,让基于图片的列表滑动起来更顺畅,来看看它是怎么做的。
FastImageCache适合用于tableView里缓存每个cell上同样规格的图像,优点是能极大加快第一次从磁盘加载这些图像的速度。但它有两个明显的缺点:一是占空间大。因为缓存了解码后的位图到磁盘,位图是很大的,宽高100100的图像在2x的高清屏设备下就需要200200*4byte/pixel=156KB,这也是为什么FastImageCache要大费周章限制缓存大小。二是接口不友好,需预定义好缓存的图像尺寸。FastImageCache无法像SDWebImage那样无缝接入UIImageView,使用它需要配置ImageTable,定义好尺寸,手动提供的原图,每种实体图像要定义一个FICEntity模型,使逻辑变复杂。
FastImageCache已经属于极限优化,做图像加载/渲染优化时应该优先考虑一些低代价高回报的优化点,例如CALayer代替UIImageVIew,减少GPU计算(去透明/像素对齐),图像子线程解码,避免Offscreen-Render等。在其他优化都做到位,图像的渲染还是有性能问题的前提下才考虑使用FastImageCache进一步提升首次加载的性能,不过字节对齐的优化倒是可以脱离FastImageCache直接运用在项目上,只需要在解码图像时bitmap画布的bytesPerRow设为64的倍数即可。
参考
谈谈 iOS 中图片的解压缩 http://blog.leichunfeng.com/blog/2017/02/20/talking-about-the-decompression-of-the-image-in-ios/#jtss-tsina
iOS图片加载速度极限优化—FastImageCache解析 http://blog.cnbang.net/tech/2578/
网友评论