Replace a colour

Every pixel is remapped locally — this page has no server to send to.

The dropper is already armed. Sample the colour you want gone, set what it becomes, and narrow the band until the coverage figure holds only what you meant.

198°
One frame, one selection. The paint moves 170 degrees around the hue wheel at the lightness it already had; the brick, the tarmac and the jacket are the same pixels either side of the line.
Drop an image here, or browse for oneJPG, PNG, WebP, GIF, BMP, TIFF and ICO decode here. HEIC pulls a codec the first time one arrives.

Nothing to hand?

One substitution, stated as two values

Colour substitution is the most literal thing anyone asks of an image editor, and it is usually answered with a brush. A brush is the wrong instrument: it constrains where you are painting and says nothing about what you are painting over, so the edge of a substituted region ends up being wherever your hand went rather than wherever the colour actually ended. What this route does instead is describe the thing being replaced — a value, and how far either side of it counts — and let the arithmetic find every pixel that matches.

That is why the first control is a dropper rather than a colour picker. The value you want is almost never the value you would have guessed; a red that looks like a single red on screen is typically several hundred distinct values across a photographed surface, and sampling one of them with the 3 by 3 average is a far better description than any hex value chosen from memory. The loupe shows the pixels under the pointer at nine times, with the sampled cell outlined, so what lands in the From field is a deliberate choice rather than an approximation of where the cursor was.

What each control writes into the operation record
ControlWritesRead back as
DropperFrom, as sRGB byteshex and OKLCH
Hex fieldeither colourhex and OKLCH
Hue bandTo, at its current lightnessdegrees
Three slidersthe tolerance tripledegrees and two decimals

Where a substitution goes wrong

There are three failure modes and the coverage figure identifies all of them. A reading near zero means the From value is not in the picture — usually a hex value typed from memory, occasionally a sample taken on a compression artefact rather than on the surface. A reading in the low single figures that misses part of the object means the tolerances are too tight, and lightness is almost always the one to widen first because it is what gathers a surface and its shadow. A reading in the tens of percent means something large has joined in, and chroma is the tolerance that excludes it, because chroma is the measurement that separates a coloured object from a grey background.

The fourth failure mode is not visible in the coverage figure at all: a substitution that selected exactly the right pixels and still looks wrong, because absolute replace was chosen for a photographed surface. Switch to hue shift and the texture comes back, since the texture was in the lightness channel the whole time and hue shift never touches it.

Asked and answered

How is this different from the front page?
Only in what is on screen. The arithmetic is identical and so is the export. This route arms the dropper the moment a picture opens and shows one operation with no list around it, because a single substitution does not need a stack, a reorder control or a second entry to manage. If you find yourself wanting a second colour changed, the front page is the same instrument with the list turned on.
The colour I want is not one flat value. It has highlights all over it.
That is the normal case and it is what the three tolerances are for. Sample somewhere in the middle of the region rather than on a highlight, then widen lightness until the coverage figure stops climbing sharply. Lightness is the tolerance that gathers a lit surface and its own shadow into one selection; hue and chroma are what keep everything else out. Sampling with the 5 by 5 average rather than a single pixel also helps on anything with grain or compression noise in it.
Can I type the colour instead of sampling it?
Yes, in either field. The hex box accepts three or six digits with or without the leading hash, and it updates the swatch as you type rather than on blur. A value you paste in as the From colour still has to exist in the picture for anything to be selected, which is why the coverage figure reading zero percent is the useful answer to a mistyped value rather than an error message.
What happens to a colour that appears in two different places?
Both are selected. The selection is a test on pixel values and nothing else — there is no notion of an object here, no segmentation and no region to constrain it. If the same red appears on a jacket and on a postbox behind it, one operation moves both. Narrowing lightness sometimes separates them when one is lit differently from the other; often it does not, and that is a genuine limit of a value-based selection rather than a setting you have not found.

Further in