把一张 4MB 的手机照片压到 300KB,绝大多数人看不出差别;但把同一张图反复保存五次,即使每次都设成「最高质量」,边缘也会糊掉。原因在于:压缩质量是一次性的取舍,重复编码是累积的损耗。

质量参数到底在控制什么

JPEG 编码会把图像切成 8×8 的块做离散余弦变换,量化表决定了丢弃多少高频细节。质量参数本质上是量化表的缩放系数:

  • 90 以上:几乎看不出差别,但体积下降很有限,通常只有原图的 60%–70%。
  • 80–85:网页配图的甜点区。体积能降到 20%–30%,高对比边缘略有可见的轻微软化。
  • 60–75:缩略图、列表封面可用。放大到 100% 时能看到块状色斑。
  • 50 以下:文字截图会糊成一团,绝不要用在带小字的图上。

三个容易被忽略的变量

色度采样。默认的 4:2:0 会丢弃四分之三的色彩信息,肉眼对亮度敏感、对色彩不敏感,所以通常几乎无损;但大面积纯色边缘(比如红色logo压在白底上)会出现色彩渗出,这时改 4:4:4 更稳。

代际损失。每次解码再编码都会重新量化。做批量处理时只压一次原图,不要对着已经压过的文件再压第二轮。要多次调整参数,请始终回到原图。

元数据。手机照片里通常塞了几百 KB 的 EXIF、缩略图、GPS 信息。用 canvas 重编码会自动丢掉这些,所以「体积下降得比预期多」往往不是因为压缩,而是元数据被剥离了。

怎么判断有没有压过头

把图放大到 200%,只看两个地方:一是高对比的边缘(比如黑色文字、树枝、发丝),二是渐变区域(天空、皮肤)。前者出现锯齿状色块,说明质量过低;后者出现一圈圈的色带(banding),说明量化过狠或者位深不足。

如果只是网页展示,还有个更实用的标准:在目标显示尺寸下(不是 100% 原图尺寸)对比,看不出区别就够了。一张 4000px 的照片放进 800px 宽的容器里,压到 75% 也看不出问题。

结论:网页图片从质量 80 起调,配合 WebP 输出通常能省一半以上体积;需要保留小字和线条的截图,优先用 PNG 或质量 90 以上的 WebP,而不是 JPG。

一条可执行的处理链路

  1. 先按最终显示尺寸的 1.5–2 倍缩放(保留高密度屏余量),不要直接压原图。
  2. 照片类输出 WebP,质量 80;需要兼容老环境再补一张 JPG,质量 85。
  3. 截图、图表、带透明通道的素材,输出 PNG 或 WebP 无损模式。
  4. 只压一次,保留原图归档。

这条链路可以直接用本地的图片压缩和尺寸调整工具跑完,文件不会离开你的浏览器。