为什么压缩之后图片反而变大了?
这比多数人以为的更常见,而且不是工具的 bug。这里说清真正的原因,以及一个合格的工具该怎么做。
你压了一张照片,结果文件比原来还大。这看起来像工具坏了。其实不是,而搞懂原因能让你判断该信哪个工具。
原因一:这个文件已经被压过了
JPEG 的质量设置不是绝对的。同一个"质量 70",不同应用存出来的文件和观感可能完全不同。所以当你把一张已经以低质量压过的图,用更高质量重新编码时,你是在要求编码器还原已经不存在的细节。
它做不到。它能做的是花比特去描述上一轮的压缩痕迹——把块状边缘和振铃当成真实的图像内容仔细编码。文件变大,而观感没有变好。
这是最常见的原因,也是为什么"把小文件的质量滑块往高调"通常只会更糟。
原因二:色度抽样被降级了
JPEG 用比亮度更低的分辨率存颜色。一个文件可能带全色度(4:4:4)、半色度(4:2:2)或四分之一(4:2:0)。如果你的源是 4:4:4 而编码器决定写 4:2:0,那应该让文件更小——所以这通常不是变大的原因。
反过来更值得注意:如果一个工具既不肯保留你的色度抽样、又额外花比特去做补偿,你可能会得到一个更大、却没有任何真实收益的文件。
原因三:原文件被优化过,新文件没有
一个 JPEG 里不只是像素。两个编码器可以产出观感相同、体积差很多的文件,差别在于:
- 霍夫曼表优化 —— 通常能省几个百分点
- progressive 还是 baseline —— progressive 通常省 2%–8%
- 元数据 —— EXIF、ICC 配置、内嵌缩略图可能占几十 KB
一个优化良好的 q85 文件,很容易比一个草率编码的 q80 文件更小。
一个合格的工具该怎么做
诚实的行为很简单:如果重编会得到更大的文件,就保留原文件并告诉你。
这正是本工具的做法。在写任何东西之前,它会把结果与你的输入比较。如果结果没有更小,你拿回的就是未经改动的原文件,并附一句说明。你不应该得到一个又更差又更大的文件。
特例:已经被压过的文件
对已经压过的文件,用相近质量重编几乎毫无收获。但有一件事是真有用的,而且零画质损失:只重写容器。
元数据段和熵编码与压缩后的图像数据在文件里是分开存放的,可以在不碰任何一个像素的前提下重写:
- 剥离元数据(EXIF、GPS、ICC)—— 纯粹减小体积,图像数据逐位不变
- 用优化的霍夫曼表与 progressive 扫描重写熵编码层 —— 像素同样逐位不变
在典型的相机风格 JPEG 上实测,这个组合能省约 4%,而解码后的像素完全相同。不多,但是真实的,而且免费。
一条实用规则
如果你手上还有原始导出文件,就回到它,从那里只压一次。对已压过的文件反复压缩,是唯一一种稳定地把事情弄糟的工作流——文件更大、痕迹更多,而且无法撤销。