PNG图像文件格式分析
一、PNG格式简介
png是一种采用无损压缩算法的位图格式,其设计目的是试图替代GIF和TIFF文件格式,同时增加一些GIF文件格式所不具备的特性。PNG使用从LZ77派生的无损数据压缩算法,一般应用于JAVA程序、网页或S60程序中,原因是它压缩比高,生成文件体积小。
以上来自百度百科
二、PNG文件详解
PNG图像格式文件由一个8字节的PNG文件署名和按照特定结构组织的3个以上的数据(chunk)组成。PNG定义了两种类型的数据块,一种是称为关键数据块(critical chunk),这是标准的数据块,另一种叫做辅助数据块(ancillary chunks),这是可选的数据块。关键数据块定义了4个标准数据块,每个PNG文件都必须包含它们。
以下图为例详细分析png图片。
1、文件署名域
png文件的文件署名域用来标识这是一个png文件,固定为:
十六进制 | 89 50 4E 47 0D 0A 1A 0A |
---|
例图与之相符。
2、数据块
PNG数据所有数据块如下:
PNG每个数据块的构成如下:
名称 | 字节数 | 说明 |
---|---|---|
Length (长度) | 4字节 | 指定数据块中数据域的长度,其长度不超过(231-1)字节 |
Chunk Type Code (数据块类型码) | 4字节 | 数据块类型码由ASCII字母(A-Z和a-z)组成 |
Chunk Data (数据块数据) | 可变长度 | 存储按照Chunk Type Code指定的数据 |
CRC (循环冗余检测) | 4字节 | 存储用来检测是否有错误的循环冗余码 |
1)关键数据块
a.IHDR数据块
文件头数据块IHDR(header chunk,13个字节)包含PNG文件中存储的图像数据的基本信息,包括分辨率、比特深度、色彩模式、压缩方法,是非常重要的数据块,必须作为第一个数据块出现在PNG数据流中,而且一个PNG数据流中只能有一个文件头数据块。
其结构如下:
对例图分析:
- 第一个红框表示数据域的长度为13字节。
- 第二个红框表示数据块类型为IHDR(文件头数据块)。
- 第三个红框表示数据块数据(下面分析)。
- 第四个蓝框表示CRC(数据冗余检测)。
对于数据块数据:
域的名称 | 16进制 | 10进制 | 说明 |
---|---|---|---|
Width | 0319 | 793 | 宽793 |
Height | 018A | 394 | 高394 |
Bit depth | 08 | 8 | 图像深度为8即真彩色图像 |
ColorType | 06 | 6 | 颜色类型为6即带α通道数据的真彩色图像 |
Compression method | 00 | 0 | / |
Filter method | 00 | 0 | / |
Interlace method | 00 | 0 | 非隔行扫描 |
b.IDAT数据块
图像数据块IDAT(image data chunk)存储实际的数据,在数据流中可包含多个连续顺序的图像数据块。
IDAT存放着图像真正的数据信息,因此,如果能够了解IDAT的结构,我们就可以很方便的生成PNG图像。
例图IDAT数据块如下:
- 红框表示数据域的长度为0x5DDA即24026字节。
- 黑色加深部分表示数据块类型为IDAT(图像数据块)。
- 后续为图像数据部分。
- 数据结尾应该是CRC,但是数据太长了CRC找起来太麻烦就没找。
c.IEND数据块
图像结束数据IEND(image trailer chunk)用来标记PNG文件或者数据流已经结束,并且必须要放在文件的尾部。
例图IEND数据块如下:
- 第一二个红框表示数据域的长度为0字节(毕竟是结尾)。
- 黑色加深部分表示数据块类型为IDAT(图像数据块)。
- 数据长度为0故没有数据部分。
- 第三个红框表示CRC(数据冗余检测)。
2)辅助数据块
a.PLTE数据块(比较重要)
搜索了一下16进制标识50 4C 54 45
发现没有。
分析是因为例图为真彩图像,因此调色板不存在。
b.pHYs数据块
物理像素数据块(pHYs),它表示了图片的像素尺寸,或者是高宽比。
例图pHYs数据块如下:
- 红框表示数据域的长度为9字节。
- 黑色加深部分表示数据块类型为pHYs(物理像素数据块)。
- 蓝色框为数据部分,数据长度为9字节,在下面分析。
- 绿框表示CRC(数据冗余检测)。
数据部分:
域 | 字节数 | 说明 |
---|---|---|
每像素像素数,X轴 | 4个字节 | 0x1274即4724字节 |
每像素像素数,Y轴 | 4个字节 | 0x1274即4724字节 |
单位说明符 | 1个字节 | 0:单位未知,1:单位是米 |
三、总结
png文件的二进制读取方式是高位在前低位在后,与课上的bmp文件不通,在刚开始理解的时候费了不少功夫,查阅了不少资料。