图片压缩到100KB以内怎么弄?我把2000张图跑了一遍,真正有用的就那几步

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

摘要:拿2000张真实照片做的图片压缩实测:为什么拉质量滑块几乎没用,尺寸、色度采样、格式选择各自能省多少,附可直接抄的ImageMagick和cwebp命令、踩过的坑,以及前端和对象存储侧的二次优化。

一张4MB的图,到底在哪一步掉下来的

图片

上周帮做女装店的朋友收拾详情页,17张主图,iPhone 15直出4032×3024,平均4.1MB一张,手机上打开要9秒多。他在Squoosh里把quality从90拉到75,文件从4.1MB掉到3.2MB,然后跟我说压缩这东西没用。

我猜不少人卡在同一个地方:以为体积是质量参数决定的。今年三月我把手头2000张图(2019到2024的手机照片,混了300来张电商白底图)批量跑了一遍,记了下数字:还是4032×3024这个尺寸,JPEG质量从95压到60,体积掉55%~65%,画面已经开始起块了;但先把长边缩到1600,同样质量85,体积直接掉到原来一成左右,那种白底导购图甚至能到1/14。

两个动作叠起来,才是从4.1MB到220KB的真实路径。所以我的看法有点反直觉:图片压缩的收益九成来自尺寸和色度采样,质量滑块只负责最后那一成微调。大家习惯先去拉滑块,因为那玩意儿最直观,但它恰恰是效率最低的一个旋钮。

能直接抄的三条命令

图片

Windows下先装ImageMagick(我用7.x,命令是magick不是convert,别踩这个坑)。批量缩图我常年用这条:

magick mogrify -path ./out -resize "1600x1600>" -strip -sampling-factor 4:2:0 -quality 82 -interlace JPEG *.jpg

-resize "1600x1600>" 里的 > 意思是只缩不放,小图不会被拉大,这个符号漏了图就糊。引号必须留着,不然PowerShell会把 > 当重定向符号,命令直接不执行——我第一次跑了半小时发现out目录是空的,就栽在这。-strip 会删掉EXIF和ICC,体积再省3~15KB(我那批iPhone图平均11KB),代价是拍摄参数和版权信息全没了,商用图先备份。-sampling-factor 4:2:0 是关键,亮度保留全分辨率,色度水平和垂直各砍一半,人眼对这块本来就不敏感。

转WebP我用cwebp,同一条流水线上的第二站:

图片

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

-m 6 是压缩算法档位(0到6),慢但小,-mt 走多线程。同一批图,JPEG q82 发出去的量,WebP q80 普遍再小25%~35%,肉眼基本找不出差别。

格式的账得算清楚,别一刀切

PNG只在该用的地方用:要透明通道,或者图里是大面积纯色(截图、logo、线稿)。照片存PNG是纯浪费,一张长边1600的PNG照片能到3MB,同尺寸JPEG q85只要180KB。我的分法是照片走JPEG或WebP,带透明的手写体logo和图标走PNG或SVG,动图看情况。

图片

WebP有损有个坑我吃过:那种从深蓝渐变到黑的背景图,q75会出色带,一圈一圈的,得抬到q90以上,或者加一点-sharpness,代价是体积翻倍。AVIF更狠,同画质能比WebP再小两成,但编码慢一个数量级,2000张我跑了一夜还没完,做实时上传处理不现实。

还有一类图很特殊:夜市、演唱会那种高ISO的,满屏噪点。噪点在JPEG里算高频信息,特别吃码率,同样参数出来体积是正常图的2到3倍。这类先过一遍降噪(darktable的profiled denoise,或者ImageMagick的 -statistic Median 3x3 都能用),再压缩,体积能再掉三成,而且看着更干净。

那几个看不见的坑

图片

EXIF里的Orientation值决定图要不要转90度,手机拍的图十有八九带这个标记。浏览器现在都自动处理,但你要是用canvas重绘或者某些后端库重新编码,方向信息一丢,用户传的竖图就躺平了,这种事我碰上过不止一次。

其次是色彩。iPhone拍的是Display P3色域,直接转sRGB会偏色,红花发闷,蓝天发灰。批量转的时候得用ICC做色彩管理,ImageMagick加 -profile sRGB.icc,别用 -colorspace sRGB,那是不带映射的硬转,出来更难看。

第三个是DPI。网页里72和300对渲染毫无影响,浏览器只认像素数。有客户坚持让我把图调成300dpi「更清晰」,解释了三回,最后我干脆把DPI数字改了,文件大小没变,他满意了,图该糊还是糊。

前端和存储这边其实还能再省一半

图片

光压图不够。同一个文件,用 <img srcset sizes loading="lazy" decoding="async" width height> 发出去,手机端只下需要的尺寸,首屏只加载进视口的。width和height一定要写死在标签上,比例不对就写aspect-ratio,这是防CLS最省事的办法,比上JS监听省心得多。

用对象存储的话,很多活儿根本不用自己写脚本。阿里云OSS在URL后面挂 ?x-oss-process=image/resize,w_800/quality,q_80/format,webp ,腾讯云数据万象是 imageMogr2/thumbnail/800x/format/webp ,源图传上去,缩略图按需生成,改尺寸不用重跑一遍。

如果只记一件事

按收益排序:先把尺寸降到实际显示宽度的1.5到2倍,再看要不要转WebP,然后调色度采样,最后才是质量参数。我朋友的17张图按这个顺序过了一遍,总量从70MB到3.4MB,页面加载从9秒多到1.2秒。他觉得神奇,我觉得只是顺序对了。

标签: