iKit
Guide · 10 min read ·

Image Resizer Online: Pixels, Percent, Longest Side (2026)

Resize an image online by exact pixels, percentage, longest side, or preset — plus how to choose a target size, batch safely, and avoid blur.

Image Resizer Online: Pixels, Percent, Longest Side (2026)

Image Resizer Online: Pixels, Percent, Longest Side

A 6000-pixel-wide phone photo does not belong in a blog post, an email signature, or a Slack avatar. Every one of those needs a different target size, and the fastest way to get there is an image resizer online that takes the dimensions you actually care about. This guide covers the four ways to specify a target size, which one to reach for, and how to resize without introducing blur.

TL;DR

  • Four resize modes: exact pixels, percentage, longest side, and named presets.
  • Longest side is the only safe mode for a mixed batch of orientations.
  • Downscale only. Upscaling invents pixels and always looks soft.
  • Export at 2× the CSS width for retina displays, then compress.
  • Browser-based resizing keeps the original file on your machine.

What "resize an image" actually means

Three operations get casually called resizing, and they do completely different things to a file. Getting the vocabulary straight saves a lot of wasted exports.

Resizing vs cropping vs compressing

Resizing changes the pixel dimensions of the image: a 4000 × 3000 photo becomes 1200 × 900. Every pixel of the original scene is still there, just represented by fewer samples.

Cropping changes the framing: it throws away the parts of the image outside a rectangle. A 4000 × 3000 photo cropped to 1:1 loses a quarter of the scene. If you need a specific aspect ratio, you need a cropper, not a resizer — resizing to a different ratio squashes the subject instead.

Compressing changes the file size without touching the dimensions, by spending fewer bits per pixel. A 1200 × 900 JPEG at quality 90 and the same image at quality 60 have identical dimensions and very different byte counts. That is the job of an image compressor.

Most real tasks are a resize followed by a compress. Resize first — compressing a 4000 px image and then shrinking it wastes the compression work entirely.

Why aspect ratio locking matters

An image's aspect ratio is width ÷ height. Change width and height independently and you distort the picture: faces stretch, circles become ovals, and text in screenshots goes subtly wrong in a way readers notice without being able to name.

A good resizer locks the ratio by default and derives the second dimension from the first. Unlock it only when you genuinely want to stretch — which, for photographs, is almost never.

Resampling: what the browser does to pixels

When 4000 pixels become 1200, the output pixel at position 0 has to represent roughly 3.3 input pixels. The algorithm that decides its color is the resampling filter. Nearest-neighbour picks a single input pixel and produces jagged edges. Bilinear averages a small neighbourhood. Lanczos and other windowed-sinc filters weigh a wider neighbourhood and preserve edge detail best for photographic content.

On the web, the filter is chosen through the resizeQuality option of createImageBitmap() or through the canvas smoothing settings — the browser maps those hints onto its own implementation rather than letting you name a filter directly.

How to resize an image online without losing quality

"Without losing quality" is a slight fiction — downscaling discards information by definition. What you can avoid is visible degradation, and that comes down to three habits.

Always downscale, never upscale

There is no information in a 400 px image to build a sharp 1600 px image from. Upscalers either interpolate (soft result) or hallucinate detail with a model (plausible but invented result). Keep a master file at the largest size you ever shot or exported, and generate every derivative from it. Never resize a derivative of a derivative.

Choose the right resample quality

Per MDN, the resizeQuality option on createImageBitmap() accepts pixelated, low, medium, or high — and the default is low. That default is why so many hand-rolled canvas resizers produce mushy output: nobody changed it. The canvas equivalent, imageSmoothingQuality, also defaults to "low" and MDN currently flags it as having limited availability across browsers, so treat it as a hint rather than a guarantee.

Use high for photographs. Use pixelated only for pixel art and QR-style graphics, where smoothing destroys the point.

Re-encode once, not three times

Each decode-and-re-encode cycle through a lossy codec compounds artifacts. Resizing a JPEG to 2000 px, then to 1200 px, then to 800 px runs three lossy encodes; resizing straight from the master to 800 px runs one. If you need several sizes, export them all from the same source in a single pass rather than chaining.

If you also need a different format, do the format conversion in the same step rather than as a separate round trip.

Four ways to specify the target size

Every serious resizer offers some subset of these four input modes. They are not interchangeable.

Mode You supply Best for
Exact dimensions Width and height in px One image, one known spec
Percentage A single ratio (e.g. 50%) Uniform shrink of similar files
Longest side One max value in px Mixed batches, mixed orientations
Preset A named target Social, OG images, app icons

Exact dimensions (width × height in pixels)

The literal mode: type 1200 and 630, get 1200 × 630. Use it when a spec hands you exact numbers — an OG image, a banner slot, a hardware display. With ratio lock on, you type one number and the tool computes the other.

The trap is batching. Forcing every file in a folder to 1200 × 630 either distorts the portrait ones or pillarboxes them.

Percentage scaling

You give a ratio; each image shrinks relative to its own dimensions. 50% turns a 4000 px photo into 2000 px and an 800 px screenshot into 400 px. That is great when your inputs are homogeneous — a burst of shots from one camera — and useless when they are not.

Percentage is also the natural mode for the "this is roughly twice as big as it needs to be" situation, where you do not know the target but you know the ratio.

Longest side (the "max dimension" mode)

You give one number: the maximum length of the longer edge. A 4000 × 3000 landscape shot capped at 1600 becomes 1600 × 1200. A 3000 × 4000 portrait shot capped at 1600 becomes 1200 × 1600. Both now fit inside a 1600 px box, both keep their ratio, and neither was upscaled.

This is the mode to use for anything batch-shaped:

  • A folder of camera photos in mixed orientations
  • Screenshots collected from different devices
  • User-uploaded avatars of unpredictable size
  • Anything headed into a documentation repo with a size budget

The arithmetic is trivial, and the Math.min(1, …) is what prevents accidental upscaling:

function fitLongestSide(w, h, max) {
  const scale = Math.min(1, max / Math.max(w, h));
  return {
    width: Math.round(w * scale),
    height: Math.round(h * scale),
  };
}

Presets for social, OG images, and app stores

A preset is just a saved exact-dimension pair with a name attached, which matters because the specs change and nobody memorises them. The iKit resizer ships presets for the common social placements; for platform icon sets, where one source has to become a dozen named files at once, an app icon generator is the better tool.

What size should I resize my image to for the web?

The honest answer is "the largest size it will ever be displayed at, times your device-pixel-ratio budget." Here is how that cashes out in practice.

Content images and srcset widths

Pick the widest your layout ever renders the image, then generate a ladder around it. For a 700 px content column, 640 / 1200 / 1920 covers 1× phones through 2× desktops without shipping a 4000 px file to anyone.

Use CSS width Export at
Content image 700 px 640 / 1200 / 1920
Full-bleed hero 1440 px 1440 / 2880
OG / social card 1200 px 1200 × 630
Avatar 48 px 96 / 144

Then let the browser choose. MDN's responsive images guide covers the syntax; the short version is that width descriptors need a matching sizes attribute, and you cannot mix width and density descriptors in one srcset:

<img
  src="photo-1200.webp"
  srcset="photo-640.webp 640w,
          photo-1200.webp 1200w,
          photo-1920.webp 1920w"
  sizes="(max-width: 700px) 100vw, 700px"
  width="1200" height="800" alt="Harbour at dusk">

Always set width and height attributes on the resized output. They let the browser reserve layout space before the bytes arrive, which is what keeps your Cumulative Layout Shift score down.

Hero and OG images

Open Graph cards are one of the few places where an exact size is genuinely required: 1200 × 630 is the ratio every major platform crops to, and anything else gets letterboxed or centre-cropped unpredictably. Because the card is re-encoded by the platform anyway, export it at quality 80–85 rather than 95 — you are paying bytes for detail that gets thrown away downstream.

Retina and devicePixelRatio (the 2× rule)

A 48 px avatar on a devicePixelRatio: 2 screen is 96 device pixels. Ship 48 and it looks soft; ship 96 and it looks correct. Ship 144 for 3× phones if the element is small enough that the extra bytes are trivial — for a 48 px avatar it is. For a 1440 px hero, a 3× export is 4320 px and absolutely not worth it; 2× is the sane ceiling for large images.

How to batch resize images in the browser

Batch resizing is where the mode choice stops being academic.

Longest side is the only safe batch mode

Given a folder with landscape photos, portrait photos, and the odd square screenshot, exact dimensions distort and percentage produces inconsistent results. Longest side gives every file the same worst-case footprint while preserving each one's ratio. Set it to the largest size any of them will ever be displayed at, and you are done.

Mixed orientations: portrait and landscape in one job

Watch for the case where a "landscape" file is actually a portrait photo carrying EXIF orientation metadata. Its stored pixel dimensions say 4000 × 3000, but it displays as 3000 × 4000. If your resizer reads raw dimensions and ignores the orientation tag, longest-side capping still works — but the rotation may be lost in the output.

Keeping EXIF orientation from flipping your photos

createImageBitmap() defaults imageOrientation to from-image, meaning it honours the EXIF rotation tag. Passing none gives you the raw sensor orientation and is how sideways photos happen. Worth knowing in the other direction too: re-encoding through a canvas typically drops the rest of the EXIF block, including GPS coordinates — which is a privacy win, and the mechanism behind stripping location data by re-encoding.

Resizing in code, when a tool is not enough

If you are building the resize into an upload pipeline rather than doing it by hand, two APIs matter.

createImageBitmap with resizeWidth and resizeQuality

This is the direct route: the browser decodes and scales in one step, off the main thread where it can, and you never touch a canvas for the scaling itself.

const file = input.files[0];
const probe = await createImageBitmap(file);
const target = fitLongestSide(
  probe.width, probe.height, 1600,
);

const bitmap = await createImageBitmap(file, {
  resizeWidth: target.width,
  resizeHeight: target.height,
  resizeQuality: "high",
});

createImageBitmap() has been available across browsers since September 2021, so it needs no polyfill in 2026 — though resizeQuality is one of the parts whose support MDN notes can vary.

Canvas drawImage as the fallback

You still need a canvas to serialise the result to a file. Set smoothing explicitly rather than trusting the default:

const c = document.createElement("canvas");
c.width = bitmap.width;
c.height = bitmap.height;

const ctx = c.getContext("2d");
ctx.imageSmoothingEnabled = true;
ctx.imageSmoothingQuality = "high";
ctx.drawImage(bitmap, 0, 0);

c.toBlob((b) => save(b), "image/webp", 0.82);

Note the third argument to toBlob() — the quality factor applies to lossy formats only. Pass it for image/webp and image/jpeg; it is ignored for image/png.

Why the manual canvas route often looks worse

If you have ever written a fifteen-line canvas resizer and been disappointed, the reason is almost always the two defaults: resizeQuality is low and imageSmoothingQuality is low. The old workaround — halving the image repeatedly until you approach the target — exists precisely because of that low-quality default. With resizeQuality: "high" you rarely need the stepped approach any more.

References

Related on iKit

Related posts