Resizing without losing quality: what actually happens to the pixels
7 min read · Measurements taken 2026-08-09
“Resize without losing quality” is a slightly dishonest phrase. Making an image smaller always discards pixels — that is the entire operation. The real question is whether the pixels that survive are the right ones, and different scaling methods give measurably different answers.
How to score a resize objectively
Comparing two scaled images by eye is unreliable, so we needed a ground truth. At an exact integer scale factor there is one: scaling to precisely 25% means each output pixel corresponds to a 4×4 block of input pixels, and the mathematically correct value is that block’s average.
So we computed that exact area average at full floating-point precision, then scored each real scaling method by its RMS error against it. Lower is better; zero would be perfect.
| Image | Browser default | Lanczos (pica) | Difference |
|---|---|---|---|
| Landscape photo | 3.41 | 2.02 | −41% error |
| High-detail photo | 19.12 | 8.38 | −56% error |
| Saturated close-up | 11.22 | 8.47 | −24% error |
| High-contrast photo | 2.17 | 1.20 | −45% error |
| Flat graphic | 1.77 | 2.24 | +26% error |
| UI screenshot | 27.95 | 11.12 | −60% error |
| Graphic with transparency | 2.97 | 5.80 | +95% error |
Why the browser default is worse on photographs
When you draw an image into a smaller canvas, the browser uses a fast filter that samples a small neighbourhood around each output pixel. It is quick, and for mild reductions it is fine. Shrink by a large factor and it starts skipping information: detail that falls between the sampled points is simply never consulted.
The visible result is aliasing. Fine repeating detail — brick, foliage, fabric weave, the pixel grid of a screenshot — turns into shimmer and moiré patterns that were not in the original. Our densely textured Mount Rushmore photograph shows the largest gap in the table for exactly this reason.
Lanczos takes a wider window and weights it with a windowed sinc function, which is much closer to what sampling theory says the answer should be. It costs more computation — which is why browsers do not do it by default — and it is what our resizer uses via the pica library.
The exception: flat graphics and hard edges
The two rows where Lanczos loses are the honest part of this data, and they are not a fluke. Lanczos uses negative lobes — it deliberately overshoots on either side of an edge to keep that edge crisp. On photographs this reads as sharpness. On a hard-edged shape it produces ringing: a faint bright halo just outside the edge and a dark one just inside.
Against a ground truth defined as a pure area average, that overshoot scores as error, which is why the flat graphic and the transparent shape came out worse (2.24 against 1.77, and 5.80 against 2.97). Whether you perceive that as worse depends on the image: mild ringing on a logo is usually invisible, but on a large flat area next to a hard edge it can show as a faint outline.
The practical rule: for photographs and screenshots, high-quality resampling is clearly better. For flat vector-style graphics, if the result must be pixel-exact, export from the original vector file at the size you need rather than scaling a raster version at all.
Upscaling cannot be fixed
Everything above concerns making images smaller. Making them larger is a different problem and a much less hopeful one. A 400-pixel-wide image enlarged to 1200 needs two-thirds of its pixels invented, and no interpolation can recover detail that was never captured.
Good resampling produces a smooth enlargement rather than a blocky one, but smooth is the ceiling. If you need a larger image, the only real fix is to go back to a higher-resolution original. Machine learning upscalers hallucinate plausible detail, which is useful for some purposes and actively misleading for others — they are inventing, not recovering.
Practical advice
Resize once, from the largest original you have. Scaling 4000px → 2000px → 1000px compounds error at each step. Go straight to your target size.
Resize before you compress. Discarding pixels first means the compressor has less to encode, and the quality setting then applies to the image people actually see. Our workflow guide measures how much that ordering saves.
Keep the aspect ratio unless you mean it. Stretching is more noticeable than any resampling artefact, particularly on faces and type.
For a batch, fit rather than force. Bulk resize scales each image to fit inside your dimensions while keeping its own proportions, so a mixed folder of portrait and landscape photos does not get squashed.
How we measured this
Each image was downscaled to exactly 25% width by two methods in headless Chromium: canvas drawImage at reduced size (the browser default) and pica’s Lanczos filter (what our resizer uses). Both were scored by RMS error against the exact 4×4 area average computed in double precision. The script is scripts/benchmark.mjs; this page renders its output directly.
We first tried scoring by high-frequency energy, on the assumption that more detail meant a better result. That metric ranked the browser default higher — because aliasing is high-frequency energy. It was measuring the artefact as if it were a feature, so we replaced it with the error-against-ground-truth method above.