PNG to 8-bit Indexed Colour
This writes a genuine indexed PNG — colour type 3, with a palette chunk and one index per pixel instead of four bytes of RGBA. That is where the size win comes from, and it is a thing a browser cannot do for you: canvas.toBlob always emits truecolour, so the palette has to be built and the file assembled by hand.
Drop images here
PNG, JPG, WebP — multiple files allowed
Where the saving comes from
A truecolour PNG stores three or four bytes per pixel before compression. An indexed PNG stores one — or less. The palette itself costs three bytes per entry, so a 256-colour table is 768 bytes of overhead against a saving of two to three bytes on every pixel in the image. On screenshots, UI mockups, flat illustrations, logos and diagrams the result is routinely 60–80% smaller than the original with no visible difference, because those images never had more than a few hundred distinct colours to begin with.
There is a second saving most tools miss. If the palette ends up small enough, PNG can pack several pixels into one byte: 16 colours or fewer fit in 4 bits, four colours in 2 bits, two colours in 1 bit. A two-colour image therefore stores eight pixels per byte before compression even starts. The bit depth is chosen automatically from the palette that actually results, and the result line tells you which one you got.
Photographs are the case where this goes wrong. A photo has tens of thousands of distinct colours, and forcing it down to 256 either bands the gradients or, with dithering on, adds per-pixel noise that defeats PNG's row-based compression — a dithered photo can come out larger than the truecolour original. For photographs use JPG or WebP, which are built for continuous tone.
Dithering, and when to turn it off
Floyd–Steinberg diffuses each pixel's quantisation error into its neighbours, which turns visible banding into fine noise. On a gradient background that is the difference between four obvious stripes and a smooth-looking ramp, so it is on by default.
Turn it off for anything with large flat areas of a single colour — icons, pixel art, screenshots of solid-coloured UI. Those areas are already exactly representable, and the dither only kicks in where the palette misses, so switching it off gives you crisper edges and a noticeably smaller file. It is also the right choice if the image is going to be scaled up afterwards: dither noise magnifies badly.
How transparency survives
Indexed PNG cannot store a separate alpha value per pixel. What it can do is mark palette
entries as transparent via a tRNS chunk — the same mechanism GIF uses. So
transparency here is binary: a pixel is either fully visible or fully invisible, with the alpha
cutoff deciding which. Palette index 0 is reserved as the transparent entry when it is needed,
which keeps the tRNS chunk down to a single byte.
That works perfectly for hard-edged cutouts and badly for soft shadows, anti-aliased text on transparency, and anything with a gradual fade — those need a real alpha channel, and a half-transparent pixel has to pick a side. If the edges matter, flatten onto the background colour the image will actually sit on instead: you keep the smooth edge and lose only the ability to move it to a different background.
FAQ
How is this different from Reduce colors?
Reduce colors quantises the pixels but re-encodes through the canvas, so the result is still a truecolour PNG that merely happens to contain few colours. You see the visual change without much of the size change. This one writes the palette into the file, which is where the bytes actually go.
Is the output a valid PNG everywhere?
Yes. Indexed colour has been in the specification since 1996 and is universally supported — it is what most GIF-to-PNG conversions produce. You can confirm the structure with Chunk viewer, which will show the IHDR colour type as 3 along with the PLTE and tRNS chunks.
Why did my file get bigger?
Almost always a dithered photograph. The dither pattern is high-frequency noise, and PNG's filters plus Deflate rely on neighbouring pixels being similar. Try it with dithering off and a smaller palette, or accept that the image wants a lossy format.
Can I supply my own palette?
Not yet — the palette is computed per image with median-cut, which splits the colour cube along whichever axis has the widest spread until it has the number of boxes you asked for. If you need a fixed palette across a set of images, that is worth asking for.
Does it strip metadata?
Yes, entirely. The file is rebuilt from IHDR, PLTE, optional tRNS, IDAT and IEND — nothing else is carried over, so EXIF, colour profiles and text chunks are all gone. If you specifically want to keep them, use Compress instead and accept the smaller saving.