JPEG 是如何工作的:交互式探索 JPEG 的有损压缩方法

Hacker News Top 新闻

摘要

一篇交互式文章,解释 JPEG 有损压缩的工作原理,涵盖色彩空间转换、频域、量化和编码步骤。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/07/31 20:00

# JPEG 是如何工作的(Christopher G. Jennings) 来源:https://cgjennings.ca/articles/jpeg-compression/ 2017年9月9日 约11分钟 可视化 (https://cgjennings.ca/articles/?tag=Visualization)图像 (https://cgjennings.ca/articles/?tag=Images)压缩 (https://cgjennings.ca/articles/?tag=Compression)JPEG (https://cgjennings.ca/articles/?tag=JPEG)STEM (https://cgjennings.ca/articles/?tag=STEM)[](https://cgjennings.ca/feed.atom)互动式探索 JPEG 的有损压缩方法 目录 1. 引言 (https://cgjennings.ca/articles/jpeg-compression/#introduction)1. 压缩方法 (https://cgjennings.ca/articles/jpeg-compression/#compression-methods) 2. 编码 (https://cgjennings.ca/articles/jpeg-compression/#encoding)1. 输入图像 (https://cgjennings.ca/articles/jpeg-compression/#the-input-image) 2. 第一步:分离颜色信息 (https://cgjennings.ca/articles/jpeg-compression/#step-1%3A-isolate-the-colour-information) 3. 第二步:丢弃部分颜色信息 (https://cgjennings.ca/articles/jpeg-compression/#step-2%3A-throw-away-some-colour-information) 4. 第三步:转换到频域 (https://cgjennings.ca/articles/jpeg-compression/#step-3%3A-convert-to-the-frequency-domain) 5. 第四步:质量滑块(量化) (https://cgjennings.ca/articles/jpeg-compression/#step-4%3A-the-quality-slider-(quantization)) 6. 第五步:无损数据压缩 (https://cgjennings.ca/articles/jpeg-compression/#step-5%3A-lossless-data-compression) 3. 解码 (https://cgjennings.ca/articles/jpeg-compression/#decoding)1. 第六步:解压缩 (https://cgjennings.ca/articles/jpeg-compression/#step-6%3A-decompression) 2. 第七步:从量化数据重建 (https://cgjennings.ca/articles/jpeg-compression/#step-7%3A-reconstruction-from-quantized-data) 3. 第八步:转换回空间域 (https://cgjennings.ca/articles/jpeg-compression/#step-8%3A-convert-back-to-spatial-domain) 4. 第九步:填补缺失的颜色信息 (https://cgjennings.ca/articles/jpeg-compression/#step-9%3A-fill-in-missing-colour-information) 5. 第十步:转换回 RGB (https://cgjennings.ca/articles/jpeg-compression/#step-10%3A-convert-back-to-rgb) 6. 输出图像 (https://cgjennings.ca/articles/jpeg-compression/#the-output-image) ## 引言 在科技世界里,“永远”大约是 5 年。想到 1992 年的 JPEG 图像标准已经经历了 5 个多“永远”,却依然强劲,这确实令人感慨。它为何如此成功?这篇文章用通俗的语言介绍 JPEG 背后的关键思想,并且页面中直接内置了一个交互式 JPEG 压缩器,你可以边读边玩。 ### 压缩方法 压缩技术会在数据中寻找重复模式,然后用更短的模式替代它们。这就像用缩写或首字母缩略词来代替较长的单词或短语。视频、静态图像和音频通常不容易被压缩。图像和声音的问题在于,这些数据通常过于嘈杂,难以找到好的缩写。因此,JPEG 和许多其他媒体格式使用了一种叫做**有损压缩**的技术。 有损压缩意味着你通过*丢弃*一些信息来减小文件大小。假设一位图书管理员的书架已经放满了,需要为更多书腾出空间。如果她用数字副本或缩微胶片替换一些书,那是无损压缩。如果她烧掉一些书,那就是有损压缩。 > 重要的不是你要弹的音符,而是你不弹的音符。迈尔斯·戴维斯(Miles Davis) 好的*有损压缩*的诀窍在于丢掉那些没人在意的信息:烧掉那些没人读的书。那如何决定保留什么?科学!就图像压缩而言,你首先要了解图像的哪些部分对人类感知是重要的,哪些不是。然后找到一种方法,保留重要特性,扔掉其余部分。在 JPEG 中,有损压缩基于两条心理视觉原理: 伪装中的豹子一头豹子走在南非一辆车附近,身上带有部分伪装。图片来源:Lee R. Berger (https://en.wikipedia.org/wiki/Leopard#/media/File:Leopard_near_driver.jpg)。1. 亮度的变化比颜色的变化更重要:人类视网膜中大约有 1.2 亿个对亮度敏感的视杆细胞,但只有大约 600 万个对颜色敏感的视锥细胞。 2. 低频变化比高频变化更重要。人眼擅长判断低频光线变化,比如物体的边缘。对于高频光线变化,比如复杂图案或纹理中的精细细节,人眼就没那么准确了。伪装之所以有效,部分原因在于高频图案会干扰被伪装物体原本较低频的边缘。 JPEG 压缩依次运用了这两条原理。在每一步中,图像数据都会被变换,以便更容易访问所需的信息(亮度信息或频率信息)。然后,一些次要信息会被丢弃。最后一步,剩余信息会经过传统的无损压缩,将最终结果打包到尽可能小的空间中。在本文中,我们将使用真实图像,逐步探索整个编码(保存为 JPEG)和解码(从 JPEG 加载)过程。你可以调整编码设置,看看它如何影响结果。开始吧! ## 编码 首先选择一张要压缩的输入图像。 ### 输入图像 选择一张图像:- 塔 - 花 - 河马 - 低频 - 高频 - 选择你自己的图像 从给定列表中选择一张图像。有几张可以试验,但我建议你第一次使用时使用默认的“塔”图像。它很好地混合了低频和高频区域,并且文章有时会提及它。 你也可以通过选择*选择你自己的图像*,或者将图像文件*拖放到*此页面,来使用自己选择的图像。 ### 第一步:分离颜色信息 图像像素图像由像素组成。每个像素的颜色是红、绿、蓝光量的总和。 典型的计算机图像由网格状的小彩色方块组成,这些小方块称为*像素*。每个像素存储为三个数字,分别表示再现该像素颜色所需的红、绿、蓝光量。因此,它被称为*RGB*图像。在左侧插图的左侧,你可以看到所选图像的红、绿、蓝部分被拆分为三个独立的*通道*。 就 JPEG 而言,问题在于图像的亮度信息均匀分布在 R、G、B 三个通道中。记住亮度比颜色更重要,因此我们需要从颜色信息中*分离出*亮度,以便单独处理它。为此,JPEG 通过一些数学运算将图像的*色彩空间*从 RGB 转换为 YCbCr。YCbCr 图像也有三个通道,但它将所有亮度信息存储在一个通道(Y)中,同时将颜色信息分散在另外两个通道(Cb 和 Cr)中。 左侧插图的右侧显示了同一张图像被拆分为 Y(上)、Cb(中)、Cr(下)通道的样子。注意 Cb 和 Cr 通道看起来“灰蒙蒙的”,因为所有由亮度信息带来的清晰度都已移到 Y 通道中。 > 为了保持插图的合理尺寸,我将所有通道缩小了。实际上,每个通道都与原始图像大小相同。 ### 第二步:丢弃部分颜色信息 在做其他事情之前,JPEG 会通过仅缩小 Cb 和 Cr(颜色)通道来丢弃一些颜色信息,同时保留重要的 Y(亮度)通道为全尺寸。严格来说,这一步是可选的。标准规定你可以保留全部颜色信息、一半或四分之一。对于图像,大多数应用程序会保留一半颜色信息;对于视频,通常是四分之一。在这个演示中,我保留四分之一,这既是为了夸大效果,也因为它能制作出更好的插图。 注意,我们从 3 个完整通道开始,现在我们有 1 个完整通道和 2 × 1⁄4 通道,总共 1½ 通道。我们才刚刚开始,就已经降到了初始信息量的一半! ### 第三步:转换到频域 为了利用关于人类视觉感知的第二条观察结果,我们首先将 Y、Cb 和 Cr 通道分别划分为 8×8 的像素块。我们将把这些块中的每一个从*空间域*变换到*频域*。 哇,慢着!什么?好吧,让我们只考虑 Y 通道中的 8×8 块之一。空间域就是我们现在所拥有的:左上角的值代表该块左上角像素的亮度(Y 值)。同样,右下角的值代表该块右下角像素的亮度。因此称为*空间*:块中的位置代表图像中的位置。当我们将这个块变换到频域时,块中的位置将转而代表图像该块中的一个频带。块左上角的值将代表最低频信息,而块右下角的值将代表最高频信息。 > 这种*域变换*是通过一种称为二维离散余弦变换 (https://en.wikipedia.org/wiki/Discrete_cosine_transform)(DCT)的数学技巧实现的。(如果你听说过傅里叶变换 (https://en.wikipedia.org/wiki/Discrete_Fourier_transform),DCT 与之类似,但它只使用实数;这对计算机表示更方便。)其基本思想是将 8×8 块中的值表示为余弦函数的和,其中每个余弦函数都有唯一特定的频率。 你不需要理解数学也能明白它的工作原理。看看“塔”图像的 Y 频率插图。你可以清楚地看到每个 8×8 块的左上角,因为那里有一个低频信息的暗点。如果你观察图像天空部分的块,你会发现每个块的其余部分大多是空的。天空在像素之间没有大量剧烈的变化:没有高频信息。再比较塔楼部分的块:砖块繁密的纹理意味着大量高频变化,这在整个块中表现为灰色。 ### 第四步:质量滑块(量化) 下一步是选择性地丢弃一些频率信息。如果你曾经保存过 JPEG 图像并选择过质量值,那么这个选择就在这里起作用。它是这样工作的:从两个 8×8 整数表开始,称为*量化*表。一个表用于亮度信息,一个用于颜色信息。你将在图像数据的每个 8×8 块上使用这些数字,即将图像数据中的频率值除以量化表中对应的数字。因此,Y 频率通道中每个 8×8 块的左上角将除以亮度量化表左上角的数字,依此类推。每次除法的结果四舍五入到最接近的整数,小数部分被丢弃。 量化后的 Y' 量化后的 Cb' / Cr' 输出 亮度表 色度表 你的选择对最终输出图像的影响会显示出来供参考。 量化表中某个数字越大,该频率范围对应的部分被丢弃的信息就越多。由于我们对高频信息的关注较少,量化表该区域的数字会较大。又由于我们对颜色的关注不如对亮度那么多,因此颜色表中的数字总体上会比亮度表中的数字大。 > 量化表会与图像数据一起保存在 JPEG 文件中。解码图像时需要用到它们。 你可以随意调整上面的质量滑块。注意,当你把质量拖向低端时,越来越多的频率信息会消失。 ### 第五步:无损数据压缩 如果仔细想想刚才发生的事情,你会意识到,尽管我们通过丢弃除法后的十进制部分而丢掉了一些频率信息,但我们仍然拥有相同*数量*的数据:三个通道中每个像素都有一个数字。看起来这一步实际上并没有带来什么好处。然而,这些数据现在将使用传统的*无损*压缩进行压缩。但等等,我们一开始使用有损压缩的原因,不就是因为无损压缩对图像效果不好吗?是的,但我们刚才做的量化将通过让数据*不那么嘈杂*来使其*更容易被压缩*。为了理解原因,比较以下三个数列: `` n = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, ... n/2 = 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 5, 6, 6, 7, 7, 8, 8, ... n/16 = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, ... `` JPEG 之字形顺序块数据按之字形顺序压缩,将相似频率分组在一起。第一行列出了例如 Y 频率通道中某个像素的值。第二行是同样的值除以 2 并四舍五入;第三行是除以 16 并四舍五入。你可以看到,除数越大,数据中的重复就越多。数据中的重复越多,就越容易压缩,最终图像文件也就越小。 JPEG 还有一个让数据更容易压缩的窍门:它按之字形模式列出每个 8×8 块的值,将数字按从最低频到最高频的顺序排列。这意味着被量化最严重的部分(除数最大的部分)会彼此相邻,形成由小数构成的漂亮、重复的模式。 ## 解码 到此为止,你已经了解了写入 JPEG 图像的基本要素:将图像从 RGB 转换为 YCbCr 以分离亮度,丢弃一些颜色,转换到频域,丢弃一些频率信息的精度,然后压缩所得数据。 那么当你读回图像时会发生什么?基本上,你只需要反转编码过程的每一步。让我们一步步来看。 ### 第六步:解压缩 量化后的 Y' 量化后的 Cb' / Cr' 第一步是解压缩量化(除以并四舍五入)后的频率数据。由于这些数据是无损压缩的,结果将与上面第五步中的完全相同。 ### 第七步:从量化数据重建 接下来,我们需要反转量化过程。我们使用与之前相同的过程,但不是除以表中的数字,而是相乘。由于我们对数字进行了四舍五入,我们不会得到完全相同的数字。结果是原始频率数据的不完美近似,精度受限于量化表允许的程度。质量越低,量化除数越大,丢失的精度就越多,我们现在重建的准确性也就越差。 ### 第八步:转换回空间域 现在我们已经重建了频率信息,需要将其从频域变换回空间域。这没有问题。编码时使用的变换有一个*逆变换*可以做这件事。 现在数据处于更可识别的形式

相似文章

通过穷举搜索实现无损GIF压缩

Hacker News Top

博客文章探讨了通过对LZW编码进行穷举搜索来实现GIF图像的无损重新压缩,类似于PNG的Zopfli方法,以达到更小的文件大小。

为什么 Chrome 中的微型 JPEG 看起来不同

Hacker News Top

本文解释了为什么与其他浏览器相比,Chrome 中的微型 JPEG 看起来会不同,原因在于一种 JPEG 解码优化,它会在重度缩小尺寸时跳过高频 DCT 系数。

ZK-JPEG: 零知识图像编辑与压缩

Hacker News Top

本文介绍ZK-JPEG,这是一个用于图像压缩和编辑的零知识加密工具,能在维护隐私的同时验证转换,有助于对抗深度伪造并确保图像来源。

反对 JPEG XL 的理由

Lobsters Hottest

本文批评了 JPEG XL 作为网络图像编解码器的表现,将其压缩效率与 AVIF 等替代方案进行了比较,并讨论了其在浏览器采用方面面临的挑战。