APNG简介
APNG 是 Animated PNG 的简写,是 PNG 格式的一种扩展,可以支持动图。APNG 是向下兼容的,扩展名也是 .png,不支持 APNG 的解码器会表现为 PNG 的形式,即显示 APNG 的第一帧图片。
PNG图片格式
在详细了解 APNG 之前,首先来了解一下 PNG 图片格式。因为 APNG 是在 PNG 图片格式的基础上组成的。
PNG 由一个 8 字节的 PNG 文件标识(file signature)域和 3 个必须的数据块 (chunk) IHDR、IDAT、IEND 组成。
|-- PNG Signature --|-- IHDR --|-- IDAT --|-- IEND --|
每一个数据块的整体结构如下:
| 名称 | 字节数 | 描述 |
|---|---|---|
| Length | 4 | 制定数据块中数据域的长度 |
| Chunk Type Code | 4 | 数据块类型码,由ASCII字母组成 |
| Chunk Data | 不定 | 数据块数据 |
| CRC | 4 | 循环冗余码,用来检测是否有错误,由Chunk Type Code 域和 Chunk Data 域中的数据进行计算得到 |
IHDR:image header chunk (文件头数据块)
包含图像基本信息,作为第一个数据块出现并只出现一次。
| 字节偏移量 | 名称 | 描述 |
|---|---|---|
| 0 | Width | 图片宽度 |
| 4 | Height | 图片高度 |
| 8 | Bit depth | 位深 |
| 9 | Color type | 颜色类型 |
| 10 | Compression method | 压缩方式 |
| 11 | Filter method | 过滤方式 |
| 12 | Interlace method | 扫描方式 |
IDAT:image data chunk (图像数据块)
存储实际图像数据。PNG数据允许包含多个连续的图像数据块。
| 字节偏移量 | 名称 | 描述 |
|---|---|---|
| 0 | frame_data | 帧数据 |
IEND:image trailer chunk (结束数据块)
放在文件尾部,表示PNG数据流结束, 数据为空。通常PNG文件的结尾都是下面这样。
00 00 00 00 49 45 4E 44 AE 42 60 82
因为数据域的长度为0,数据块类型码都为 IEND,所以计算出来的CRC码都为 AE 42 60 82。
APNG图片格式
在了解了 PNG 图片格式的基础上,现在来看看 APNG 图片格式。

从上图可以看出,APNG 图片格式就是在 PNG 图片基础上增加了 ACTL、FCTL、FDAT 这三个额外的数据块。
ACTL:The Animation Control Chunk(动画控制块)
| 字节偏移量 | 名称 | 描述 |
|---|---|---|
| 0 | 帧数 | APNG图片帧数 |
| 4 | 循环次数 | APNG图片循环次数,0为无限循环 |
FCTL:The Frame Control Chunk(帧控制块)
| 字节偏移量 | 名称 | 描述 |
|---|---|---|
| 0 | sequence_number | 动画块的序列,从0开始 |
| 4 | width | 帧的宽度 |
| 8 | height | 帧的高度 |
| 12 | x_offset | 水平偏移量 |
| 16 | y_offset | 垂直偏移量 |
| 20 | delay_num | 这帧显示时间的分子(单位为秒) |
| 22 | delay_den | 这帧显示时间的分母(单位为秒) |
| 24 | dispose_op | 清除方式 |
| 25 | blend_op | 混合模式 |
其中 dispose_op 表示绘制下一帧时需要对当前缓冲区的操作,包含三个选项:
| 值 | 常量 | 描述 |
|---|---|---|
| 0 | APNG_DISPOSE_OP_NONE | 把当前帧增量绘制到画布上,不清空画布 |
| 1 | APNG_DISPOSE_OP_BACKGROUND | 绘制当前帧之前,先把画布清空为默认背景色 |
| 2 | APNG_DISPOSE_OP_PREVIOUS | 绘制下一帧前,先把画布恢复为当前帧的前一帧 |
其中 blend_op 表示绘制当前帧时是混合还是直接替换,包含两个选项:
| 值 | 常量 | 描述 |
|---|---|---|
| 0 | APNG_BLEND_OP_SOURCE | 绘制时,全部通道(包含Alpha通道)都会覆盖到画布,相当于绘制前先清空画布的指定区域 |
| 1 | APNG_BLEND_OP_OVER | 绘制时,Alpha 通道会被合成到画布,即通常情况下两张图片重叠的效果 |
FDAT:The Frame Data Chunk(帧数据块)
| 字节偏移量 | 名称 | 描述 |
|---|---|---|
| 0 | sequence_number | 动画块的序列,从0开始 |
| 4 | frame_data | 帧数据 |
FDAT 与 IDAT 的结构相同,只是多了一个序列号。
FCTL 和 FDAT 中的序列号是一起计算的。第一个 FCTL 块必须包含序列0, 在 FCTL 和 FDAT 中的序列号必须是按顺序连续的,中间不能有间隔或者重复的序列号。
APNG压缩
APNG播放动画的过程相当于在画布上绘画的过程。第一帧称作关键帧,之后的帧称作预测编码帧。一个压缩的比较好的动图内,通常只有少量的关键帧,而其余都是预测编码帧;一个较差的压缩工具制作的动图内,则基本都是关键帧。不同的动图压缩工具通常能得到不同的结果。
好的压缩结果:


第一帧做为基础,之后每一帧都是在第一帧基础上进行绘制,只保留差值部分。
不好的压缩结果:

APNG支持情况:

在了解APNG内部结构的基础上,可以用程序的方法做到将APNG反向播放,一些交互需要hover进去一个动画,leave的时候反向播放,就不需要UI提供两张图片了。