Three color checkpoints for HEIC to JPEG, and why sips -g profile isn't one
Why do some HEIC-to-JPEG conversions come out washed out? The measurements I ran on 2026-11-06 pointed to three checks rather than to a library. Is there an ICC profile after decode, does the encoder carry it or convert the pixels, and what does your inspector actually read. The third is the easiest to get wrong. Scope first. Three HEIC files were encoded with macOS sips from a synthetic chart…
Three checks, not a library, cause washed-out HEIC-to-JPEG conversions. An ICC profile either needs to be read, carried by the encoder, or converted by the pixels, and this is often where things go wrong. Three HEIC files, encoded with macOS sips from synthetic and CC0 Wikimedia Commons photos, were tested. Both used Display P3 color space, but the source material was not iPhone originals, lacking HDR gain map, 10-bit, or nclx.
One Mac, single runs, Pillow 11.3, sharp 0.34.5, Chromium 149, and WebKit 26.5 were used. Color differences were measured using CIEDE2000 on patches, with a threshold below 1 being hard to detect and 2 to 3 visible side by side. The decoder determines the format; after decode, you either have P3 numbers with a profile, P3 numbers without a profile, or pixels already converted to sRGB.
Mixing these formats can cause washed-out results. Browser canvases convert at decode time, and Chromium 149 couldn't decode HEIC, converting to sRGB instead. sharp 0.34.5 read the metadata correctly but failed on the pixels due to a lack of a built-in decoding support for HEIC. The encoder either carries the profile or converts the pixels, and Pillow's plain save() writes the JPEG without the ICC, leaving the numbers unchanged.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.