PNG(Portable Network Graphics)是一种无损压缩的图像格式,其文件结构由一个固定的文件签名和一系列称为“数据块”(chunk)的部分组成。([W3C][1])

[!Tip] PNG 由多个 chunk 组成,chunk 的 layout 为: length(4-byte unsigned inreger), chunk type, chunk data, CRC(4 byte)


PNG 文件结构概述

一个标准的 PNG 文件由以下部分组成:

  1. 文件签名(Signature):固定的 8 字节序列,用于标识文件为 PNG 格式。

  2. 数据块(Chunks):紧随文件签名之后,PNG 文件由多个数据块组成,每个数据块包含特定类型的信息。([维基百科][2])


数据块(Chunk)结构详解

每个数据块由以下四部分组成:

  1. 长度(Length):4 字节,表示数据字段的字节数(不包括类型码和 CRC)。([W3C][1])

  2. 类型码(Chunk Type):4 字节,由 ASCII 字母组成,用于标识数据块的类型。([维基百科][2])

  3. 数据(Chunk Data):可变长度,包含与数据块类型相关的实际数据。([维基百科][2])

  4. CRC(Cyclic Redundancy Check):4 字节,用于校验类型码和数据字段的完整性。

例如,文件结束数据块(IEND)的结构如下:([维基百科][2])

  • 长度00 00 00 00([programmersought.com][3])

  • 类型码49 45 4E 44(即 “IEND”)([ctf-wiki.mahaloz.re][4])

  • 数据:无

  • CRCAE 42 60 82([ctf-wiki.mahaloz.re][4])

因此,PNG 文件通常以以下字节序列结束:([rfc-editor.org][5])


00 00 00 00 49 45 4E 44 AE 42 60 82

数据块类型及其作用

PNG 定义了多种数据块,主要分为两类:([维基百科][2])

关键数据块(Critical Chunks)

这些是解码 PNG 文件所必需的块:

  • IHDR:图像头部,包含图像的宽度、高度、颜色类型等基本信息。([维基百科][2])

  • PLTE:调色板,定义索引颜色图像的颜色表。

  • IDAT:图像数据,存储实际的图像像素数据。([维基百科][2])

  • IEND:图像结束,标识 PNG 数据流的结束。([维基百科][2])

辅助数据块(Ancillary Chunks)

这些块提供额外的信息,解码器可以选择忽略:

  • tEXt:存储未压缩的文本信息。

  • zTXt:存储压缩的文本信息。([CSDN][6])

  • iTXt:支持国际化的文本信息。

  • tIME:图像最后修改时间。([CSDN][6])

  • gAMA:图像的伽玛值,用于颜色校正。

  • cHRM:图像的色度信息。

  • sRGB:标准 RGB 色彩空间信息。([CSDN][6])

  • bKGD:建议的背景颜色。

  • pHYs:物理像素尺寸信息。([维基百科][2])

  • tRNS:透明度信息。([维基百科][2])


位置	字符	意义	解释
第1字节	I	是否为关键块(Critical)	大写表示关键块,必须被解析才能理解图片
第2字节	H	是否为公开块(Public)	大写表示这是 PNG 标准公开定义的类型,小写是私有块
第3字节	D	是否被保留(Reserved)	必须是大写,供将来标准扩展使用(当前应为大写)
第4字节	R	是否安全复制(Safe-to-copy)	小写表示可以安全复制,即使解码器不理解这个块
根据 PNG 规范,一个 chunk type 是合法的前提包括:
正好是 4 个 ASCII 字符。
每个字符必须是英文字母:A-Z 或 a-z。
第 3 个字符(保留位)必须是大写字母。
其他位的大小写有意义,但不影响是否合法(只影响语义)。

参考链接

PNG (Portable Network Graphics) Specification