• Image解码


    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解码到底在哪里做的?

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



































    CGContextDrawImage函数调用

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

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

    jpeg decode -1

    jpeg decode - 2

    jpeg decode -3

    很明显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内部调用如下

    iOS_initWithContentOfFile函数调用

    文件通过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没有被释放,就不会再解码。

  • 相关阅读:
    Ruby
    WebGL的第二个小程序
    wegGL的第一个小程序
    Node.js介绍
    接口隔离原则(Interface Sepreation Principle)
    参数
    字段/属性
    接口和抽象类
    javascript中的事件
    线性回归算法-4.多元线性回归算法
  • 原文地址:https://www.cnblogs.com/feng9exe/p/8857460.html
Copyright © 2020-2023  润新知