图片压缩后体积还是很大?压了2万张图后我发现方向搞反了

关键词:图片压缩,WebP转换,批量图片处理,ImageMagick压缩,图片体积优化

摘要:把2万多张图重新压了一遍之后的真实记录:为什么调质量滑块只能省12%,而砍尺寸能省90%。附照片/截图/图标/透明图四类素材的具体处理参数和命令行。

先说结论:你一直调的那个"质量80",只占最终体积的15%

图片

去年年底我整理自己的素材库,硬盘里躺着21437张图,加起来186GB。第一反应是"该压了",然后打开用了六七年的老工具,把质量从95拉到80,导出,一看体积——从4.1MB变成3.6MB。省了12%。

那一刻我是有点崩溃的。

后来我把这些图按像素总量重新算了一遍,才发现问题根本不在质量参数上。一张4000×3000的图,像素总量1200万;而我实际用到的展示尺寸是1200×900,108万像素。也就是说有91%的像素从来没被人看见过,但它们照样占着体积。

真正该砍的第一刀是尺寸。这一刀下去,体积直接掉到原来的8%左右。质量参数那一刀,是后面才该考虑的——顺序搞反了,你会觉得自己怎么调都调不动。

不同来源的图,处理逻辑完全不是一回事

我把素材按来源分成四类,参数完全不同,这块踩坑最多。

图片

第一类,相机和手机拍的照片。 色彩连续、噪点多,压缩算法发挥空间大。我的参数是:长边缩到1920,JPEG质量82,色度采样4:2:0,加-strip去掉EXIF。平均4.2MB降到280KB。单独说下EXIF,很多人不知道那玩意能占30到80KB,相机型号、GPS坐标、拍摄时间全在里面。我见过一张240KB的图,EXIF自己占了71KB,去掉之后什么都没变,就是小了三分之一。

第二类,手机截图和UI稿。 这类最容易被误伤。大片纯色加锐利文字边缘,JPEG一压,文字周围就冒彩色噪点,糊成一团。但你也不能无脑转WebP——我实测过200张App截图,转WebP无损后平均体积反而涨了18%,WebP无损模式对大面积纯色的压缩效率不如PNG。

截图我最后用的是PNG-8量化到128色。一张1080×2340的截图从1.8MB掉到190KB,肉眼基本看不出来。前提是图里没有渐变,有渐变的场景PNG-8会出现明显色带,这个只能一张张看。

第三类,图标和logo。 别存位图,直接SVG。我素材库里300多个logo,转成SVG之后总共400多KB。同样这批图如果存PNG是12MB。

第四类,带透明通道的商品图。 最麻烦的一类。PNG无损转WebP通常能省25%到35%,但如果你图边缘有半透明羽化,WebP的alpha通道处理和PNG有细微差异,某些电商平台的审核系统会判定"图片异常"。我踩过这个坑,一次传200张,47张被打回,当时没反应过来是格式的问题,还以为是网络。

具体怎么批量做,命令和参数

图片

照片批量处理,ImageMagick 7:

magick mogrify -path ./out -resize '1920x1920>' -quality 82 -sampling-factor 4:2:0 -strip ./photos/*.jpg

几个参数解释一下。-resize '1920x1920>' 里的 > 是指"只在原图超过这个尺寸时缩小",不会把小的放大。-strip去掉所有元数据。-sampling-factor 4:2:0是色度采样,人眼对亮度敏感、对色度不敏感,砍掉一半色度信息体积能掉一截,画质损失你基本看不出来。

对比很残酷:只加-quality 82不加缩放的,输出3.6MB;两个都加的,280KB。差了接近13倍。

截图处理:

pngquant --quality=65-85 --speed 1 --strip *.png

转WebP:

图片

cwebp -q 80 -m 6 -mt input.jpg -o output.webp

-m 6是压缩方法,范围0到6,6最慢但最小,默认是4,改成6大概能再小5%到8%。-mt开多线程。

Node项目里我更喜欢sharp:

sharp(input)
  .resize(1920, 1920, { fit: 'inside', withoutEnlargement: true })
  .jpeg({ quality: 82, mozjpeg: true, chromaSubsampling: '4:2:0' })
  .toFile(output)

mozjpeg: true这个参数挺关键,用的是Mozilla那套编码器,同等质量下比默认的再小10%到15%,代价是编码慢大概2倍。我压2万张图,开mozjpeg之后总耗时从11分钟涨到26分钟。这15分钟我觉得花得值,但如果你是那种按秒计费的场景,自己权衡。

格式对比,数据摆出来

图片

下面都是同一张1920×1280的风景照和一张1080×2340的App截图,我跑出来的平均值:

格式 适用场景 实测体积 编码速度 兼容性
JPEG q82 照片 280KB 快 100%
WebP q80 照片/网页 186KB 中 97%+
AVIF q60 照片/网页 141KB 慢 约88%
PNG-8 128色 截图/UI 190KB 中 100%
SVG 图标/logo 1-3KB 不适用 100%

AVIF用的是q60不是q80,因为它质量刻度和JPEG不一样,q60的AVIF大概相当于JPEG的q80。这个数字不要直接混用。

一个我到现在也没完全想明白的事

AVIF的体积画质比确实好。同画质下平均比WebP小20%到30%,我测的那张风景照,WebP是186KB,AVIF是141KB,SSIM还更高一点。数据上毫无争议。

但编码速度是个坑。同一张图,WebP编码0.3秒,AVIF要4.7秒。2万张图的话,这就是26小时的事,而且我只是跑一次,那些每天要处理用户上传的站点呢。

图片

iOS 16之前的Safari完全不支持AVIF,我后台数据里还有6.2%的用户在用旧设备。所以最后方案是用<picture>做渐进增强:AVIF优先,WebP兜底,JPEG保底。多存一份文件,CDN多花点钱,覆盖率100%。

说实话我到现在也没想清楚这个代价值不值。如果目标用户集中在安卓新机型,可能压根不用管JPEG保底。这个东西没有标准答案,得看你的实际用户构成。

最后

如果你只记一句话:先砍尺寸,再选格式,最后才调质量。

我见过太多人打开压缩工具第一件事就是拖那个质量滑块,包括三年前的我。那个滑块能给你的收益,通常不到整体优化空间的10%。大头在尺寸和格式上,而这两样是要分类讨论的,没有一键方案。

谁要跟你说有个按钮能一键搞定所有图片压缩,他要么没压过两万张图,要么就是想卖你东西。

标签: