一个 67 字节的 PNG 如何存储单个黑色像素

原标题How a 67-Byte PNG Stores a Single Black Pixel

Theo Browne 用一个极小的例子讲解 PNG 签名、数据块、滤镜和压缩。

TBTheo Browne讲者 · Theo - t3․gg
频道
Theo - t3․gg
发布
2024年2月1日
视频
20:52
阅读
4 分钟
原文
英语
在 YouTube 打开
往下滚动阅读时,视频会缩到右下角继续播放。字幕跟随阅读语言。
阅读语言共 2 种语言可读
由 AI 从英语原文翻译。打开“对照原文”可以逐段核对。
摘要

30 秒看懂

Theo Browne 阅读 Evan Hahn 的文章,逐项拆解一个只有一个像素、大小为 67 字节的 PNG。他还讨论调色板、隔行扫描、压缩开销,以及为何其他小图像也能达到相同文件大小。

  1. 1固定开销签名和必需数据块占据了这个极小文件的大部分空间。
  2. 2IHDR 描述图像图像头记录尺寸、颜色类型、位深和其他方法。
  3. 3压缩也可能增加字节对于两个字节的数据,zlib 开销使结果更大。
  4. 4更多像素,相同大小一幅 8×1 黑色图像可以与单像素例子占用相同空间。

要点建议

  1. PNG 以固定签名开头,后面是带类型的数据块。
  2. 即使只有一个像素,必需数据块也会产生开销。
  3. 图像头记录尺寸、颜色类型、位深和编码方法。
  4. 滤镜为压缩准备扫描线字节,可以使用相邻数据。
  5. 压缩开销可能让极小的数据变大。
全文

按章节阅读整理后的全文

只看原始文稿
01

67 字节的 PNG

Theo Browne 解读 Evan Hahn 关于一个 67 字节 PNG 的文章。图像只有一个黑色像素,却能展示格式所需的结构,以及几乎没有图像数据时仍存在的开销。

Theo Browne 解读 Evan Hahn 关于一个 67 字节 PNG 的文章。图像只有一个黑色像素,却能展示格式所需的结构,以及几乎没有图像数据时仍存在的开销。

这个例子有四部分:8 字节签名、25 字节图像头数据块、22 字节图像数据块和 12 字节结束数据块,总计 67 字节。

02

签名与数据块

每个 PNG 都以相同的 8 字节签名开头。解码器可以先检查签名,再解析文件的其余部分;签名中包含 PNG 字母,有助于识别格式。

每个 PNG 都以相同的 8 字节签名开头。解码器可以先检查签名,再解析文件的其余部分;签名中包含 PNG 字母,有助于识别格式。

签名之后,文件由数据块组成。每个块包含长度、4 字节类型、数据和 4 字节 CRC 校验和;即使没有数据,块本身也要占 12 字节。

长度字段只描述数据部分的大小,而非整个块的大小。必需的数据块有规定顺序:图像头在图像数据之前,IEND 标志文件结束。

Browne 将逐步加载图像与基线 JPEG 和渐进式 JPEG 作比较。他后来纠正自己:PNG 也支持隔行扫描,可以先显示粗略图像,再逐渐补足细节。

03

图像头

IHDR 块包含 13 字节数据,记录宽、高、位深、颜色类型、压缩、滤镜和隔行扫描方法;长度、类型及校验和又增加 12 字节。

IHDR 块包含 13 字节数据,记录宽、高、位深、颜色类型、压缩、滤镜和隔行扫描方法;长度、类型及校验和又增加 12 字节。

在这个例子中,宽和高都是 1。灰度颜色类型 0 和每个采样 1 位就足以表示黑色像素,无需真彩色所需的额外通道。

位深决定每个采样能表示多少种数值。表达能力更强的格式也能生成同样的黑色像素,但描述它可能需要更多数据。

04

颜色与透明度

Browne 解释索引颜色:调色板保存可用颜色,像素通过索引指向其中的条目。当图像只使用有限颜色时,这可以节省空间。

Browne 解释索引颜色:调色板保存可用颜色,像素通过索引指向其中的条目。当图像只使用有限颜色时,这可以节省空间。

透明度需要额外的表示方式,例如 alpha 通道或其他受支持的透明信息。Browne 提到,浏览器视频工作流与静态图像格式对透明度的处理有所不同。

该例子的 PNG 压缩方法和滤镜方法都设为 0,也不使用隔行扫描。IHDR 校验和覆盖块类型与数据,可用于检测损坏。

