ExactSize

PNG size reducer: how much comes off when not one pixel may change

Measured on five real screen captures: 18.24% to 36.01% smaller, with the decoded pixel buffer byte-identical before and after (SHA-256 of the RGBA data, same dimensions). Across all five: 699,658 → 516,000 bytes, 26.25% off. The same five files also show the other half of the answer — the worst of twelve encoder configurations produced a file larger than the original every single time, up to +44.4%.

The short answer

A PNG size reducer that keeps every pixel can take 18–36% off a browser screenshot. It is not a fixed rate, and it can go negative:

  • Screen captures (Chrome): −18.24%, −22.78%, −26.53%, −36.01%, −26.65% — pixels identical
  • All five together: 699,658 → 516,000 bytes, 26.25% off (183,658 bytes removed)
  • Files already written with optimize=True: +22.00% at best, −6.99% at worst
  • Worst configuration tried: bigger than the original on all five captures, +24.5% to +44.4%
  • 70–80% savings: not lossless — that range needs palette quantization, which changes pixels

Ten files, twelve configurations each, decoded and hashed on 30 October 2026. Every byte count below was read from disk; every "identical" claim is a hash comparison, not a visual one.

How to read these numbers: two groups of files, one encoder, twelve configurations per file, and one rule — a result only counts as lossless if the decoded pixels hash the same. Where a figure is arithmetic on top of a measured row I show the division. The byte-target route (what happens when a form demands 100 KB and the pixels may change) is a different measurement and lives on the page about hitting a PNG byte target.

How these numbers were measured

A PNG file has two halves: the pixels, and the way those pixels are described to the compressor. Lossless re-encoding only touches the second half — the row filter applied to each scanline, and the DEFLATE stream that follows. Nothing about colour, alpha or dimensions is allowed to move. The test therefore has one job: prove that nothing moved.

Method, in full: a from-scratch PNG encoder written for this test, using zlib level 9 with twelve configurations — five fixed row filters (none, sub, up, average, Paeth) plus a per-row adaptive choice, each run with both the default DEFLATE strategy and Z_FILTERED. Every output was then decoded again, converted to RGBA, and SHA-256 hashed. A row is only reported as identical if that hash matches the source hash and the width and height match. Ten files, 120 encodes, Windows 11, 30 October 2026.

The ten files are two groups on purpose. The first five are screen captures written by Chrome's DevTools screenshot command — the kind of PNG most people are actually trying to shrink. The second five were written by Pillow with optimize=True, so they start from a writer that already tried to be clever. The difference between the two groups is the whole story of this page.

The five screen captures: what came off, and what it cost

Same encoder, same twelve configurations, five files. "Best" is the smallest output that hashed identical to its source; "worst" is the largest of the twelve.

File Pixels Original Re-encoded Saved Worst of 12 Pixels identical
_aud1.png 1920 × 1065 54,430 44,504 18.24% 68,154 yes — SHA-256 equal
_aud8.png 1904 × 985 210,672 162,678 22.78% 268,452 yes — SHA-256 equal
_api3.png 1920 × 1065 175,877 129,210 26.53% 221,304 yes — SHA-256 equal
_a1.png 1280 × 900 108,329 69,321 36.01% 156,387 yes — SHA-256 equal
_aud11.png 1904 × 985 150,350 110,287 26.65% 187,190 yes — SHA-256 equal
Five together — 699,658 516,000 26.25% 901,487 yes, all five

The total is arithmetic on the rows above it: 699,658 − 516,000 = 183,658 bytes removed, and 183,658 ÷ 699,658 = 26.25%. The worst-of-twelve column sums to 901,487, which is 28.9% more than the five files started at (901,487 ÷ 699,658 = 1.288) — that column is what happens when the encoder picks a filter that does not suit the content.

Lossless PNG compression: what "identical" is checked against

"Looks the same" is not a measurement, and it is how most size-reducer pages get away with a lossy step. The check used here is narrower than that, and it is the only one worth trusting: decode the output file, convert it to RGBA, hash the raw bytes, and compare with the hash of the source decoded the same way.

All five captures passed that check. A single changed pixel — one unit of red in one corner — changes the SHA-256 and the row would have been reported as failed. Palette quantization, the step behind the 70–80% claims, changes thousands of pixels by small amounts; it would fail this check immediately, which is why none of those numbers appear in the table above.

Optimize PNG, and why the answer can be a bigger file

The second group of five was written by Pillow with optimize=True. These are the files that punish optimistic advice: the same encoder, same twelve configurations, and three of the five best results are larger than the input.

