PNG文件分析与实例
Abstract 本文采用从理论到实践的行文思路,两大部分采用同样的结构分析PNG文件,实乃杀人放火学术科研必备好文。
概述
便携式网络图形(Portable Network Graphics,PNG),开发于20世纪90年代中期,用于替代GIF和TIFF格式,同时增加了一些GIF格式不具备的特性。支持索引、灰度、RGB三种颜色方案以及alpha通道特性,支持256色调色板技术,产生文件的体积小,最高支持24位真彩色图像和8位灰度图像,支持存在附加文本信息,以保留图像名称、作者、著作权、创作时间、注释等,支持无损压缩,适合在网络传输中快速显示预览效果后再显示全貌。
PNG文件的结构可以分为两个部分:头部和数据块序列。
理论存在
头部
头部由固定的8字节识别标志组成,它们是
10进制 | 137 80 78 71 13 10 26 10 |
---|
16进制 | 89 50 4E 47 0D 0A 1A 0A |
这确保了系统与软件能识别出它是PNG文件,每一字节均有各自的含义:
字节(16进制) | 含义 |
---|
89 | 超出ascii字符范围,防止被当作文本文件 | 50 4E 47 | 对应ascii码的"PNG"(大写) | 0D 0A | DOS风格的换行符,用于DOS-Unix数据的换行符转换 | 1A | 在DOS命令行下,用于阻止文件显示的文件结束符 | 0A | Unix风格的换行符,用于Unix-DOS换行符的转换 |
数据块的结构
数据块由4个部分组成:
组成部分 | 长度/bytes | 说明 |
---|
Length | 4 | 指定Chunk Data部分的长度(字节) | Chunk Type Code | 4 | 指定数据块的类型(ascii字母) | Chunk Data | 0~231-1 | 数据部分 | CRC | 4 | 循环冗余码,用于检测错误 |
可以分为两种类型:关键数据块和辅助数据块,其中:
关键数据块
关键数据块共4种,每个PNG文件都必须包含这四种数据块。
IHDR - 文件头数据块
包含PNG文件中存储的图像数据基本信息,位于数据块序列的首位,一个PNG文件只能拥有一个IHDR。
Length 字段:指定Chunk Data 的长度为13字节
Chunk Type 字段:
10进制 | 73 72 68 82 |
---|
16进制 | 49 48 44 52 |
Chunk Data 字段:
名称 | 字节数 | 说明 |
---|
Width | 4 | 图像宽度,以像素为单位 | Height | 4 | 图像高度,以像素为单位 | Bit depth | 1 | 图像位深,取值1、2、4、8、16 | ColorType | 1 | 颜色类型,取值0、2、3、4、6 | Compression method | 1 | 压缩方法,取值0,表示deflate压缩方法 | Filter method | 1 | 滤波器方法 | Interlace method | 1 | 隔行扫描方法,0表示无隔行,1表示Adam7隔行 |
PLTE - 调色板数据块
包含与索引彩色图像相关的彩色变换数据,仅与索引彩色图像有关,而且要放在图像数据块IDAT之前。
- 对于Colour type 3的PNG图像(索引图像),PLTE块是必需的,此时调色板的颜色索引从0开始编号,然后是1,2……
- 对于Colour type为2和6的图像,PLTE块是可选的,此时调色板将提供一个1—256的建议颜色集,以便软件或屏幕不支持显示真彩色时量化真彩色图像
- Colour type为0和4的图像中不能出现PLTE块
Length 字段:指定Chunk Data 的长度
Chunk Type 字段:
10进制 | 80 76 84 69 |
---|
16进制 | 50 4C 54 45 |
Chunk Data 字段:可以包含1-256个调色板信息,每个信息由3个字节组成:
颜色 | 字节数 | 说明 |
---|
R | 1 | 0=黑,255=红 | G | 1 | 0=黑,255=绿 | B | 1 | 0=黑,255=蓝 |
IDAT - 图像数据块
用于存储实际的图像数据,一个PNG文件中可以包含多个连续的IDAT。
Length 字段:指定Chunk Data 的长度
Chunk Type 字段:
10进制 | 73 68 65 84 |
---|
16进制 | 49 44 41 54 |
Chunk Data 字段:储存图像数据
IEND - 图像结束数据块
标志着PNG数据流的结束,位于数据流的最后一个。
Length 字段:指定Chunk Data 的长度为0
Chunk Type 字段:
10进制 | 73 69 78 68 |
---|
16进制 | 49 45 4E 44 |
Chunk Data 字段为空
辅助数据块
辅助数据块类型众多,PNG文件格式规范规定了10种辅助数据块:
数据块 | 说明 |
---|
bKGD | 背景颜色数据块,位于PLTE之后、IDAT之前 | cHRM | 基色和白色度数据块,位于PLTE和IDAT之前 | gAMA | 图像γ数据块,位于PLTE和IDAT之前 | hIST | 图像直方图数据块,位于PLTE之后、IDAT之前 | pHYs | 物理像素尺寸数据块,在IDAT之前 | sBIT | 样本有效位数据块,位于PLTE和IDAT之前 | tEXt | 文本信息数据块,可以有多个 | tIME | 图像最后修改时间数据块 | tRNS | 图像透明数据块,位于PLTE之后、IDAT之前 | zTXt | 压缩文本数据块,可以有多个 |
实践开始
选取图片文件lab2test.png 如下 使用Xcode打开 上文中,我们提到了:
头部
关键数据块
IHDR - 文件头数据块
Length 字段:指定Chunk Data 的长度为13字节 Chunk Type 字段:
Chunk Data 字段:
名称 | 字节数 | 说明 |
---|
Width | 4 | 图像宽度,以像素为单位 | Height | 4 | 图像高度,以像素为单位 | Bit depth | 1 | 图像位深,取值1、2、4、8、16 | ColorType | 1 | 颜色类型,取值0、2、3、4、6 | Compression method | 1 | 压缩方法,取值0,表示deflate压缩方法 | Filter method | 1 | 滤波器方法 | Interlace method | 1 | 隔行扫描方法,0表示无隔行,1表示Adam7隔行 |
PLTE - 调色板数据块
Color Tpye为6,PLTE块是可选的,测试图片中恰好没有PLTE块
IDAT - 图像数据块
如图,可以看出测试图片中共有189个IDAT数据块,以第一个IDAT数据块为例: Length 字段指定Chunk Data 的长度 长度为400016=1638410字节
Chunk Type 字段为
Chunk Data 字段储存图像数据
IEND - 图像结束数据块
Length 字段指定Chunk Data 的长度为0
Chunk Type 字段为
Chunk Data 字段为空
辅助数据块
图中包含物理像素尺寸数据块pHYs,在IDAT之前
|