JPEG 是如何工作的:交互式探索 JPEG 的有损压缩方法
摘要
一篇交互式文章,解释 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'
第一步是解压缩量化(除以并四舍五入)后的频率数据。由于这些数据是无损压缩的,结果将与上面第五步中的完全相同。
### 第七步:从量化数据重建
接下来,我们需要反转量化过程。我们使用与之前相同的过程,但不是除以表中的数字,而是相乘。由于我们对数字进行了四舍五入,我们不会得到完全相同的数字。结果是原始频率数据的不完美近似,精度受限于量化表允许的程度。质量越低,量化除数越大,丢失的精度就越多,我们现在重建的准确性也就越差。
### 第八步:转换回空间域
现在我们已经重建了频率信息,需要将其从频域变换回空间域。这没有问题。编码时使用的变换有一个*逆变换*可以做这件事。
现在数据处于更可识别的形式
相似文章
JPEG XL 发展之路:开源实验塑造了图像编码的未来
谷歌工程师回顾 JPEG XL 背后长达十年的开源历程,重点介绍了 WebP Lossless、Butteraugli 和 Guetzli 等关键实验如何塑造了下一代图像标准。
通过穷举搜索实现无损GIF压缩
博客文章探讨了通过对LZW编码进行穷举搜索来实现GIF图像的无损重新压缩,类似于PNG的Zopfli方法,以达到更小的文件大小。
为什么 Chrome 中的微型 JPEG 看起来不同
本文解释了为什么与其他浏览器相比,Chrome 中的微型 JPEG 看起来会不同,原因在于一种 JPEG 解码优化,它会在重度缩小尺寸时跳过高频 DCT 系数。
ZK-JPEG: 零知识图像编辑与压缩
本文介绍ZK-JPEG,这是一个用于图像压缩和编辑的零知识加密工具,能在维护隐私的同时验证转换,有助于对抗深度伪造并确保图像来源。
反对 JPEG XL 的理由
本文批评了 JPEG XL 作为网络图像编解码器的表现,将其压缩效率与 AVIF 等替代方案进行了比较,并讨论了其在浏览器采用方面面临的挑战。