图像格式编解码器与压缩工具深度解析

本文深入探讨图像压缩技术,对比JPEG与AVIF编解码器性能,分析SSIM和神经网络评估方法,并提供实用压缩工具建议,帮助开发者构建高效图像处理流程。

图像格式:编解码器与压缩工具

如果您错过了本系列之前的文章,请从第一部分《人类与设备的颜色模型》和第二部分《从编码器到解码器的像素数据》开始阅读。它们涵盖了图像压缩的基础知识。现在,在这最后一部分中,我们将采取更动手实践的方法。我们将使用不同的编解码器和压缩技术进行一些实验,并查看一些用于构建自己的图像流水线的有用工具。

让它们竞争

让我们考虑一个热门讨论话题:“JPEG格式是否仍然是图像压缩的最佳选择?” 不幸的是,没有明确的答案。每个任务都有其独特的背景。您是想优化编码速度?还是需要为专业摄影师提供高分辨率照片?如果您正在存储截图库或栅格化的矢量图形呢? 在决定对图像使用哪种压缩方法时,可以进行一些实验以找到最适合您需求的方法。与任何系统一样,最好从明确的需求列表开始——包括功能性需求(系统应该做什么)和非功能性需求(重要的系统指标)。 您可能需要思考以下一些问题:

  • 您正在处理什么类型的图像?是否有动物(注意毛发和羽毛)、地图、栅格化的HTML元素或矢量图形?它们的行为都不同。
  • 您的图像尺寸是多少?您需要显示大图像(一边超过1000像素)还是缩略图?
  • 您的最终用户是谁,他们使用什么设备?您的目标是移动用户吗?
  • 您的图像处理预算是多少?您需要处理大量图像吗?
  • 编码速度如何?如果您使用实时图像压缩,您可能更喜欢更快的编码而不是更好的压缩。您的压缩方法也会影响编码成本。尝试几种选项并进行一些快速的粗略计算。
  • 您需要什么质量水平?如果您的应用程序处理专业图像,您可能希望使用无损格式或支持更高位深度和更丰富色彩空间的格式。
  • 在您所需的质量下,图像看起来如何?例如,如果您想使用低质量图像,AVIF可以给出令人印象深刻的结果。但是,AVIF应用的滤镜可能会平滑掉一些细节,如毛发。
  • 您正在使用什么工具和系统?如果您必须使用现有系统或工具,请考虑它满足您需求的程度。例如,您可能使用图像处理工具,但它可能不支持您想要的格式或参数。

注意: 我们这里不考虑矢量图形。它们代表了一个完全不同的世界,有自己的一套技术和独特的挑战。本文我们只关注栅格图像。

通常,您会考虑几种可能适用于您项目的工具,然后决定使用哪种格式和编解码器。在这一点上,理解您所说的"图像质量"是什么意思非常重要。正如我们稍后将看到的,为图像分配质量甚至决定哪个图像更好是非常困难的。 您还需要记住,编码结果取决于几个因素:

  • 图像本身
  • 您使用的编解码器
  • 您发送给编解码器的参数

例如,正如我们在上一节中看到的,任何编解码器都可以轻松压缩黑色矩形,但对于每个编解码器,压缩白噪声都具有挑战性。

压缩松鼠

让我们通过一个示例来看看如何评估需求、探索可用选项并做出明智的权衡(您在自己的项目中不需要深入到这个程度 🙂)。 假设我们有一个带有松鼠图像的网站,我们想向用户展示其最佳版本。我们有一个原始源图像,尺寸为2733×3727像素,具有16位深度。不幸的是,文件大小约为50 MB,比我们预期的要大一些。 假设由于某种原因,我们只能使用JPEG或AVIF。 让我们尝试为最终图像选择最佳质量和编解码器参数。在这一点上,我们完全确定不想调整图像大小。 为了选择最佳质量,我们将进行以下实验:使用AVIF和JPEG编解码器将此图像压缩100次。每次我们将质量参数增加1;我们将从1开始,一直到100。

注意: 仅基于一张图像得出结论是不好的做法。为了进行可靠的估计,我们需要一个图像数据集和具有统计意义的结果进行比较。

我们绘制了结果,发现AVIF表现差得多——与JPEG相比,在相同质量下它生成的文件大小要大得多。

您可能会发现这个结论有几个问题。我们使用了什么编解码器参数?我们的比较可能是错误的吗?让我们看看AVIF编码器的日志:

看起来我们禁用了下采样并使用了12位深度。让我们修复这个问题,为两个编解码器设置8位深度和4:2:0子采样。

注意: 在真实场景中,理想情况下您应该尝试所有选项组合,而不是减少编解码器参数。

