All Tools / Blog / How to Resize an Image Without Losing Quality

How to Resize an Image Without Losing Quality

3 min read

Resizing an image always changes the data. When you scale down, the software discards pixels; when you scale up, it invents them. The right resampling filter and output format makes that change invisible at normal viewing distances.

Resampling methods

The filter the software uses when resizing determines how sharp the result looks.

Method Best for Notes
Lanczos Photos, downscaling Sharpest result; slight ringing on hard edges
Bicubic Photos, general use Good quality; standard default in most tools
Bilinear Fast previews Softer; faster to compute
Nearest neighbor Pixel art, icons Preserves hard edges; wrong for photos

For downscaling photos, Lanczos produces the sharpest output. For pixel art or icon sprites, nearest neighbor keeps the crisp edges intact.

In the browser

Drag an image into the image resizer, enter the target width or height, and download. Lock the aspect ratio before entering dimensions to avoid stretching. The tool runs client-side — the image doesn't leave your device.

ImageMagick (command line)

# Resize to 800px wide, maintain aspect ratio
convert input.jpg -resize 800x output.jpg

# Resize to exact dimensions (stretches if ratio differs)
convert input.jpg -resize 800x600! output.jpg

# Fit within a bounding box without upscaling
convert input.jpg -resize 800x600> output.jpg

# Resize with Lanczos resampling
convert input.jpg -resize 800x -filter Lanczos output.jpg

# Resize and convert to WebP at quality 85
convert input.jpg -resize 800x -quality 85 output.webp

The > flag prevents upscaling — useful when batch processing files of unknown dimensions.

sharp (Node.js)

npm install sharp
const sharp = require('sharp');

// Resize to 800px wide, maintain aspect ratio
sharp('input.jpg')
    .resize(800)
    .toFile('output.jpg');

// Resize to exact dimensions, crop to fill
sharp('input.jpg')
    .resize(800, 600, { fit: 'cover', position: 'centre' })
    .toFile('output.jpg');

// Resize with Lanczos kernel
sharp('input.jpg')
    .resize(800, null, { kernel: sharp.kernel.lanczos3 })
    .toFile('output.jpg');

// Resize and convert to WebP
sharp('input.jpg')
    .resize(800)
    .webp({ quality: 85 })
    .toFile('output.webp');

fit: 'cover' crops to fill exactly. fit: 'contain' adds letterboxing. fit: 'inside' fits within the box without cropping or padding.

Python: Pillow

from PIL import Image

with Image.open('input.jpg') as img:
    ratio = 800 / img.width
    new_height = int(img.height * ratio)
    resized = img.resize((800, new_height), Image.LANCZOS)
    resized.save('output.jpg', quality=85, optimize=True)

Image.LANCZOS is the highest-quality downsampling filter in Pillow. In Pillow 10+, it's also available as Image.Resampling.LANCZOS.

The thumbnail() method preserves aspect ratio and never upscales:

from PIL import Image

with Image.open('input.jpg') as img:
    img.thumbnail((800, 800), Image.LANCZOS)  # fits within 800×800
    img.save('output.jpg', quality=85)

Upscaling

Upscaling always loses quality — the software has to invent pixel data that didn't exist. Standard bicubic upscaling looks blurry past about 1.5× the original size.

AI upscalers (Real-ESRGAN, Topaz Gigapixel) produce sharper results at 2–4× but are slow and overkill for most web work. For websites, avoid upscaling: start with a source image large enough for your largest display size.

Retina and HiDPI displays

A retina screen has 2× the pixel density of a standard screen. An image displayed at 400 px CSS width needs an 800 px source file to look sharp. Serve both sizes with srcset:

<img
  src="image-400.jpg"
  srcset="image-400.jpg 1x, image-800.jpg 2x"
  width="400"
  alt="Description"
/>

Common output sizes

Target Recommended dimensions Format
Web banner / OG image 1200×630 WebP
Blog post image 800–1200px wide WebP
Instagram square 1080×1080 JPEG
Twitter/X card 1200×675 JPEG
Email header 600px wide JPEG
Favicon 32×32, 180×180 PNG

Key takeaways

  • Lanczos resampling gives the sharpest result for downscaling photos — use it by default.
  • Never upscale: source images should always be larger than the display size.
  • After resizing, convert to WebP at quality 80–85 for the smallest file at good quality.
  • fit: 'cover' in sharp and thumbnail() in Pillow both handle aspect ratio automatically.
  • Serve 2× images via srcset for retina screens.