CompressDog

Raising Quality on an Already-Bad JPEG Makes It Worse

On 320 photos, re-encoding a quality-45 file at 90 made every one score slightly worse and almost doubled its size, while staying 20 points short of a clean encode.

Someone sends you a photo that looks mushy. You open it in an editor, drag the quality slider from wherever it was up to 90, save. The file is now bigger and the picture is... still mushy. You assume it at least did not hurt.

It hurt. Slightly, on every image we tested.

The three paths

The question has a clean form, so we set it up as three paths from the same original:

B and A end in the same format, the same quality, the same encoder. B just went through one low-quality pass first. If raising the slider recovers detail, B should land near A. If it does nothing, B should land near C.

The numbers

320 JPEGs, scaled to 768 px on the long edge, scored with SSIMULACRA2 against the decoded original.

The q45 pass cost 20.09 points. Re-encoding at 90 recovered minus 0.43 of them.

Not "zero". Minus. All 320 images came out slightly worse than the file they started from, and the average was 2.1% of the loss in the wrong direction.

The size went the other way: 183.7 KB against 96.3 KB, an increase of 90.9%, for a file that still sits 20.5 points below a clean encode.

Why it gets worse rather than just not helping

A q45 image is full of compression artifacts. They are not detail, but they are structure, and an encoder has to spend bits on them. At quality 90 it tries hard to represent every one of them faithfully, which is a lot of work for something you would rather it ignored. Then that effort introduces its own quantization and throws away a little more.

So the second pass does not restore anything. It spends roughly twice the bytes describing the damage more precisely, and loses a fraction of a point doing it.

Our earlier piece on why compressing an image can make it bigger is the same mechanism from a different angle: the encoder has no way to know that some of the signal it is being asked to preserve is not signal at all.

What to do instead

If you still have the original, re-encode from the original. That is the only path that recovers anything, because it is the only one that has the detail.

If the q45 file is all you have, leave it alone. More precisely:

Caveats

Pillow's libjpeg, not this site's encoders. The absolute numbers would shift with a different encoder, but "re-encoding a damaged file at high quality does not recover it" is a property of lossy compression rather than of one implementation. 768 px sources, mostly already-compressed JPEGs.

Quality 45 and 90 were the only two settings tested. A different pair would change the magnitude. The direction of the result seems unlikely to reverse, though: once detail is gone, later encoders cannot see what was there.

And SSIMULACRA2 is a metric. That said, this is the one result where you can verify it by eye in ten seconds: open C and B at 100% and try to find a difference that favours B.

Reproducing it

The script is tools/measure-quality-recovery.py. It needs Pillow and ssimulacra2 on the path, and takes about six minutes for 320 images.

If your own images behave differently, tell us. The about page has the address, and all six of our measurements are collected on one summary page.

Open the compressor