from PIL import Image, ImageCms
im = Image.open(src)
icc = ImageCms.ImageCmsProfile("sRGB.icc")
out = ImageCms.profileToProfile(im, im.info.get("icc_profile"), icc, outputMode="RGB")
out.save(dst, "JPEG", quality=86, icc_profile=icc.tobytes())
iPhone 拍的图上传后,商品红色变成暗红,绿色偏黄。原图 ICC 是 Display P3,服务器转出来的 JPEG 没有嵌入配置文件,浏览器按 sRGB 解释。色差用取色器量 ΔE 到 12。这类现象通常不是突然出现的,往前翻半天日志能看到苗头。
追下去是这么回事:转换时只改了像素没做色彩空间映射,P3 的色域比 sRGB 宽,直接当 sRGB 用会把饱和色压暗。保存时又没有写 ICC,浏览器只能猜。两个错误叠在一起,偏色更明显。
「色彩空间偏色」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。
把这次用到的命令存进笔记,比记住结论有用,换个环境还能照着走。
处理上按这个顺序:读取时按图片自带 ICC 转成 sRGB 再处理;保存时显式嵌入 sRGB 配置文件;统一输出格式 别让 P3 和 sRGB 混在一批;抽 10 张对比取色值 把 ΔE 控制在 3 以内。
确认没问题再收工,转出的图片嵌入 sRGB 配置,取色器量红色和设计稿 ΔE 小于 3,一批图里不再出现偏绿。
