跳转到内容

转换后偏色、ICC 丢失或 CMYK 失真

复制本页

偏色不一定发生在编码阶段。先沿着“输入色彩空间 → ICC 变换 → 像素操作 → 导出元数据”逐段检查,确认 Profile 在哪一步缺失或被错误解释。

  • 导出 WebP 后 ICC profile 丢失,色彩管理失效(即使 StripMetadata 设了 false)。
  • CMYK 源在 resize / 格式转换后颜色变化、偏灰或失真。
  • 一张原本没有 EXIF 的图,经过一次导出反而带上了 EXIF。
  • 带 alpha 的灰度/2-band 图做背景填充时报错或结果异常。

1. CMYK 需要先做 ICC 变换,不要直接 resize

Section titled “1. CMYK 需要先做 ICC 变换,不要直接 resize”

CMYK 不是“颜色”而是“油墨分量”,在 sRGB 目标下直接缩放会造成颜色漂移。应先做 ICC profile 变换到目标空间,再做缩放。

StripMetadata 默认是 false——即默认保留并可能处理元数据。这有两个影响:

  • 想在输出中彻底去掉 EXIF/IPTC 时,必须显式设为 true,否则残留。
  • 反向的坑:某些情况下会给原本干净的图“添加”元数据(#385)。所以如果你期望输出是“干净图”,请显式开启。

WebP 编码对 ICC 处理有特殊路径,在部分 govips/libvips 版本下即便 StripMetadata: false 也会丢弃 ICC。这是已知问题,你的代码并没有写错;规避方式是在导出前确认 profile 仍存在,或明确放弃对该版本 ICC 保留的依赖。

  1. 先读源图的 ICC/profile 与色彩空间,确认输入本身。
  2. 明确目标色彩空间与是否保留 profile。
  3. 在“加载 → 变换 → 导出”各阶段记录 profile 是否存在,定位在哪一步丢失。
  4. 对 CMYK 源先 TransformICCProfile 到 sRGB 再处理。
  • 仅取第一帧/颜色名称变化,但 profile 与色彩空间一致——这是符合预期的转换。
  • 期望输出不保留 EXIF,但没开 StripMetadata——这是用法问题,不是你代码以外的 bug。
  • 本页按 govips v2.19.0 与 libvips 8.17.3 复核;Profile 保留与编码器行为仍需按输出格式验证。

CMYK、ICC 与元数据默认值在 pyvips、sharp 和 CLI 中可能不同;本页不把 govips 的默认行为推广到其他 binding。