05

扫描线与压缩

IDAT 块保存压缩后的图像数据。压缩之前,像素按扫描线排列,每条扫描线前有一个字节标明所用滤镜。

IDAT 块保存压缩后的图像数据。压缩之前,像素按扫描线排列,每条扫描线前有一个字节标明所用滤镜。

单像素例子使用 0 号滤镜,即不做滤镜处理。Browne 纠正了此前过于简单的说法:[PNG 滤镜](https://www.w3.org/TR/PNG-Filters.html)可以利用相邻字节或前一条扫描线,为压缩准备数据。

黑色像素只需要 1 位,但扫描线要填充到完整字节。加上滤镜字节,这个例子的未压缩图像数据是两个零字节。

PNG 使用 zlib 封装基于 DEFLATE 的图像数据。压缩通常节省空间,但对于两个字节,头部与校验和的开销会让编码结果比输入更大。

10 字节的 zlib 数据包括头部、压缩块和 Adler-32 校验和;外围的 IDAT 块还有自己的 CRC,承担另一层完整性检查。

06

结束标记与其他小图像

最后的 IEND 块没有数据字节,但仍需要长度、类型和 CRC 字段。这个固定的 12 字节结尾完成了该最小示例。

最后的 IEND 块没有数据字节,但仍需要长度、类型和 CRC 字段。这个固定的 12 字节结尾完成了该最小示例。

单像素图像并非唯一达到这一文件大小的图像。文章展示了一幅同样为 67 字节的 8×1 黑色图像,因为它利用了原本在像素字节中作为填充的位。

例子中,具有更多灰度等级的单像素图像也能保持 67 字节。由此可见,文件开销和压缩表现并不会直接按可见像素数量缩放。

07

探索真实 PNG 文件

Browne 回顾了签名、必需数据块和压缩数据。他用作者的数据块浏览工具查看较大的 PNG,展示其中的元数据和多个图像数据块。

Browne 回顾了签名、必需数据块和压缩数据。他用作者的数据块浏览工具查看较大的 PNG,展示其中的元数据和多个图像数据块。

他还介绍了一个通过程序生成单色 PNG 的例子。把格式理解为结构化字节,而不只是导出目标,有助于理解这类工具。

最后,Browne 提到,即使格式能表示很大的图像,解码器也会施加实际限制。他感谢 Hahn 的文章,并鼓励读者继续探索这个格式。

同频道的其他文章

4 张幻灯片49:29EN → 简体中文
Theo - t3․gg· 2026年10月30日Theo:智能体 Harness、界面与不断变化的抽象层次Theo · T3 CodeT3 Code 创建者解释他对 harness 的理解,以及为什么他预计用户会越来越少地注意它们的差异。编程智能体智能体工程Software engineering+2
5 张幻灯片41:49EN → 简体中文
Theo - t3․gg· 2026年10月29日Theo 演示如何用 T3 Code 协调编码智能体Theo · t3.ggT3 Code 的创建者介绍多个智能体提供方、远程机器、会话组织方式,以及开源编码界面的取舍。Agent orchestration开发流程与测试智能体工程+2
5 张幻灯片38:47EN → 简体中文
Theo - t3․gg· 2026年10月28日Theo 的长时间 Agent 实验:验证、算力与成本Theo Browne · Ping Labs滑板游戏和两个编译器项目展示了反复检查与弹性算力如何支撑 agent 工作,也揭示了循环可能带来的高昂成本。编程智能体智能体工程AI cost & performance+2
5 张幻灯片36:07EN → 简体中文
Theo - t3․gg· 2026年10月27日Theo 谈 Token 成本、编程智能体与 AI 能力的价格Theo Browne · Ping Labs一则关于 Lauren 的 AI 支出估算广泛传播,引出了对缓存计价、基准测试和编程智能体工作方式的讨论。AI cost & performance编程智能体Inference+1
5 张幻灯片30:37EN → 简体中文
Theo - t3․gg· 2026年10月26日Theo 的三个技能:用编程智能体审查和交付代码Theo Browne · Ping Labssol-loop、full-send 和 full-stop 如何定义审查、验证以及不同程度的合并权限。Agent skills编程智能体Code review & verification+2
2 张幻灯片0:43EN → 简体中文
Theo - t3․gg· 2026年10月23日Theo 区分安全漏洞与实际攻击Theo Browne · Ping Labs一段简短讲解:软件漏洞披露和攻击事件为何属于不同类型的安全新闻。CybersecuritySoftware engineering