Resizing without wrecking the picture

Percentages that land on exact numbers, vectors that stay vectors, and animations that still animate afterwards.

5 min read

Two ways to say how big

You can give a percentage or you can give pixels, and the two are not the same instruction dressed differently. A percentage is a scale applied to whatever each file happens to be, so a mixed batch keeps its variety. Pixels are a target every file is made to meet, so a mixed batch comes out uniform.

In percentage mode both sides are worked out from the source, which is why 4000 by 3000 at 50 per cent lands on precisely 2000 by 1500 rather than something a pixel short. Fitting to a ratio would round one side down to preserve a proportion the numbers already have.

In pixel mode a single side is enough when the ratio is locked — the other is derived from the source. Give both and you choose what happens to the difference: fit the whole picture inside the box, cover the box and let the overflow be cut, or ignore the ratio and stretch to the two numbers exactly.

Instagram square
1080 × 1080
Instagram story
1080 × 1920
Facebook cover
851 × 315
X header
1500 × 500
YouTube thumbnail
1280 × 720
LinkedIn banner
1584 × 396

A vector is not a picture of a vector

An SVG is a set of drawing instructions, not a grid of dots. Scaling one by turning it into dots first throws away the property that made it worth using — so this tool rewrites the file instead. The width and height on the root element are replaced, and a viewBox is added from the original numbers when the file has none.

That last part is the detail that decides whether it works. Without a viewBox, new width and height attributes enlarge the canvas and leave the artwork sitting at its old size in the corner, which looks exactly like a resize that silently failed.

The file is cleaned as it passes through rather than merely read. Keeping a document as a document means keeping whatever its author put inside it, and an SVG can carry script — so anything active is stripped, and a file that still looks dangerous afterwards is refused rather than handed back.

Frames, kernels and the smallest possible side

Animated GIFs and animated WebP are opened as animations, so every frame is scaled and the timing between them is left alone. Handle them as a single image and you get the first frame back, which is a bug that looks like a feature until somebody plays the result.

The scaling filter is Lanczos 3. That is also what the underlying library would pick on its own, and it is written out in the code anyway, because a quality decision this central should not be inherited from a default that could change under us.

Every computed dimension is forced to at least one whole pixel. A ten-to-one panorama taken down to five per cent still has a height, and a zero there is not a small image — it is a failure.

What it takes and what it will not

JPEG, PNG, GIF, WebP and SVG go in; each comes back in the format it arrived as. Up to thirty files in one go, fifty megabytes each, two hundred across the whole task — counted as the bytes arrive rather than read off a header the client controls.

There is also a "do not enlarge" switch, which is worth reaching for in a batch. Ask for 1920 wide across thirty photographs and the ones that were already smaller would otherwise be stretched up to meet it, gaining size on disk and no detail at all.

Frequently asked questions

Can I make an image bigger?
Yes, up to ten times its size, but understand what you are getting: enlarging invents pixels from the ones already there. It suits flat graphics and logos far better than photographs. For a photograph, start from a larger original wherever one exists.
Why did my width come out slightly different?
With the aspect ratio locked and both boxes filled, the picture is fitted inside what you asked for rather than stretched to it, so one side lands short when your box has a different proportion. Unlock the ratio to get the two exact numbers, or use cover to fill the box and crop the overflow.
Does resizing an animation lose frames?
No. The file is decoded as a sequence, every frame goes through the same scale, and the delays are carried over — so the result plays at the speed it did before, just smaller.
Can I set different dimensions for each file?
Not yet. One set of settings applies to the whole batch. If two files need different treatment, run them as two tasks.