Does a transparent PNG know what colour is behind it?
No. A transparent PNG stores three colour numbers and one coverage number per pixel, and the viewer works out the rest: result = alpha x colour + (1 - alpha) x whatever you put behind it. On a hair strand that really covers 40 per cent of a pixel, our keyer writes RGB (26,102,51) at alpha 20 out of 255 — so 92 per cent of that pixel's final colour comes from a background the file has never seen. Drop it on black and the pixel lands at (2,8,4); on mid grey (120,126,122); on white (237,243,239). That is a 407-code-level spread from one file that never changed.
What the file actually carries
Every pixel of a transparent PNG is four numbers: red, green, blue, and alpha. Alpha is not a colour and it is not a background; it is a fraction. It says how much of this pixel belongs to the subject. Everything that opens the file afterwards runs the same sum — take the stored colour, multiply it by alpha, take the thing behind, multiply it by one minus alpha, add them. The background term is supplied at display time. It is not in the file and it never was.
The format has no field for "what should appear here". WebP carries the same four channels. JPEG and flat PNG carry no alpha at all, which is the one case where the file genuinely knows, because there is nothing left to decide.
What the keyer leaves in those four numbers
The interesting part is not the format, it is what a chroma keyer puts into it. Ours writes exactly one channel: alpha. The red, green and blue of a pixel are left as they arrived, with the green channel pulled down afterwards by the spill controls. That is worth seeing in numbers. Take a dark hair strand, (48,42,38), sitting over a lit #00B140 screen, and let the strand cover 40 per cent of the pixel.
The camera sees a mixture, not a switch: integrating in linear light and encoding back to 8-bit gives (28,143,55). That pixel is more screen than hair, and it is unmistakably green. Spill suppression and despill bring the green channel down to 106, which is still two and a half times the hair's own green. The keyer then measures the distance to the key colour and writes alpha 20 out of 255 — it has decided the pixel is 92 per cent background.
So the file ends up holding RGB (26,102,51) at alpha 20/255. The hair is (48,42,38). The stored colour is 60 levels too green in the green channel, and the coverage it claims — 0.08 — is a fifth of what the strand really covers. Both numbers are wrong, and neither one matters until something goes behind them.
One file, three answers
Composited on black, that pixel becomes (2,8,4). On mid grey it becomes (120,126,122). On white it becomes (237,243,239). The correct answers for a 40-per-cent hair strand are (19,17,15), (96,94,92) and (172,170,168). The distance from correct is 22 code levels on black, 50 on mid grey and 121 on white.
Two things follow. The spread: 407 code levels between the black result and the white result, from one file that did not change by a single bit. And the direction: the error grows with the brightness of what you drop in, because the alpha is too low, and a too-low alpha lets the background flood the pixel. At alpha 20/255 the pixel takes 92 per cent of its final value from something the file has never seen — a dark halo on black, a bright one on white, from the same export.
How much of a shot is like this
On a hard-edged subject the answer is: almost none of it, and it does not matter. Render a figure with a fringe of hair and count where the alpha lands: 57.7 per cent of the subject's pixels come out fully opaque, 10.4 per cent land somewhere in between, and 31.9 per cent are deleted outright. Only that middle tenth is exposed to this problem, and it is exactly the tenth that draws the outline.
Across that band the mean error is 36.6 code levels on black, 43.4 on mid grey and 90.6 on white, with the worst pixels reaching 75, 54 and 134. The mean coverage in the band is 0.459 and the mean alpha the keyer hands back is 0.424; the average pixel is off by 0.247 in the wrong direction.
Which half is to blame
Split the error two ways. Hold the stored colour and pretend the alpha were right, and the residual is 29.8 on every background — the same number, because once the coverage is correct the background term cancels. Hold the alpha and pretend the colour were the true hair colour, and you get 18.3 on black, 36.6 on mid grey and 90.9 on white.
That second row is the useful one. On white, correcting the colour makes the result no better at all — 90.9 against 90.6. When 92 per cent of a pixel is coming from the background, the colour you stored barely registers. On black the colour is worth about half the error. The alpha is the bigger lever in both cases and the only lever on light backgrounds.
The despill controls confirm it from the other side. Pushing the despill slider to 100 takes the stored green from 98 levels above the hair's own green down to 9 — the stored colour is essentially clean — and the composited error on mid grey moves from 52.2 to 47.7. Fixing the colour was never going to fix this.
Why no slider makes alpha equal coverage
The obvious move is to tune similarity until the alpha lines up with the true coverage. It does not converge. Sweep it across a hair fringe and measure how far the alpha sits from the real coverage: at similarity 20 the average gap is 0.397, at 30 it is 0.296, at 40 it bottoms out at 0.272, and at 50 it is back up to 0.304. The floor is around 0.27 and it never approaches zero.
The reason is structural. The keyer reads a distance and a distance is not a coverage; it maps one narrow band of distances onto the whole 0-to-1 alpha range, so a single setting can be right at one coverage and is wrong at every other. Meanwhile the same sweep moves how much hair survives: 6,300 deleted pixels at similarity 20 against 23,021 at similarity 50. You are trading one kind of wrong for another.
If you know what is behind it, say so
There is one thing that does work, and it works because it stops asking the question. This tool has a Background control with three tabs: Transparent, Colour and Image. Pick Colour or upload the plate you are actually going to use, and the export is flattened — the background is baked into the pixels and the file carries no alpha anywhere. Whatever opens it afterwards shows exactly those code values, in every viewer, every time.
Flattening does not make the edge correct. Take the same hair pixel with mid grey baked in and it still sits 50 code levels from where it should be. What flattening buys is agreement: instead of three different answers depending on who opens the file, you get one answer that cannot drift. For a thumbnail, a marketplace listing, a slide or anything that will be shown rather than composited, that is worth more than a correct-but-unstable alpha.
One caveat on that tab: it defaults to #FFFFFF, and white is precisely the background that maximises this error — 90.6 mean error in the band against 36.6 on black. If you are flattening because you do not need transparency, pick a tone close to the real plate rather than leaving it on the default.
Keep the alpha when the next step genuinely needs it: a compositing app that will blend in linear light, a template where the background is decided later, a video overlay that has to sit over moving footage. In those cases the file is supposed to be open about the decision, and the way to make that safe is to fix the alpha rather than the colour — a slightly hard edge that composites predictably beats a soft edge that lets 92 per cent of the background through.
Related questions
Why does the cutout change colour when I open it in a different program?
Because the program is supplying the background term. The file holds a colour and a coverage number; the viewer computes alpha x colour + (1 - alpha) x background. Semi-transparent pixels therefore have no fixed appearance. Fully opaque pixels look the same everywhere, which is why flattening removes the problem.
Is a PNG with an alpha channel always the right export?
Only if something downstream is going to composite it. For anything that gets displayed directly — a listing image, a slide, a social post — a flattened PNG is safer: it carries no alpha, so no viewer can reinterpret the edge. Formats like JPEG have no alpha channel at all for the same reason.
Can I fix this by turning despill up?
Not on its own. Despill to 100 takes the stored green from 98 code levels above the hair's own green to 9, which is essentially clean, but the composited error on mid grey only moves from 52.2 to 47.7. The dominant term is the alpha, not the colour — especially on light backgrounds, where correcting the colour changes nothing at all.
Why is the fringe worse on a white background than a black one?
Because the keyer's alpha at the fringe is lower than the true coverage — 20 out of 255 for a strand covering 40 per cent of the pixel. That leaves 92 per cent of the pixel's final value to be supplied by the background, so the brighter the background, the further the pixel travels from correct: 36.6 mean error on black against 90.6 on white.