一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第20天,点击查看活动详情。
_updateSourceImageIO
这里以GIF为例,解码器的简单初始化是为了搜集每一帧的宽度,高度,
duration
,原始方向以及循环次数一些简单属性,这里每一帧的对象是以_YYImageDecoderFrame
及成语YYImageFrame
的私有类保存,然后统一存储到frames数组里面,记住,这里的图片只是显示了每一帧的基本信息保存而已,图片还是没有解码的。
YYImageDecoder
就是管理类,里面的参数frames保存上面的DecoderFrame
,也就是每一帧的信息,然后把数据源通过CG函数转换存入_source字段备用,后续frames(YYImageDecoderFrame)
里面的每一帧都会被解码存储到image字段,通过定时器去显示,可以理解为Decoder
管理数据源以及每一帧的信息和解码后的image资源。
到了这里基本上就是把图片的信息保存下来了。
根据index,提取出对应帧的解码图片,下面这个方法就是解码提取图片的核心方法
说明这两份方法是用来进行土拍呢压缩的。我们先看
_newUnblendedImageAtIndex
:
Color Spaces and Bitmap Layout
我们前面已经知道了,像素格式是用来描述每个像素的组成格式的,比如每个像素使用的总bit数。而要想确保Quartz能够正确地解析这些bit所代表的含义,我们还需要提供位图的布局信息CGBitmapInfo
:
其中Alpha为CGImageAlphaInfo
- 是否包含alpha;
- 如果包含alpha,那么alpha信息所处的位置,在像素的最低有效位,比如RGBA,还是最高有效位,比如ARGB;
- 如果包含alpha,那么每个颜色分量是否已经乘以alpha的值,这种做法可以加速图片的渲染时间,因为它避免了渲染时的额外乘法运算。比如,对于RGB颜色空间,用已经乘以alpha的数据来渲染图片,每个像素都可以避免3次乘法运算,红色乘以alpha,绿色乘以alpha和蓝色乘以alpha。
我们可以知道,当图片不包含alpha的时候使用
kCGImageAlphaNoneSkipFirst
,否则使用kCGImageAlphaPremultipliedFirst
。另外,这里也提到了字节顺序应该使用32位的主机字节顺序kCGBitmapByteOrder32Host
,而这个值具体是什么,我们后面再讨论。
根据前面的讨论,我们知道字节顺序的值应该使用的是32位的主机字节顺序
kCGBitmapByteOrder32Host
,这样的话不管当前设备采用的是小端模式还是大端模式,字节顺序始终与其保持一致。
CGBitmapContextCreate
函数中的参数信息:
data
:如果不是NULL,那么它应该指向一块大小至少为bytesPerRow *height
字节的内存;如果为NULL,那么系统就会为我们自动分配和释放所需的内存,所以一般指定NULL即可;- width和height:位图的宽度和高度,分别赋值为图片的像素宽度和像素高度即可;
bitsPerComponent
:像素的每个颜色分量使用的bit数,在RGB颜色空间下指定8即可; bytesPerRow
:位图的每一行使用的字节数,大小至少为width *bytes per pixel
字节。有意思的是,当我们指定0时,系统不仅会为我们自动计算,而且还会进行cache line alignment的优化。space
:就是我们前面提到的颜色空间,一般使用RGB即可;bitmapInfo
:就是我们前面提到的位图的布局信息。
这里面主要有三个步骤:
- 使用
CGBitmapContextCreate
函数创建一个位图上下文; - 使用
CGContextDrawImag
e函数将幻视位图绘制到上下文中; - 使用
CGBitmapContextCreateImage
函数创建一张新的解压缩后的位图。 这个时候就是解码的核心逻辑。
如果此时没有相应的步骤,就显示第一帧图片在UI上。