PNG文件分析与实例
文章目录
- PNG文件分析与实例
- 概述
- 理论存在
- 头部
- 关键数据块
- IHDR - 文件头数据块
- PLTE - 调色板数据块
- IDAT - 图像数据块
- IEND - 图像结束数据块
- 辅助数据块
- 实践开始
- 头部
- 关键数据块
- IHDR - 文件头数据块
- PLTE - 调色板数据块
- IDAT - 图像数据块
- IEND - 图像结束数据块
- 辅助数据块
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进制) | 含义 |
| 超出ascii字符范围,防止被当作文本文件 |
| 对应ascii码的"PNG"(大写) |
| DOS风格的换行符,用于DOS-Unix数据的换行符转换 |
| 在DOS命令行下,用于阻止文件显示的文件结束符 |
| 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
字段:
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 - 调色板数据块
Color Tpye为6,PLTE块是可选的,测试图片中恰好没有PLTE块
IDAT - 图像数据块
如图,可以看出测试图片中共有189个IDAT数据块,以第一个IDAT数据块为例:
Length
字段指定Chunk Data
的长度
长度为400016=1638410字节
Chunk Type
字段为
16进制 | 49 44 41 54 |
Chunk Data
字段储存图像数据
IEND - 图像结束数据块
Length
字段指定Chunk Data
的长度为0
Chunk Type
字段为
16进制 | 49 45 4E 44 |
Chunk Data
字段为空
辅助数据块
图中包含物理像素尺寸数据块pHYs,在IDAT之前