Image解码

可以看到从CFDataRef直到创建出UIImage,都没有调用过对图像解码的函数,只读取了一些图像基础数据和元数据。

Image解码发生在什么时候?在ImageIO/CGImageSource.h文件中kCGImageSourceShouldCache的上面其实有明确注释。

Specifies whether image decoding and caching should happen at image creation time.

The value of this key must be a CFBooleanRef. The default value is kCFBooleanFalse (image decoding will happen at rendering time).

如果不手动设置Image只会等到在屏幕上渲染时再解码。经过测试,确实如此。这个kCGImageSourceShouldCacheImmediately还不如起名为kCGImageSourceShouldDecodeImmediately

Image解码到底在哪里做的?

如果在画布上渲染图片,图片一定是会被解码的。下列代码再跑测试



所有调用的函数名中没有明显decompress或者decode字眼。而上面四个函数调用的频率是最高的。根据CGImageDestinationRef调用的png_compress_IDAT,猜测png_read_IDAT_data是做解码的函数。

以上是以png图片作为测试用例,下面看看jpeg图片的

很明显AppleJPEG的decode方法是做解码的函数。jpeg与png调用了两个同样函数,而不同的图片调了不同的解码函数。在画布上画图片的时候,会调用ImageProviderCopyImageBlockSetCallback设置callback,然后调用copyImageBlock,再调用设置的callback,但是解码函数是由copyImageBlock的调用的还是由callback调用的无法验证。

ImageProviderCopyImageBlockSetCallbackCGDataProviderCopyData是否有关系?经过测试,CGDataProviderCopyData内部也会调用ImageProviderCopyImageBlockSetCallbackcopyImageBlock。而且CGDataProviderCopyData得到的CFDataRef是解码过的像素数组。

结论:Image解码发生在CGDataProviderCopyData函数内部调用ImageProviderCopyImageBlockSetCallback设置的callback或者copyImageBlock函数,根据不同的图片格式调用的不同的方法中。

Image的初始化方法

imageWithData从内部函数的调用来看,通过CGImageSourceRef访问图像数据,创建CGImageRef

imageWithContentsOfFile内部调用如下

文件通过mmap到内存然后通过CGImageSourceRef访问图像数据,创建CGImageRef

imageNamed先从Bundle里找到资源路径,然后同样也是将文件mmap到内存,再通过CGImageSourceRef访问图像数据,创建CGImageRef

Image的缓存

通过调用不同的UIImage初始化方法然后创建UIImageVIew展示到屏幕上,来看看不同方法是否有缓存的行为。

imageNamed在第二次展示相同image的时候没有调用imageIO的任何方法。

imageWithDataimageWithContentsOfFile在第二次在展示相同image的时候均调用了imageIO的解码方法。

而imageWithData和imageWithContentsOfFile初始化方法创建的UIImage只要不被释放,再次渲染不会调用imageIO解码方法。

结论为UIImage有两种缓存,一种是UIImage类的缓存,这种缓存保证imageNamed初始化的UIImage只会被解码一次。另一种是UIImage对象的缓存,这种缓存保证只要UIImage没有被释放,就不会再解码。

最新文章

  1. android TCP 客户端(仅接收数据)
  2. 阅读《LEARNING HARD C#学习笔记》知识点总结与摘要一
  3. 获取发布版SHA1获取
  4. meta基础知识
  5. ASP.NET Ajax核心对象
  6. front-end
  7. ural 1106 Two Teams
  8. awr报告基本操作
  9. Java EE (9) -- JDBC & JTA
  10. 数据结构之Huffman树与最优二叉树
  11. KB奇遇记(6):搞笑的ERP项目团队
  12. SpringMVC中404错误解决方法总结
  13. MVC配置伪静态
  14. SQL 行转列的运用
  15. 2018-2019-2 20165325 《网络对抗技术》 Exp5:MSF基础应用
  16. h5直接分享的实现方案
  17. Cookie保存中文用户名报错(500)
  18. 长沙IT二十年
  19. 第五十五天 css基础入门
  20. JQuery常见事件

热门文章

  1. Redmine 甘特图导出 PDF 和 PNG 中文乱码问题
  2. java 1.8 内存告警问题
  3. 版本控制之git学习
  4. 使用js控制文本超出部分显示省略号
  5. vue中使用base64进行加解密
  6. React传递参数的多种方式
  7. Vue.js 渲染简写样式存在的问题
  8. Problem 11
  9. js 文档加载完成之后执行 备用
  10. 工具-VS2015前端开发工具简介