CompressDog

Lossless PNG Recompression: 12.7% Smaller, Verified

Most compressors cannot promise your pixels survive. PNG recompression can, so we measured 261 files and checked every output byte for byte against the original.

"Lossless" is the kind of word that gets used loosely. A service will call itself lossless because the format is lossless, or because it did not touch the quality slider, or because the difference is hard to see.

For PNG we can make a stronger claim than usual: the pixels come out identical. Not "visually identical". Identical. So we tested whether that holds on real files, and how much it actually saves. The format where that guarantee does not exist is covered in our screenshot guide, and the wider format question is answered here.

What we ran

261 PNG files from three folders on one machine. A folder of artwork, a desktop, and a downloads folder. That mix matters: the first is generated art, the second is mostly screenshots, the third is whatever the internet handed over.

Each file was recompressed with the site's own call: oxipng at level 2, transparency preserved, the exact arguments from our worker code. Nothing else was touched.

Then every output was decoded and compared to the original, pixel by pixel, in RGBA space. Files that produced different pixels were pulled out and investigated separately. That turned out to be the most interesting part.

What came out

That last line is unusual and worth stating plainly, because the general rule for compressors is that some files come back bigger. Here they never did.

Small files gained the most

The trend is consistent, but do not lean on the first two rows: 8 and 10 files are not a group, they are an anecdote. The two larger buckets have enough files to trust.

Why would small files shrink more, proportionally? Probably overhead. A small PNG is often a screenshot that was saved by a tool that did not try very hard with the deflate stream, so there is more slack to reclaim. A 4 MB export has already had someone's attention.

The eight files whose bytes changed

Eight files came back with different pixel bytes. Six of them had "removebg" in the filename, which is a strong hint: those are cut-out images with transparency.

We checked all eight properly. For each one, we counted pixels where the colour changed and the pixel was not fully transparent. Those are the only changes a person could ever see.

Zero. In all eight. And composited over white, every one was byte-identical to the original.

What oxipng had done is drop the colour values underneath fully transparent pixels. An invisible pixel still has a colour stored in it, and that colour costs bytes. Replacing it with something cheaper changes the file, not the image. Any decoder shows the same thing.

Those eight happened to save the most, between 12% and 53%, with seven of the eight above 16%, because a transparent background is far cheaper to encode once you stop preserving what nobody can see.

What 12.7% is good for, and what it is not

Twelve percent is a real saving and it is free. You lose nothing. It is also not enough to get a 4 MB screenshot under a 1 MB upload limit. If that is the problem you have, the PNG tab has a second mode: reduce to a palette. That one is lossy, it changes colours, and the preview is there so you can decide rather than guess.

We would rather say that clearly than let "lossless" imply it will solve every size problem.

Caveats

One machine, three folders. Other people's PNGs will have been saved by different tools, and the savings depend on how much slack the original encoder left.

These are ordinary consumer files. Huge exports from design software, or PNGs written by an optimiser at maximum settings already, will save little or nothing.

The per-folder numbers differ, 14.1% for the desktop folder, 11.4% for downloads, which tells you the result is a property of the files, not of oxipng alone. Treat 12.7% as "what one person's collection did", not as a promise.

And the pixel check is 8-bit RGBA. A 16-bit PNG converted down would show up as a difference, and we did not specifically test for that case.

Reproducing it

tools/measure-png-lossless.mjs. It needs Pillow for the pixel comparison, and it loads the oxipng build from dist/, so run the build first. It took about eleven minutes for 261 files.

It writes a JSON with per-file numbers, including the ones where bytes changed.

If you run it and get a materially different number, we would like to know. The address is on the about page, and a contradiction with a concrete example is more useful to us than agreement.

Open the compressor