Alpha flattening — what happens to transparency when you convert PNG to JPG
JPG refuses to carry an alpha channel. When you convert a PNG (or WebP, or AVIF) with transparency to JPG, the transparent and partially-transparent pixels in your source need to land on something — and that something has to be a colour. The converter picks white.
When flattening kicks in
Among the supported output formats — jpg, png, webp, avif — only jpg triggers the flattening step. PNG, WebP, and AVIF all preserve alpha and skip flattening entirely.
The converter detects the no-alpha case by checking the chosen output before drawing. If the destination is JPG, it fills the canvas with white before drawing the source onto it. The order matters: white first, image on top, so the image's own alpha channel composites against the white fill rather than against whatever was previously in the canvas buffer.
if (outputFormat === 'jpg') {
ctx.fillStyle = '#FFFFFF';
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
ctx.drawImage(img, 0, 0);
The compositing math
Each output pixel is a weighted average of the source pixel and the white fill, weighted by the source's alpha. For a fully opaque pixel (A=255), the output is exactly the source colour. For a fully transparent pixel (A=0), the output is white. For everything in between, the output is a linear blend.
out_R = src_R · (A/255) + 255 · (1 − A/255)
out_G = src_G · (A/255) + 255 · (1 − A/255)
out_B = src_B · (A/255) + 255 · (1 − A/255)
The blending happens in the 2D canvas at premultiplied-alpha precision, then the result is read out as an opaque RGB buffer that the JPEG encoder writes to disk.
Why white, and not something else
White is a default that produces the least surprising result for the most common inputs: logos, icons, screenshots, and product shots usually live on white backgrounds in the user's mental model. Picking black would invert the apparent shape of any anti-aliased edge; picking the page background colour would require knowing where the image will eventually be placed.
Other tools sometimes ask for a fill colour, sometimes guess from the corner pixels, sometimes use a neutral grey. The converter doesn't ask, and doesn't guess — white is the explicit default and the only choice. If white is wrong for your image, the workaround is to pre-composite in a desktop image editor (drop a layer of the colour you want behind the image, flatten, export) before uploading, or to choose a format that preserves alpha.
The halo problem
If your PNG was authored against a dark background — a logo with a shadow that fades into black, say — the partially-transparent edge pixels carry colour values that assume black behind them. Composited onto white, the same anti-aliased edges produce a faint white halo around the shape because the blended colour is now (dark · A + white · (1 − A)) instead of the (dark · A + dark · (1 − A)) the artwork was designed for.
This is unavoidable in any format conversion that drops alpha. The data needed to render the edge correctly against a dark background is no longer present. The fix is at source — re-export the PNG against the new background colour, or keep alpha by choosing PNG/WebP/AVIF as the output format.
A note on the PNG spec's "matte"
PNG defines a small chunk called bKGD that lets the encoder declare a default background colour for renderers that can't composite. The PNG spec says renderers may use it; in practice, almost no viewer does. The converter ignores it as well — the white fill is hard-coded, not derived from any hint in the source. Doing otherwise would make the conversion result depend on a chunk most authors don't even know exists.
How to keep your alpha
Pick an output format that supports it. PNG is the most universal; WebP and AVIF give you smaller files at the same visual fidelity. Any of those routes through the same canvas without the white-fill step — alpha bytes pass straight to the encoder. If you need a JPG specifically (smaller files, universal compatibility), accept that transparency goes away and design around it.