PNG文件的组成
一个PNG文件可以看作是由多个数据块(chunk)部分组成,如同积木一样,一个数据块就是一个小积木,不同类型的积木组合搭建成了我们的PNG图像。
PNG图像至少由文件署名域和三个关键数据块IHDR,IDAT,IEND组成,因此一个最小PNG图像可以抽象的表示成如下图像
我们结合png图像来了解png文件格式,用16进制编辑器打开该图片来分析。
上图包含的三个关键数据块的主要作用如下
1.PNG文件署名域(magic number)
png文件在开头用署名域标志了该文件的类型,长度为8个字节。因此一个文件只要前8个字节值为89 50 4E 47 0D 0A 1A 0A,我们就可以认为该文件为png
[署名域(8Bytes)]:标识文件类型为png格式
PS:试着在C用字符类型打印50 4E 47,你会发现打印出PNG三个字符
2.(Image Header) chunk:描述影像的维度、色彩深度、色彩格式、压缩类型等
3.(Image Data)chunk:存储影像的像素数据
4.(Image End)chunk:PNG数据流结束
PNG的Chunk有很多类型,这里只介绍了最关键的三种
数据块结构
PNG中一个Chunk的结构通常如下
名称 | 大小(字节) | 说明 |
---|---|---|
Length(长度) | 4 | 标识了数据块的长度(包括长度域) |
Chunk Type Code(数据块类型) | 4 | 标志了该数据块的类型 |
Chunk Data(数据库长度) | 可变 | 根据不同的类型数据块长度不一样,取决于Chunk Type Code |
CRC(循环冗余检验) | 4 | 检验数据块是否出错 |
IHDR数据块
将上图图像文件的IHDR表示如上,BD(Bit Depth),CT(Color Type),CM(Compression method),FM(fjlter method),IM(Insterlace Method)具体介绍如下
域名 | 字节数(Byte) | 说明 |
---|---|---|
Width | 4 | 图像宽度,以像素为单位 |
Height | 4 | 图像高度,以像素为单位 |
Bit Depth | 1 | 图像深度: 索引彩色图像:1,2,4或8 灰度图像:1,2,4,8或16 真彩色图像:8或16 |
Color Type | 1 | 颜色类型:0:灰度图像, 1,2,4,8或16 2:真彩色图像,8或163索引彩色图像,1,2,4或8 4:带α通道数据的灰度图像,8或16 6:带α通道数据的真彩色图像,8或16 |
Compression method | 1 | 压缩方法(LZ77派生算法) |
Filter Method | 1 | 滤波器方法 |
Interlace method | 1 | 隔行扫描方法:0:非隔行扫描 1: Adam7(由Adam M. Costello开发的7遍隔行扫描方法) |
我们从上可以得到该图像的分辨率为128*128,图像深度为彩色图像,没有使用压缩、滤波器等信息。
LZ77压缩算法和rar的压缩方式是一致的
IDAT数据块
IDAT数据块存储的格式取决于PNG的格式以及是否压缩。
PNG文件格式分为PNG-24和PNG-8,其最大的区别是PNG-24是用24位来保存一个像素值,是真彩色,而PNG-8是用8位索引值来在调色盘 中索引一个颜色,因为一个索引值的最大上限为2的8次方既128,故调色盘中颜色数最多为128种,
一旦使用了压缩我们必须使用zlib解压才能看见它的具体颜色。
IEND数据块
值得注意的是,IEND区块虽然也按照数据块的结构,但Chunk Data是没有的,所以是固定的96个字节:0x00000000 0x49454e44 0xae426082
IEND数据块的长度总是0(00 00 00 00,除非人为加入信息),数据标识总是IEND(49 45 4E 44),因此,CRC码也总是AE 42 60 82
参考资料
(Yolo的svpng)[]
(PNG文件格式分析)[]