Does HEIC to JPG shift the colours?

Yes, if the photo is Display P3. The numbers are copied through untouched and then labelled sRGB — so the warm tones come out flatter than the original. Here is the measurement.

Profile never read Up to ΔE 13.5 Measured today

Short answer: the converter does not read the colour profile embedded in the HEIC. I made two 500 × 500 test images with exactly the same pixel values, tagged one Display P3 and one sRGB, and converted both. The two output files were byte-for-byte identical — same 4,834 bytes, same SHA-256 hash. The P3 numbers arrive in the JPG unchanged, but the JPG declares itself sRGB, so a viewer interprets those numbers as the narrower space and the saturated tones render duller than they were.

How I know: I generated a Display P3 ICC profile locally, wrote it into a HEIC, converted the file at two quality settings, pulled the resulting JPG back out of the browser and read its pixels and its ICC segment. Every number below came out of that run.

The test files

One 500 × 500 image, five vertical bands of solid colour, 8-bit, saved as HEIC. Two copies with identical pixel values:

FileEmbedded profileSize on disk
p3-swatches.heicDisplay P3, 2,040 bytes12,225 bytes
srgb-swatches.heicsRGB, 588 bytes10,773 bytes

The P3 profile is one I generated myself. I checked it before using it: feeding it sRGB pure red (255,0,0) returns (234,51,35), which is the correct Display P3 value for that colour, so the profile is behaving like a real P3 profile and not like a broken one.

The five bands, read back out of the saved HEIC before conversion: an orange (230,130,70), a sky blue (110,170,220), a grass green (110,160,89), a skin tone (220,171,141) and a neutral grey (128,128,128). The grey is the control — a neutral should look the same in both colour spaces.

What came out

BandValue in the HEICWhat sRGB should have beenWhat the JPG containsΔE76
Orange230, 130, 70246, 123, 52230, 130, 7013.5
Sky blue110, 170, 22089, 172, 225110, 170, 2205.0
Grass green110, 160, 8994, 162, 81110, 160, 898.1
Skin tone220, 171, 141229, 167, 135220, 171, 1415.8
Neutral grey128, 128, 128128, 128, 128128, 128, 1280.0

Every saturated patch landed on the wrong colours. The neutral grey landed exactly right, which is what you would expect: greys sit on the axis both colour spaces share, so ignoring the profile costs them nothing.

The ΔE76 column is the distance in Lab between the colour the photo actually contained (the P3 numbers read as P3) and the colour the JPG will show (the same numbers read as sRGB). A value around 5 is visible side by side; 13.5 on the orange is obvious.

Conversion took 0.7 s to 1.8 s per file. At the lower quality setting the P3 file produced a 4,007-byte JPG with the same patches (±2 on one channel), so the shift has nothing to do with quality — it is the same at both settings.

The proof that the profile is never read

Two different inputs, two different colour profiles, two different source files — and the converter produced one file twice. The P3-tagged HEIC and the sRGB-tagged HEIC both came out as a 4,834-byte JPG with the SHA-256 hash starting a8af458e. Not similar. Identical, byte for byte.

That can only happen if the profile is discarded before the pixels are written. And the output file then states what it is: its APP2 segment is 472 bytes, of which 458 bytes are an ICC profile whose description reads sRGB. So the P3 numbers get a new label claiming they are sRGB. Every viewer downstream believes the label.

The 10-bit half of the question

HEIC can store ten bits per channel; JPG cannot. I made a 1,024 × 64 gradient that uses all 1,024 levels a 10-bit file can hold, confirmed the file reports bit_depth = 10, and converted it. The output JPG's middle scanline holds 256 distinct values, not 1,024 — exactly four source levels collapse into each output level. The gradient still looks smooth here because it is a synthetic ramp; in a real sky or a sunset, that is where banding comes from, and no setting on this converter can prevent it, because JPG has eight bits per channel to work with.

What I did not measure

How to check this on any converter

  1. Find a photo you know is P3 — a recent phone photo of something saturated, a sunset or bright foliage.
  2. Convert it, then open the JPG in any tool that reports colour space. If it says sRGB and the file was P3, the profile was dropped.
  3. Compare the two side by side on the same screen. If the converted copy is flatter in the reds and oranges, you are seeing exactly what I measured.

Thirty seconds of work, and it settles the question for whatever tool you actually use.

Questions

Does converting HEIC to JPG change the colours?

On this converter, for a Display P3 source, yes. The numbers survive untouched but the file is relabelled sRGB, so saturated colours render differently — up to ΔE 13.5 on the most saturated patch I measured. Neutral greys were unchanged.

Why does it happen?

Because the embedded profile is not read. I proved it by converting two files with identical pixels and different profiles: the outputs were byte-for-byte identical, 4,834 bytes each with the same hash, and both carried a 458-byte sRGB profile.

Will the photo look washed out?

Not washed out — slightly less saturated in the strong colours. On my orange patch the difference is 16 levels of red and 18 levels of blue. You would notice it in a sunset, much less in a portrait or a document scan.

Can I avoid it?

Not with a JPG output, because the JPG format has no way to say "these numbers are P3" here — the converter writes an sRGB tag. Keep the original HEIC if the exact colour matters; the conversion does not modify it.

Does 10-bit depth survive?

No. My 10-bit gradient held 1,024 distinct levels going in; the JPG that came out held 256. JPG stores eight bits per channel.

Is this the same on every converter?

I did not test other converters and will not speak for them. This is a measurement of this one, run today.

Try it yourself: convert a HEIC with strong colour in it, then compare the JPG against the original on the same screen.

First published: 23 September 2026