本篇文章主要介绍了" 从零开始实现一个APNG DecoderSwift, iOS",主要涉及到方面的内容,对于IOS开发感兴趣的同学可以参考一下:
从零开始实现一个APNG Decoder(Swift, iOS)本文基于Swift,开源项目地址:https://github.com/czqasngit/Be...
从零开始实现一个APNG Decoder(Swift, iOS)
本文基于Swift,开源项目地址:https://github.com/czqasngit/BerryPlant
参考:
https://en.wikipedia.org/wiki/Portable_Network_Graphics
https://en.wikipedia.org/wiki/APNG
更好的方案是使用C实现解码部分.
要做好APNG的解码,首先得了解APNG的格式
1.什么是APNG ?
不同的图片格式的文件有不同的压缩算法,不同的数据组织结构.
APNG也是一种文件格式,他是基于PNG扩展出来的一种类似GIF的动态图片格式.
不同于GIF的是他是存在Alpha通道的,解析后就是一帧一帧的PNG图片.
既然APNG是PNG的扩展,那我们首先得搞清楚PNG的文件结构.

图中所画就是PNG的数据结构
PNG signature: PNG图片的签名,32字节,值是固定的: '.PNG'(89 50 4E 47 0D 0A 1A 0A)
IHDR、Other Chunks、IDAT、Other Chunks、IEND都被统一成一种结构,称为Chunk
图中所示Chunk的结构
4个字节表示长度,4个字节表示Chunk的类型,length个字节表示chunk 的数据,CRC4个字节用于校验数据
IHDR: 图片的元数据
Other Chunks: 在这里我暂且这样称呼,这里表示有一个或者多个连续的Chunk


图中所示就是Other Chunks可能的类型值
IDAT:图片数据
IEND:结束Chunk
有了以上的完整的PNG数据就可以被标准的PNG Decoder解码,iOS中我使用
CGDataProvider
CGImageSourceCreateWithDataProvider
来解析并得到数据
PNG的数据结构搞清楚了,我们就可以来撸一撸APNG的数据结构了

APNG的第一帧就是一个PNG,只是Other Chunks里面多了两种在PNG中没有的Chuck,分别是acTL与fcTL。在标准的PNG解码器中可以将APNG的第一帧解析出来并生成图片,acTL与fcTL也并不会影响到解码器,因为他们只是用于起控制作用的Chunk,并不会影响到IDAT里面的数据.
在维基百科上面看这幅图时可能会有些疑惑,因为他省略了一些细节的东西,这样会对解码APNG过程有一定的影响。
解码APNG的流程大致是这样的:
1.拿到文件数据,分离签名与Chunk
2.获取APNG的元数据与acTL(总动画控制)
3.提取第一帧PNG
4.以第一帧为参考,将后续fdAT解析出来替换第一帧IDAT的位置生成每一帧的图片
5.用fcTL(帧动画控制)的属性渲染图片
下面用Swift在iOS系统为例实现一下解析与渲染:
1.分离签名与Chunk
2.提取元数据与acTL