Colour shifts, missing ICC profiles, and CMYK distortion
A colour shift does not necessarily begin in the encoder. Trace the pipeline through the input colourspace, ICC transform, pixel operations, and export metadata to find where the profile is lost or interpreted incorrectly.
Symptoms
Section titled “Symptoms”- Exporting WebP drops the ICC profile, breaking colour management (even with
StripMetadataset to false). - A CMYK source shifts, greys, or distorts after resize or format conversion.
- An image with no EXIF gains EXIF after an export pass.
- Background-filling a greyscale/2-band image with alpha reports an error or a wrong result.
Root causes and fixes
Section titled “Root causes and fixes”1. CMYK needs an ICC transform before resize, not after
Section titled “1. CMYK needs an ICC transform before resize, not after”CMYK represents ink separation, not “colour” directly. Resizing it into an sRGB target without a transform shifts colours. Run an ICC profile transform to the target colour space first, then resize.
2. Know the default of StripMetadata
Section titled “2. Know the default of StripMetadata”StripMetadata defaults to false — metadata is kept and may be processed by default. Two implications:
- To strip EXIF/IPTC from output you must set it to true explicitly, otherwise it lingers.
- The reverse trap: some runs add metadata to an otherwise clean image (#385). If you expect a “clean” output image, enable it explicitly.
3. WebP dropping ICC is a known edge case
Section titled “3. WebP dropping ICC is a known edge case”WebP encoding has a special ICC path; in some govips/libvips releases the profile is dropped even with StripMetadata: false. That is a known limitation, not a bug in your code. Work around it by confirming the profile is still present before export, or by not depending on ICC retention for that version.
Debug steps
Section titled “Debug steps”- Read the input image’s ICC/profile and colour space first, to know what you start with.
- Decide the target colour space and whether to keep the profile.
- Record at each stage (load → transform → export) whether the profile survives, to locate where it is lost.
- For CMYK input, run
TransformICCProfileto sRGB before further processing.
Affected versions and scope
Section titled “Affected versions and scope”- Only the first-frame/colour name changes while the profile and colour space stay consistent — that is an expected conversion.
- You expect output without EXIF but did not enable
StripMetadata— a usage issue, not a bug outside your code. - This page was checked against govips v2.19.0 and libvips 8.17.3. Profile retention and encoder behaviour must still be verified per output format.
Sources
Section titled “Sources”- govips #552 — WebP export drops ICC
- govips #275 / #497 — CMYK resize shifts colour, ICC ignored
- govips #385 — image without EXIF gains EXIF after export
- govips #310 — RemoveMetadata does not remove EXIF
- govips #534 — 2-band PNG background fill error
- govips v2.19.0 README
CMYK, ICC, and metadata defaults can differ in pyvips, sharp, and the CLI. This page does not project govips defaults onto those bindings.