图片压缩后变模糊、颜色发灰?我批量处理3174张商品图的踩坑记录(附参数)

关键词:批量图片压缩,图片加工教程,WebP转换,图片颜色发灰,EXIF方向

摘要:用iPhone拍的3174张商品图做批量加工,返工三遍才跑通。记录ICC色彩发灰、EXIF方向错乱、锐化顺序反了等真实踩坑,附Python与ImageMagick参数、JPEG/WebP量化对比表和工具横评。

图片压缩后变模糊、颜色发灰?我批量处理3174张商品图的踩坑记录

图片

先说结论我尽量少说,直接讲事。起因很简单:朋友开淘宝店,手机拍的图直接往上传,详情页在4G下打开要8秒多,他自己看后台数据说跳出率高得吓人。他让我帮忙批量处理一下,我想这不就是个resize吗,结果从晚上9点干到凌晨3点,前后返工三遍。下面是我真正踩到的坑,和最后跑通的参数。

一、先把“加工”拆开,不然你永远在返工

我统计了一下手头的素材:3174张,iPhone 13拍的HEIC,分辨率4032×3024,单张2.8~4.5MB,平均3.6MB。听起来是个体力活,但真正需要“创意加工”的——调色、去背景、换底色的——不到200张。剩下的全是四件枯燥的事:转格式、改尺寸、修色彩、清元数据。

很多人把权重搞反了。我自己实测下来,对最终观感的影响从大到小大概是:分辨率 > 压缩质量 > 锐化 > 调色。你把一张750px宽的图调得再通透,放到1440px的屏幕上照样糊;反过来,尺寸给够、质量给够,哪怕完全不动颜色,看起来也是“清楚”的。

所以第一步不是打开PS,是先问清楚这张图最终出现在哪:淘宝主图800×800还是1200×1200,详情页750px宽,微信朋友圈1080px长边,公众号封面900×383。目标尺寸定错了,后面全是白干。这一步花五分钟,能省你一晚上。

图片

二、颜色发灰:这个坑卡了我两小时

批处理第三遍跑完,我打开输出文件夹,人有点傻——所有图都像蒙了一层灰。红色衣服尤其明显,原图是正的朱红,输出后变成暗红发土,白衬衫变成了米白。

问题不在压缩,在ICC配置文件被剥掉了。iPhone拍的照片默认带Display P3的色彩配置,Pillow保存JPEG的时候如果不显式传icc_profile,这个配置就丢了,浏览器只好按sRGB去解释那堆像素值,颜色自然偏。

# 保色彩:把原图的ICC原样带过去
img.save(out_path, 'JPEG', quality=88, subsampling=0,
         icc_profile=img.info.get('icc_profile'))

# 或者干脆统一转成sRGB(多数电商平台要求这个)
from PIL import ImageCms
srgb = ImageCms.createProfile('sRGB')
img = ImageCms.profileToProfile(img, img.info.get('icc_profile'),
                                srgb, outputMode='RGB')

图片

ImageMagick那边对应的是 -profile /path/sRGB.icc,但注意 -strip 要放在 -profile 前面,顺序反了配置文件会被清掉——这个我真试过,出来的图还是灰的,查了半天才发现是顺序问题。

三、图歪了?EXIF方向和HEIC解码

第二个莫名其妙的bug:一部分竖着拍的照片,处理完全躺下了。原因是有个东西叫EXIF Orientation,手机拍照时传感器方向固定,靠EXIF里的一个标记告诉阅读器“请旋转90度”。你在系统相册里看是正的,但代码里读进来是没转过的原始像素。

from PIL import Image, ImageOps
img = ImageOps.exif_transpose(img)   # 必须放在resize之前

放前面和放后面差别很大:放后面等于你按错的方向缩了一遍再转正,长宽比都拧了,出来的图要么被裁要么模糊。

图片

HEIC解码要装 pillow-heif,新版直接 register_heif_opener() 就行,老版本API不一样,网上抄的代码经常对不上,建议看一眼自己装的是哪个版本再复制。

四、先缩后锐,顺序反了就是白干

这是我的核心观点,也是最容易被忽略的一条:锐化永远放在缩放之后。先锐化再缩小,等于把锐化出来的高反差边缘重新采样一遍,好处全被平均掉了,还多出一圈振铃。

缩放的滤波器也有讲究。默认的双线性(BILINEAR)缩图会偏软;LANCZOS更锐,但缩得太狠(超过3倍)时容易在边缘出现一圈白边;BICUBIC相对保险。我的做法是:能整数倍缩就先 img.reduce(2) 走一次,剩下的零头再用LANCZOS收尾。

图片

锐化的参数(8位通道下):radius 0.5~0.8,amount 60%~90%,threshold 2~4。缩得越狠,amount反而要给得小一点,不然噪点会被一起放大。这条我一开始也搞反了,设了150%,结果商品图的布纹全变成了雪花。

五、格式和参数:一张表说清楚

参数 我的取值 说明 / 代价
JPEG quality 88(图片带文字)/ 82(纯色块) 低于75开始出现块状伪影
色度抽样 4:4:4(subsampling=0) 比4:2:0大10%~20%,但红字不糊
目标宽度 主图1200px,详情页750px 别把4032px的成品传上去
WebP quality 80 同等观感下比JPEG小25%~35%
PNG有损 pngquant --quality=70-90 --speed 1 能减60%~70%体积
元数据 保留版权 + 必须清掉GPS 别把家里坐标一起传上去

实测数字:原图3.6MB → JPEG quality 88、4:4:4、1200px宽,平均210KB,缩到原来的5.8%。换WebP quality 80,平均138KB,肉眼看不出差别。注意WebP不是哪都能传,有些平台的上传接口还是只吃JPEG,别一股脑全转WebP。

六、工具横评:我最后留下了三个

图片

工具 批量 色彩管理 元数据 上手成本 我会拿它做什么
Photoshop 动作/批处理 中 强 强 高 少量需要精细抠图的
ImageMagick 强 强 强 中 服务器上跑批,配shell
Python + Pillow 强 中(要自己写) 中 中 逻辑复杂的,比如按文件名分目录
Squoosh(网页) 弱 弱 弱 极低 临时压一两张
sharp(Node) 极强 中 中 中 接在构建流程里自动跑

我的组合是:ImageMagick做第一道批处理(转格式、缩放),Python脚本处理那些需要按规则分目录、加白底的,最后人工只挑那200张精修。3174张图,全流程跑完大概12分钟,其中机器占了11分半。

七、最后送你一份可以直接抄的清单

  1. 先确定目标尺寸和投放到哪个平台,再动手。
  2. 转格式之前确认ICC要不要带、要不要转sRGB。
  3. exif_transpose 放在resize之前。
  4. 缩放 → 再锐化,绝不反过来。
  5. JPEG带文字用quality 88 + subsampling=0。
  6. 有透明通道才用PNG,否则一律JPEG或WebP。
  7. 批量前先拿5张试跑,肉眼对比之后再全量跑。
  8. 发布前清GPS定位,用 exiftool -gps:all= -overwrite_original。

有个反常识的点最后说一下:别迷信“原图”。你手机里的JPEG本身已经是有损编码过的产物,所谓无损压缩只是“不在这一次再损失”,不代表它干净。真正决定观感的,是你把它放到正确尺寸、正确色彩空间、正确压缩率上——这几件事做对了,图就赢了八成的加工。

标签: