4、JPEG压缩策略:量化表、色度子采样、渐进式JPEG,工具推荐
JPEG 压缩,说白了就是一场「人眼感知的骗局」。它利用我们眼睛对颜色不敏感、对高频细节不敏感的特点,把那些「看了也白看」的信息扔掉。我做了这么多年界面移植,跟 JPEG 打交道最多。嗯,今天咱们就把它聊透。
核心思路:JPEG 压缩不是简单的「删数据」,而是通过三个步骤——色度子采样、离散余弦变换(DCT)、量化——把图像从「像素空间」转换到「频率空间」,再根据人眼敏感度选择性丢弃信息。
4.1 量化表:压缩的「心脏」
量化是 JPEG 里唯一真正丢失信息的步骤。DCT 变换本身不丢数据,但量化表一上来,就开始「四舍五入」了。
我刚开始做移动端优化时,总觉得量化表是 JPEG 标准里写死的,不能动。后来踩了坑才发现——量化表是可以自定义的,而且它对压缩质量和文件大小的影响,比任何参数都大。
4.1.1 标准量化表长什么样?
JPEG 标准里给了两张「参考量化表」:一张给亮度(Y),一张给色度(Cb/Cr)。数值越大,压缩越狠。
| 亮度量化表(Y) | 色度量化表(Cb/Cr) |
|---|---|
|
|
你看,色度量化表右下角全是 99。这意味着高频色度信息几乎被全部丢弃。为什么?因为人眼对颜色变化不敏感,你根本看不出区别。
4.1.2 量化表怎么影响质量?
量化表里的每个数字,都会去除以对应的 DCT 系数,然后取整。数字越大,取整后丢失的信息越多。
- 低质量(Q=10):量化表数值整体放大 2~3 倍,文件很小,但块效应明显
- 中等质量(Q=50):接近标准表,平衡点
- 高质量(Q=90):量化表数值缩小,保留更多高频细节
- 无损(Q=100):量化表全为 1,不丢数据,但文件巨大
我的经验:界面截图做 JPEG 压缩时,Q=75~85 是最佳区间。低于 70,文字边缘开始模糊;高于 90,文件大小翻倍但肉眼几乎看不出提升。
4.2 色度子采样:扔掉一半颜色
人眼对亮度的敏感度远高于色度。JPEG 利用这一点,把色度信息的分辨率砍掉一半甚至更多。
4.2.1 常见的采样格式
| 格式 | 含义 | 压缩比 | 适用场景 |
|---|---|---|---|
| 4:4:4 | 不采样,每个像素保留完整色度 | 最低 | 高质量摄影、文字截图 |
| 4:2:2 | 水平方向色度减半 | 中等 | 视频帧、一般照片 |
| 4:2:0 | 水平和垂直方向色度都减半 | 最高 | 网络图片、移动端界面 |
4:2:0 是最常用的格式。它把色度信息压缩到原来的 1/4,但人眼几乎察觉不到。我在做 H5 页面优化时,所有 JPEG 背景图都强制用 4:2:0,文件能再小 30%~40%。
注意:如果图片里包含细小的彩色文字或 UI 图标,4:2:0 会导致颜色边缘出现「渗色」现象。这时候建议用 4:4:4 或直接转 PNG。
4.3 渐进式 JPEG:先模糊后清晰
普通 JPEG 是「逐行扫描」的——从上往下加载。渐进式 JPEG 则先加载一个模糊的完整图像,再逐步变清晰。
我记得有一次做移动端首屏优化,首屏图片有 200KB,用户打开页面要等 3 秒才能看到内容。换成渐进式 JPEG 后,用户 0.5 秒就能看到模糊轮廓,体验提升了一大截。
4.3.1 渐进式的原理
渐进式 JPEG 把图像数据分成多个「扫描(scan)」。第一个扫描只包含低频信息(DC 系数和少量 AC 系数),后面的扫描逐步补充高频细节。
- 优点:用户能更快感知到图像内容,适合网络加载
- 缺点:解码需要更多内存,文件通常比普通 JPEG 大 5%~10%
- 适用场景:大图、首屏图片、慢速网络
避坑指南:我曾经在某个项目中把所有 JPEG 都转成渐进式,结果发现小图标(< 10KB)的渐进式反而加载更慢。因为小图不需要渐进,额外开销反而拖了后腿。记住:渐进式 JPEG 只适合 50KB 以上的图片。
4.4 工具推荐:jpegtran 与 mozjpeg
市面上 JPEG 压缩工具很多,但真正能「无损优化」和「有损优化到极致」的,我推荐这两个。
4.4.1 jpegtran:无损压缩利器
jpegtran 是 libjpeg 自带的命令行工具。它不做任何有损操作,只优化 Huffman 编码和 DCT 系数排列,能无损减少 5%~15% 的文件大小。
# 基本用法:无损优化 JPEG
jpegtran -optimize -copy none input.jpg > output.jpg
# 转为渐进式 JPEG
jpegtran -progressive -optimize -copy none input.jpg > output.jpg
# 裁剪并优化
jpegtran -crop 800x600+0+0 -optimize input.jpg > output.jpg
-copy none 会丢弃 EXIF 等元数据,能再省一点空间。如果不需要保留拍摄信息,建议加上。
4.4.2 mozjpeg:有损压缩的天花板
Mozilla 开发的 mozjpeg,在 libjpeg-turbo 基础上改进了量化表和熵编码。同样的视觉质量,mozjpeg 能比普通 libjpeg 再小 20%~30%。
# 安装(macOS)
brew install mozjpeg
# 基本压缩
cjpeg -quality 75 -optimize input.png > output.jpg
# 使用 mozjpeg 的「trellis 量化」
cjpeg -quality 75 -quant-table 3 -trellis -optimize input.png > output.jpg
-trellis 参数是 mozjpeg 的核心。它会在量化时做全局优化,找到「视觉损失最小、文件最小」的平衡点。代价是编码速度慢 2~3 倍,但压缩效果确实好。
| 工具 | 压缩类型 | 压缩率 | 速度 | 推荐场景 |
|---|---|---|---|---|
| jpegtran | 无损 | 5%~15% | 极快 | 已有 JPEG 的二次优化 |
| mozjpeg | 有损 | 20%~50% | 较慢 | 从源文件生成高质量 JPEG |
| libjpeg-turbo | 有损/无损 | 10%~30% | 快 | 通用场景 |
我的工作流:设计稿导出 PNG → mozjpeg 压缩(Q=80, trellis)→ jpegtran 无损优化 → 上线。两步下来,文件能比直接导出 JPEG 小 40% 以上。
4.5 本章知识体系
下面这张图,帮你把 JPEG 压缩的核心链路串起来。
从原始图像到最终 JPEG 文件,经历了色度子采样、DCT 变换、量化、熵编码四个步骤。其中量化是「丢信息」的关键,色度子采样是「砍颜色」的关键,而渐进式 JPEG 和工具选择,则是在编码阶段做优化。
嗯,JPEG 压缩这块,说白了就是「用最小的文件,骗过最多的眼睛」。掌握了量化表和色度子采样,你就能在界面移植中做到「肉眼无损、文件减半」。下次遇到 JPEG 压缩需求,别只调一个 quality 参数了——试试自定义量化表,或者用 mozjpeg 的 trellis 量化,效果会让你惊喜。