30 秒看懂
Theo Browne 阅读 Evan Hahn 的文章,逐项拆解一个只有一个像素、大小为 67 字节的 PNG。他还讨论调色板、隔行扫描、压缩开销,以及为何其他小图像也能达到相同文件大小。
- 1固定开销签名和必需数据块占据了这个极小文件的大部分空间。
- 2IHDR 描述图像图像头记录尺寸、颜色类型、位深和其他方法。
- 3压缩也可能增加字节对于两个字节的数据,zlib 开销使结果更大。
- 4更多像素,相同大小一幅 8×1 黑色图像可以与单像素例子占用相同空间。
要点建议
- PNG 以固定签名开头,后面是带类型的数据块。
- 即使只有一个像素,必需数据块也会产生开销。
- 图像头记录尺寸、颜色类型、位深和编码方法。
- 滤镜为压缩准备扫描线字节,可以使用相邻数据。
- 压缩开销可能让极小的数据变大。
按章节阅读整理后的全文
67 字节的 PNG
Theo Browne 解读 Evan Hahn 关于一个 67 字节 PNG 的文章。图像只有一个黑色像素,却能展示格式所需的结构,以及几乎没有图像数据时仍存在的开销。
Theo Browne 解读 Evan Hahn 关于一个 67 字节 PNG 的文章。图像只有一个黑色像素,却能展示格式所需的结构,以及几乎没有图像数据时仍存在的开销。
这个例子有四部分:8 字节签名、25 字节图像头数据块、22 字节图像数据块和 12 字节结束数据块,总计 67 字节。
签名与数据块
每个 PNG 都以相同的 8 字节签名开头。解码器可以先检查签名,再解析文件的其余部分;签名中包含 PNG 字母,有助于识别格式。
每个 PNG 都以相同的 8 字节签名开头。解码器可以先检查签名,再解析文件的其余部分;签名中包含 PNG 字母,有助于识别格式。
签名之后,文件由数据块组成。每个块包含长度、4 字节类型、数据和 4 字节 CRC 校验和;即使没有数据,块本身也要占 12 字节。
长度字段只描述数据部分的大小,而非整个块的大小。必需的数据块有规定顺序:图像头在图像数据之前,IEND 标志文件结束。
Browne 将逐步加载图像与基线 JPEG 和渐进式 JPEG 作比较。他后来纠正自己:PNG 也支持隔行扫描,可以先显示粗略图像,再逐渐补足细节。
图像头
IHDR 块包含 13 字节数据,记录宽、高、位深、颜色类型、压缩、滤镜和隔行扫描方法;长度、类型及校验和又增加 12 字节。
IHDR 块包含 13 字节数据,记录宽、高、位深、颜色类型、压缩、滤镜和隔行扫描方法;长度、类型及校验和又增加 12 字节。
在这个例子中,宽和高都是 1。灰度颜色类型 0 和每个采样 1 位就足以表示黑色像素,无需真彩色所需的额外通道。
位深决定每个采样能表示多少种数值。表达能力更强的格式也能生成同样的黑色像素,但描述它可能需要更多数据。
颜色与透明度
Browne 解释索引颜色:调色板保存可用颜色,像素通过索引指向其中的条目。当图像只使用有限颜色时,这可以节省空间。
Browne 解释索引颜色:调色板保存可用颜色,像素通过索引指向其中的条目。当图像只使用有限颜色时,这可以节省空间。
透明度需要额外的表示方式,例如 alpha 通道或其他受支持的透明信息。Browne 提到,浏览器视频工作流与静态图像格式对透明度的处理有所不同。
该例子的 PNG 压缩方法和滤镜方法都设为 0,也不使用隔行扫描。IHDR 校验和覆盖块类型与数据,可用于检测损坏。
扫描线与压缩
IDAT 块保存压缩后的图像数据。压缩之前,像素按扫描线排列,每条扫描线前有一个字节标明所用滤镜。
IDAT 块保存压缩后的图像数据。压缩之前,像素按扫描线排列,每条扫描线前有一个字节标明所用滤镜。
单像素例子使用 0 号滤镜,即不做滤镜处理。Browne 纠正了此前过于简单的说法:[PNG 滤镜](https://www.w3.org/TR/PNG-Filters.html)可以利用相邻字节或前一条扫描线,为压缩准备数据。
黑色像素只需要 1 位,但扫描线要填充到完整字节。加上滤镜字节,这个例子的未压缩图像数据是两个零字节。
PNG 使用 zlib 封装基于 DEFLATE 的图像数据。压缩通常节省空间,但对于两个字节,头部与校验和的开销会让编码结果比输入更大。
10 字节的 zlib 数据包括头部、压缩块和 Adler-32 校验和;外围的 IDAT 块还有自己的 CRC,承担另一层完整性检查。
结束标记与其他小图像
最后的 IEND 块没有数据字节,但仍需要长度、类型和 CRC 字段。这个固定的 12 字节结尾完成了该最小示例。
最后的 IEND 块没有数据字节,但仍需要长度、类型和 CRC 字段。这个固定的 12 字节结尾完成了该最小示例。
单像素图像并非唯一达到这一文件大小的图像。文章展示了一幅同样为 67 字节的 8×1 黑色图像,因为它利用了原本在像素字节中作为填充的位。
例子中,具有更多灰度等级的单像素图像也能保持 67 字节。由此可见,文件开销和压缩表现并不会直接按可见像素数量缩放。
探索真实 PNG 文件
Browne 回顾了签名、必需数据块和压缩数据。他用作者的数据块浏览工具查看较大的 PNG,展示其中的元数据和多个图像数据块。
Browne 回顾了签名、必需数据块和压缩数据。他用作者的数据块浏览工具查看较大的 PNG,展示其中的元数据和多个图像数据块。
他还介绍了一个通过程序生成单色 PNG 的例子。把格式理解为结构化字节,而不只是导出目标,有助于理解这类工具。
最后,Browne 提到,即使格式能表示很大的图像,解码器也会施加实际限制。他感谢 Hahn 的文章,并鼓励读者继续探索这个格式。
同频道的其他文章
49:29EN → 简体中文
41:49EN → 简体中文
38:47EN → 简体中文
36:07EN → 简体中文
30:37EN → 简体中文
0:43EN → 简体中文