我们可以观察到情况发生了变化,但JPEG仍然获胜。这怎么可能? 如果您阅读了本系列之前的文章,您会记得我们为AVIF传递给编码器的数字与JPEG不同。我们正在比较不可比较的实体。 所以,我们需要一个"真实质量"的度量标准。第一次尝试是逐像素比较图像。有一个特殊的度量标准叫做均方误差(MSE)。然而,它在比较压缩结果时效果不佳。MSE是一个"越低越好"的度量标准;0表示图像相同。不幸的是,MSE效果不好。如果我们意外引入几个非常不同的像素,误差就会变大。它也不考虑图像结构、颜色或亮度,并且对大量噪声的惩罚较弱。 还有另一个度量标准叫做峰值信噪比(PSNR),它仍然被广泛使用。它的计算方式不同,但存在与MSE相同的问题。 更好的选择是结构相似性指数(SSIM)。这个度量标准试图模拟人类感知以及我们在上一节讨论的其他方面。不深入细节,SSIM将图像分成小的重叠块。对于每个块,它估计亮度、对比度和结构的差异,然后对所有块的结果进行平均。SSIM是一个"越高越好"的度量标准;1表示图像相同。 让我们将这个度量标准应用到我们的实验中。我们高兴地得到了预期的结果。根据图表,AVIF显示出相对于JPEG的显著优势,特别是对于低质量图像。橙线(AVIF)更高,这意味着在相同文件大小下它给出更好的SSIM。我们对x轴应用对数刻度以使图表更易读。

当然,所有这些数学度量标准可能不适合您的任务。

压缩乌鸦

让我们考虑另一个例子。这是乌鸦的原始图像:

这是经过一些调整的相同图像:第一个已被修改,第二个缺少乌鸦。

调整过的乌鸦 缺少乌鸦

猜猜哪个有更好的度量标准?

注意: 正如我们提到的,质量是一个主观话题。直觉上,我会投票认为第一张图像更好,因为主要对象可见。但是,如果图像中的噪声或其他伪影对您来说绝对不可接受,您可能更喜欢第二张图像。

询问神经网络

除了 solely 依赖数学推导的度量标准,我们可以利用神经网络。野外有许多方法被认为是SSIM的替代品。大量论文证明神经网络能够更好地模拟人类感知。并且它们是在由人类标记的图像上训练的。 让我们选择其中一种评估方法,并将其应用到消失乌鸦的问题上。 模型认为有乌鸦出现的图像更好(0.52 vs 0.47,结果越接近1越好)。现在让我们在一个稍微修改过的松鼠压缩练习中使用这个模型。这次,我们将松鼠调整大小为1000×1000像素(并裁剪其美丽的尾巴),像这样:

这也更接近真实世界的任务。大多数图像都很小,尽管看起来它们没有被正确压缩。根据HTTP Archive,在2025年,图像的平均大小约为1MB,对应于中等质量的2000×2000像素JPEG。 在创建了100个JPEG和100个AVIF并比较它们的质量后,AVIF仍然获胜。

作为最后的修饰,我们将绘制几个图像示例以进行视觉比较。让我们先看看非常低质量的图像:

松鼠1 松鼠2

如果您阅读了上一节,您已经知道这些图像为什么看起来是这样。AVIF使用更大的瓦片(导致大的色块)和导致模糊毛发的滤镜。在AVIF图像中,您可以看到它失去了所有颜色细节,并且有微小的8x8块,这是JPEG使用的唯一块。 现在看看这两个。哪个更好?

松鼠1 松鼠2

答案 第一个是AVIF,第二个是JPEG。35KB vs 97KB。

为了说明准确选择编解码器的重要性,让我们运行更多比较:

松鼠1 松鼠2

两张图像都是75质量的JPEG。它们看起来一模一样,哈哈。然而,第一个小30%。这些图像是由不同的编解码器生成的。第一个使用MozJPEG,第二个使用Chrome的内置编解码器。 还有最后一个例子:

松鼠1 松鼠2

两张图像都是由相同的编解码器生成的,但使用了不同的编解码器参数:

结论

在压缩图像时,请记住以下提示:

  • 在许多情况下,您不需要自己压缩图像。考虑使用允许实时图像处理的云服务。它们让您选择要提供的图像大小、质量和格式。它们还允许以多种格式提供图像,这可能非常具有成本效益。例如,Cloudflare将多种图像格式计为一种。您还将获得开箱即用的调整大小和裁剪功能。实时图像仍然是可配置的;您可以通过将参数添加到URL来设置编解码器参数。
  • 如果您以前从未考虑过图像压缩,请考虑一个非常简单的练习:使用参数Q=75,strip,interlace用MozJPEG压缩您的图像。当然,您可以根据需要调整质量。您可能会惊讶于静态文件占用的空间如此之少。
  • 作为下一级别,将您的图像压缩为其他格式并比较结果。您可以使用<picture>元素为不同设备提供多种格式。尝试更现代的格式,如WebP或AVIF。
  • 在可能的情况下,不要忘记使用渐进式图像。但是,不要使用交错PNG,因为它们比非交错的大。实际上,如果可能的话,完全避免使用PNG。有更高效的无损格式,如WebP或AVIF。
  • 当您压缩图像时,注意您使用的编解码器。您可以使用压缩工具,如vips或sharp。不要忘记您可以向编解码器或工具传递参数。进行实验,找到最适合您需求的解决方案。您还可以使用在线压缩UI,如Squoosh,或为您的程序使用特殊插件(如Figma)。
  • 如果图像在屏幕上不可见,不要加载它!有几种有用的技术,从超级简单的loading="lazy"属性到更高级的技术,如Intersection Observer API。
  • 收集关于您图像使用情况的统计数据。主动监控和优化您的图像。

祝压缩愉快!

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计