PicScrub logoPicScrub
返回格式列表

PNG 格式

Portable Network Graphics

基于 chunk 的结构

PNG 大概是最干净利落的文件格式之一。所有内容都被组织成一个个“chunk”, 每个 chunk 自成一体,带着类型、数据和校验和。妙就妙在解码器可以直接跳过 自己看不懂的 chunk,PNG 因此能支持元数据,又不会让老软件读不了。

更聪明的是 chunk 的命名规则:首字母大写表示“关键”(缺了它图片就显示不出来), 小写则表示“辅助”,有更好,没有也不影响。我们关心的那些元数据 chunk 全都是辅助型的, 所以可以放心删掉。

PNG 文件结构

Signature
IHDR
Metadata
IDAT
IEND
Signature
8 字节
89 50 4E 47 0D 0A 1A 0A
IHDR
25 字节
图像头(必需)
Metadata
100 字节
tEXt、iTXt、eXIf 等 chunk
IDAT
长度可变
压缩后的图像数据
IEND
12 字节
图像结束标记

PNG 签名和 IHDR

PNG 签名
IHDR 长度(13)
IHDR 类型
宽度(256)
高度(256)
位深、颜色类型等
OffsetHexASCII
0000
89504E470D0A1A0A0000000D49484452
.PNG........IHDR
0010
00000100000001000802000000000000
.............

chunk 的结构

长度类型数据CRC32
4 字节4 字节可变4 字节

chunk 类型的命名约定

  • • 首字母大写 = 关键 chunk(必须能被理解)
  • • 首字母小写 = 辅助 chunk(可选,可以忽略)
  • • 第二个字母 = 公有(大写)或私有(小写)

关键 chunk

这些 chunk 必须存在、必须能被理解,图片才算有效。PicScrub 永远会保留关键 chunk。

IHDR:图像头

紧跟在签名之后的第一个 chunk,包含宽度、高度、位深、颜色类型、 压缩方法、过滤方法和隔行扫描方法,数据部分正好 13 字节。

IDAT:图像数据

存放压缩后(zlib/deflate)的图像数据,可能被拆成多个 IDAT chunk, 但所有 IDAT chunk 必须连续排列。

IEND:图像结束

标记 PNG 数据流的结束,必须是最后一个 chunk,数据部分为零字节。

PLTE:调色板

索引颜色图片(颜色类型 3)必需,包含 1–256 个 RGB 调色板条目。

元数据 chunk

这些辅助 chunk 可能装着涉及隐私的元数据,也正是 PicScrub 会清除的部分。

tEXt:未压缩文本

以 Latin-1 编码存放的键值对。常见的键有 Author、Description、 Copyright、Creation Time、Software。

Format: keyword + null + text

zTXt:压缩文本

和 tEXt 一样,只是用 zlib 压缩过,适合放较长的文本内容。

iTXt:国际化文本

UTF-8 文本,可选压缩,支持语言标签和翻译过的关键词,XMP 元数据就放在这里。

XMP keyword: XML:com.adobe.xmp\0

eXIf:EXIF 数据

2017 年被登记为 PNG 的扩展。里面是 TIFF 格式的原始 EXIF 数据, 结构和 JPEG 里的 EXIF 一样。 可能包含 GPS、时间戳和设备信息。

iCCP:ICC 色彩配置文件

内嵌的 ICC 色彩配置文件,用 zlib 压缩。为了颜色准确,PicScrub 默认会保留它。

tIME:最后修改时间

七个字节:年(2 字节)、月、日、时、分、秒,会暴露图片最后一次被修改的时间。

与颜色相关的 chunk

这些 chunk 会影响颜色的呈现,但通常不含个人信息,PicScrub 默认保留它们。

sRGB

声明使用 sRGB 色彩空间,用一个字节表示渲染意图。

gAMA

伽马值,以 4 字节无符号整数表示(乘以 100,000 后存储)。

cHRM

三原色的色度坐标和白点坐标。

sBIT

各通道原始采样的位深。

CRC32 校验

每个 PNG chunk 都带着一个 CRC32 校验和,覆盖 chunk 类型和数据,用来保证数据完整。

CRC 的计算方式

CRC32 input = chunk_type (4 bytes) + chunk_data (N bytes)
CRC32 output = 4 bytes appended after chunk data

// PNG 使用的 CRC-32 多项式:0xEDB88320

PicScrub 为什么要校验 CRC

读取 PNG 文件时,PicScrub 会校验每个 chunk 的 CRC,以确保数据完整。 遇到损坏的 chunk 也会妥善处理,不会直接崩掉。

PicScrub 如何处理 PNG

1

校验签名

确认 PNG 签名:89 50 4E 47 0D 0A 1A 0A

2

解析 chunk

读取每个 chunk 的长度和类型,并校验 CRC

3

过滤元数据 chunk

识别并跳过 tEXt、zTXt、iTXt、eXIf、tIME 这些 chunk

4

重新拼出文件

写入签名 + 过滤后的 chunk + IEND

保留的 chunk

  • • IHDR、PLTE、IDAT、IEND(关键)
  • • sRGB、gAMA、cHRM(颜色)
  • • iCCP(色彩配置文件,可选)
  • • pHYs(像素尺寸)
  • • tRNS(透明度)

清除的 chunk

  • • tEXt(文本元数据)
  • • zTXt(压缩文本)
  • • iTXt(国际化文本、XMP)
  • • eXIf(EXIF 数据)
  • • tIME(修改时间)