图片格式:WebP

Google 最初开发 WebP 作为一种有损图片格式,旨在取代 JPEG,它能够生成比同等质量的 JPEG 编码图片文件更小的文件。该格式的后续更新引入了无损压缩、类似 PNG 的 Alpha 通道透明度和类似 GIF 的动画选项,所有这些都可以与 JPEG 风格的有损压缩一起使用。WebP 是一种非常通用的格式。

WebP 的有损压缩算法基于 VP8 视频编解码器 用于压缩视频中的关键帧的方法。从宏观层面来看,它类似于 JPEG 编码:WebP 以“块”而不是单个像素为单位进行操作,并且在亮度和色度之间有类似的划分。WebP 的亮度块为 16x16,而色度块为 8x8,这些“宏块”进一步细分为 4x4 子块。

WebP 与 JPEG 的根本区别在于两个特性:“块预测”和“自适应块量化”。

块预测

块预测是通过周围块(特别是当前块上方和左侧的块)的值来预测每个色度和亮度块内容的过程。您可以想象,执行此工作的算法相当复杂,但用通俗易懂的语言来说:“如果当前块上方是蓝色,并且当前块左侧是蓝色,则假定此块是蓝色。”

实际上,PNG 和 JPEG 在某种程度上也进行这种预测。但是,WebP 的独特之处在于,它对周围块的数据进行采样,然后尝试通过几种不同的“预测模式”来填充当前块,从而有效地尝试“绘制”图像的缺失部分。然后,将每种预测模式提供的结果与真实图像数据进行比较,并选择最接近的预测匹配项。

A diagram of WebP’s various block prediction methods.

当然,即使是最接近的预测匹配项也不会完全正确,因此,预测值与该块的实际值之间的差异会编码在文件中。解码图像时,渲染引擎使用相同的数据来应用相同的预测逻辑,从而为每个块生成相同的预测值。然后在预测值之上应用预测值与文件中编码的预期图像之间的差异,这类似于 Git 提交表示应用于本地文件的差异补丁,而不是文件的全新副本。

为了进行说明:我们不会深入研究真实预测算法中涉及的复杂数学运算,而是发明一种具有单一预测模式的类 WebP 编码,并像处理旧格式一样使用它来有效地传递数字网格。我们的算法具有单一预测模式,我们将其称为“预测模式 1”:每个块的值是其上方和左侧块的值之和,从 1 开始。

现在,假设我们从以下真实图像数据开始

111151111
122456389

使用我们的预测模型来确定 2x9 网格的内容,我们将获得以下结果

111111111
123456789

我们的数据非常适合我们发明的预测算法,预测数据与我们的真实数据非常匹配。当然,并非完全匹配,实际数据中有几个块与预测数据不同。因此,我们发送的编码不仅包括要使用的预测方法,还包括应与其预测值不同的任何块的差异

_ _ _ _ +4 _ _ _ _
_ _ -1 _ _ _ -4 _ _

用与我们讨论过的一些旧格式编码相同的通俗易懂的语言表达

使用预测模式 1 的 2x9 网格。+4 到 1x5,-1 到 2x3,-4 到 2x7。

最终结果是一个非常高效的编码文件。

自适应块量化

JPEG 压缩是一种全面操作,对图像中的每个块应用相同级别的量化。在构图均匀的图像中,这当然是有道理的,但现实世界的照片与我们周围的世界一样不均匀。实际上,这意味着我们的 JPEG 压缩设置不是由 JPEG 压缩擅长的高频细节决定的,而是由图像中最可能出现压缩伪影的部分决定的。

A compressed JPEG image of a monarch butterfly

正如您在这个夸张的示例中所看到的,前景中帝王蝶的翅膀看起来相对清晰,与高分辨率原图相比有点颗粒感,但如果没有原图进行比较,肯定不明显。同样,马利筋的详细花序和前景中的叶子,您和我可能会用我们训练有素的眼睛看到压缩伪影的痕迹,但即使在压缩率远超合理水平的情况下,前景中的事物看起来仍然相当清晰。图片左上角的低频信息(叶子的模糊绿色背景)看起来糟糕透顶。即使是没有受过训练的观看者也会立即注意到质量问题,背景中细微的渐变被舍入为锯齿状的纯色块。

为了避免这种情况,WebP 对量化采用自适应方法:图像被分成最多四个视觉上相似的段,并且独立调整这些段的压缩参数。将相同的超大压缩应用于 WebP

A compressed WebP image of a monarch butterfly

这两个图片文件的大小大致相同。当我们查看帝王蝶的翅膀时,质量大致相同,如果您非常非常仔细地观察,您可能会发现最终结果存在一些细微差异,但在整体质量上没有真正的差异。在 WebP 中,马利筋的花朵稍微清晰一些,同样,除非您并排比较这两个文件并真正寻找质量差异(就像我们现在这样),否则可能不足以引起注意。背景则完全是另一回事:它几乎没有 JPEG 明显伪影的痕迹。WebP 为我们提供了相同的文件大小,但图像质量更高得多,只是我们心理视觉系统无法检测到的一些微小细节,除非我们如此密切地比较这两者。

使用 WebP

WebP 的内部结构可能比 JPEG 编码复杂得多,但对于我们的日常工作而言,它同样简单:WebP 编码的所有复杂性都围绕一个单一的“质量”值进行标准化,该值从 0 到 100 表示,就像 JPEG 一样。再说一遍,这并不是说您仅限于单一的总体“质量”设置。您可以而且应该调整 WebP 编码的所有精细细节,哪怕只是为了更好地了解这些通常不可见的设置如何影响文件大小和质量。

Google 提供了一个 cwebp 命令行编码器,可让您转换或压缩单个文件或整个图片目录

$ cwebp -q 80 butterfly.jpg -o butterfly.webp

Saving file 'butterfly.webp'
File:   butterfly.jpg
Dimension: 1676 x 1418
Output: 208418 bytes Y-U-V-All-PSNR 41.00 43.99 44.95   41.87 dB
        (0.70 bpp)
block count:    intra4:     7644  (81.80%)
               Intra16:     1701  (18.20%)
               Skipped:       63  (0.67%)
bytes used:  header:            249  (0.1%)
              mode-partition:  36885  (17.7%)
Residuals bytes  |segment 1|segment 2|segment 3|segment 4|  total
macroblocks:     |       8%|      22%|      26%|      44%|   9345
quantizer:       |      27 |      25 |      21 |      13 |
filter level:    |       8 |       6 |      19 |      16 |

如果您不喜欢命令行,Squoosh 同样可以很好地用于 WebP 编码。它使我们可以选择并排比较不同编码、设置、质量级别以及与 JPEG 编码的文件大小差异。