Both halves of that photograph are the same file. Same wedding, same frame, same edit. The only thing that differs is how the colour was handled when preparing it for the web — and the one on the right lost 20 % of its saturation to a one-line oversight.

If you have ever uploaded a photo and felt it looked better in Lightroom, it probably was not your screen or your imagination. It was this.

What happens, in one sentence

Your camera and your Lightroom are probably working in Adobe RGB, a wider colour space than sRGB — it can hold more greens and more cyans. The web, on the other hand, assumes sRGB unless it is told otherwise.

A pixel is just three numbers. Those numbers mean nothing on their own: they mean a colour within a space. If the photo was saved in Adobe RGB and that label is lost somewhere along the way, the browser reads the same numbers as if they were sRGB. And because sRGB is narrower, every number describes a less saturated colour than it should. The result: everything looks slightly washed out, reds and greens most of all.

Modern browsers do manage colour

Worth saying, because a lot of outdated advice is still going around. Chrome, Safari and Firefox do read the embedded profile and display an Adobe RGB image correctly if the profile travels with it.

The problem is not Adobe RGB. The problem is that the profile gets lost on the way extremely easily: image optimisers strip it, some content managers strip it, several social platforms strip it when they recompress, and so does any script that processes the photo without knowing what it is doing. Once it is gone, the file has no way of saying which space it is in.

That is why converting to sRGB before publishing is not superstition: it removes the file’s ability to be misread.

The line of code that took me a while to find

When I automated the image processing for this site, the first version did this:

imagen = imagen.convert('RGB')

It looks like a conversion. It is not. .convert('RGB') changes the file’s mode — CMYK to RGB, greyscale to RGB — but it does not touch the colour space. The numbers come out exactly as they went in, with no profile attached, so from that point on everyone reads them as sRGB.

It is a particularly treacherous bug because it does not fail. It throws nothing, it breaks nothing, and the file looks fine unless you have the original next to it. It just looks flat.

How much is lost, measured

I took one of my wedding photographs — a table setting, plenty of flowers, plenty of colour — and processed it both ways to measure the difference instead of assuming it. It is the image that opens this article.

Mean saturation drops from 66.7 to 53.1: 20.5 % less. The largest single-channel difference reaches 46 levels out of 255. It is not a brutal change, and that is exactly the danger: it does not look wrong, it looks flat. Nobody will complain. Your photographs will simply carry less force than they do on your screen.

What to do

If you export from Lightroom: choose sRGB as the export colour space for anything going to the web, and keep Adobe RGB or ProPhoto for anything going to print. It is one dropdown, and you only forget it once.

If you process with a script: do not use a bare .convert('RGB'). You need a profile-to-profile conversion that reads the original’s embedded profile and genuinely transforms it to sRGB. In Python, with Pillow, that is ImageCms.profileToProfile — and then you have to embed the sRGB profile in the output file.

And check the result rather than trusting it. Open the final file and look at what profile it declares. If it says “sRGB IEC61966-2.1”, you are fine. If it declares none, you have already started losing colour.

When you do want Adobe RGB

For print. A good lab or printer makes use of that wider space, especially in greens and cyans, and there you would notice the difference the other way round. So the advice is not “always use sRGB” but sRGB for screen, Adobe RGB for paper — and never let the file travel without saying which it is.