File Original Best of 12 Change Winning configuration
gradient-2400x1600.png 2,537,877 1,979,580 +22.00% filter 0 / default strategy
bt-shot-1920x1080.png 83,101 67,489 +18.79% filter 0 / default strategy
bt-chart-1600x900.png 28,605 29,221 −2.15% adaptive / default strategy
graphic-4000x4000.png 84,394 88,449 −4.80% adaptive / default strategy
cutout-3600x3600.png 62,081 66,420 −6.99% adaptive / default strategy

Notice the split: the two files that still shrank were won by filter 0 (no filtering at all), and the three that grew were won by per-row adaptive filtering — meaning the original had already picked filters good enough that a fresh pass could not improve on them, and every configuration that tried something else landed above the input size. What optimize=True does internally is not something this test measured, so I am not going to claim a mechanism for it. The measured fact is enough: on those files the best of twelve attempts lost.

The large-file side: 2.54 MB to 1.98 MB

The biggest file in the set is a 2400 × 1600 smooth gradient PNG of 2,537,877 bytes. Best of twelve: 1,979,580 bytes, 22.00% off, pixels identical. So the technique is not limited to screenshots of a few hundred kilobytes, and on a 2.54 MB file the saving is worth 558,297 bytes on its own — more than eight times the entire original size of the smallest capture in the first table.

That is also the clearest evidence that file size is not what decides the saving. Rank the ten files by size and the percentages do not follow: a 108,329-byte capture gave the best result of the day (36.01%), a 54,430-byte capture gave the weakest of the five (18.24%), and a 62,081-byte cut-out gave a negative result (−6.99%) while a file forty times its size gave +22.00%. What decides it is how much redundancy the original writer left in the file — which is why the same instruction produces a different number on every file, and why any page quoting one fixed percentage is quoting someone else's file.

Compress PNG file size when the pixels are allowed to change

Everything above keeps the pixels. The moment a pixel may change, the arithmetic is different and much larger numbers become available: reduce to a 256-colour palette, dither the gradients, and a screenshot can lose most of its bytes — because most of its colours are gone. That is a legitimate choice for a thumbnail and a bad one for a UI screenshot where text must stay crisp, and it is the step that produces the 70–80% figures. It is lossy by construction, not by accident.

If the constraint is a byte target rather than a percentage — a form that says 100 KB, a CMS that rejects anything larger — that is a different problem with a different measurement: how many pixels survive a fixed byte budget, and where the quality floor sits. To reduce PNG file size to a fixed target, that page carries the measured pixel counts; the same question for photographs is on the 200 KB page. If a format change is acceptable, WebP buys more pixels per byte than PNG ever will, at the cost of losing PNG's exactness.

What to do with this, in order

  • Try lossless first. It cannot make the picture worse, and on a screen capture it typically removes a fifth to a third.
  • Compare bytes, not percentages. If the tool returns a file bigger than the one you gave it, keep the original — three of the ten files here would have been damaged that way.
  • Check that dimensions did not change. A "reducer" that quietly resizes is not lossless, whatever it says.
  • Only then go lossy, and only if the picture can take it: flat UI text usually cannot, photographs usually can.

Questions this page gets

Can you compress PNG without losing quality?

Yes — five screen captures came back 18.24% to 36.01% smaller with a byte-identical decoded pixel buffer. The condition is that the encoder only rewrites the filter and DEFLATE layers. Anything that reduces the colour palette, dithers, or resizes is a different operation with a different result.

Is lossless PNG compression worth it at all?

On files a browser or a screenshot tool wrote, usually yes: 26.25% across five captures here, with nothing to lose. On files that were already written with an optimizing writer, sometimes no: three of the five in the second table came out larger, and the honest move is to keep the original.

Why is my PNG already optimized?

Because whatever wrote it tried several filters and a high compression level before saving. That is what the second group of files looks like: best-of-twelve could only beat them on two of five, and by a smaller margin than the captures. There is no way to tell from the outside — you have to run the comparison and read the byte count.

Does the image get uploaded anywhere?

Not on this site. The compressor on the front page reads the file with the browser's File API and re-encodes it on a canvas inside the page; you can disconnect the network and it still returns the same bytes.

The measurements above were produced by a standalone encoder script, not by the browser tool, because the browser's canvas cannot write PNG with a chosen row filter. The script, its twelve configurations and the hash check are the same ones described in the method section; the outputs are on disk.