WebP 格式
谷歌的现代图片格式
RIFF 容器
谷歌并没有为 WebP 另造一个容器,而是直接用了 RIFF,也就是从上世纪 90 年代初就在扛着 WAV 音频和 AVI 视频的那个格式。如果你解析过 WAV 文件, 那你已经懂了 WebP 在容器这一层是怎么回事。
这个格式用的是带 4 个字符标识符(叫 FourCC 码)的嵌套 chunk, 设计简单又结实,经受住了时间的考验。
WebP 文件结构(RIFF 容器)
WebP 文件头
| Offset | Hex | ASCII | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0000 | 52494646241A00005745425056503858 | RIFF$...WEBPVP8X | |||||||||||||||
| 0010 | 0A00000010000000FF0000FF00000000 | .............. | |||||||||||||||
RIFF chunk 的结构
注意:如果需要,chunk 数据会用一个空字节补齐到偶数长度。
几个关键偏移量
- • 子 chunk 起始位置:12 字节(RIFF + 大小 + WEBP 之后)
- • chunk 头:8 字节(4 字节 FourCC + 4 字节大小)
- • 大小字段的偏移:从 chunk 起始处 +4(小端序)
图像 chunk
WebP 其实是三种格式合在一起:有损(VP8)、无损(VP8L)和扩展(VP8X)。 chunk 类型会告诉你用的是哪种压缩方式。
VP8:有损压缩
使用 VP8 视频编解码器压缩,画质与体积的比例和 JPEG 接近。 简单 WebP 文件里就只有这一个 chunk。
VP8L:无损压缩
结合预测、色彩变换和熵编码的无损压缩,通常比 PNG 小 25-34%。
VP8X:扩展格式
表示文件带有可选功能:动画、透明通道、ICC 配置文件、EXIF 或 XMP。 只要用到其中任何一项,就必须有这个 chunk。
ALPH:透明通道
单独存放的透明通道数据,可以独立于颜色数据做无损或有损压缩。
ANIM/ANMF:动画
ANIM 存放全局动画参数,ANMF chunk 存放每一帧的画面和时间信息。
元数据 chunk
简单 WebP 文件里只有图像数据,而扩展 WebP 文件可以携带元数据。 好消息是这些 chunk 和图像数据划分得很清楚,识别和清除都很容易。
EXIF:EXIF 元数据
以与 JPEG 相同的格式(原始 TIFF 结构)存放 EXIF 数据, 包括相机信息、GPS 坐标、时间戳和缩略图。 隐私上最需要提防的部分。
XMP:XMP 元数据
基于 XML 的元数据,除了重复一份 EXIF 数据,还可能有编辑历史、 软件信息和自定义字段。
ICCP:ICC 色彩配置文件
用于色彩管理的 ICC 配置文件。为了颜色准确,PicScrub 默认会保留它。
VP8X 标志位
VP8X chunk 就像一份目录,告诉解码器这个文件里有些什么。 我们清除元数据 chunk 的时候,也得同步更新这些标志位, 否则解码器会去找一份根本不存在的数据。
标志位
标志位为什么重要
PicScrub 清除 EXIF/XMP chunk 时,必须同时更新 VP8X 的标志位来反映它们已经不在了。 否则解码器可能会去找一份不存在的数据。
PicScrub 如何处理 WebP
校验 RIFF 文件头
确认存在 RIFF....WEBP 签名
解析 chunk
遍历所有 RIFF chunk,读取 FourCC 和大小
清除元数据 chunk
写出结果时跳过 EXIF 和 XMP chunk
更新 VP8X 标志位
把 VP8X chunk 里的 EXIF/XMP 标志位清零
重新计算文件大小
用新的总大小更新 RIFF 文件头
会保留
- • VP8/VP8L 图像数据
- • ALPH 透明通道
- • ANIM/ANMF 动画数据
- • ICCP 色彩配置文件(可选)
会清除
- • EXIF 元数据
- • XMP 元数据
简单 WebP 与扩展 WebP
如果一个 WebP 文件里没有 VP8X chunk,那它就是“简单”WebP: 一层 RIFF 外壳裹着单个 VP8 或 VP8L chunk。简单 WebP 根本装不下元数据, 所以如果你在意隐私,这种文件是最理想的。
简单 WebP
只有 VP8 或 VP8L chunk,不可能有元数据。
扩展 WebP
带有 VP8X chunk,从而支持元数据、透明通道和动画。