Downscale Image
Reduce image dimensions right in your browser with a quality slider and smooth multi-pass scaling. Supports JPG, PNG, WebP, and GIF.
Shrink JPG / PNG / WebP / GIF in your browser. Multi-pass downscale for large reductions (avoids Moiré), output-format selector, quality slider, original filename preserved. Output format matches your input, with a clear warning if converting would make the file larger.
How to Use Downscale Image
- Drop an image on the upload area, or click to pick. JPG, PNG, WebP, and GIF accepted. SVG is REJECTED - it's vector, not raster, so "downscale" doesn't apply (use a vector editor).
- Pick the output format. "Keep original" preserves JPG → JPG, PNG → PNG, WebP → WebP, but maps GIF → PNG (Canvas can't re-encode GIF).
- Drag the scale slider (0.10× to 1×). Live preview re-renders on each change (debounced 150 ms).
- For scale < 0.5, multi-pass halving kicks in. The "Halving passes" stat shows how many. This avoids Moiré/aliasing - single-pass canvas downscale to 0.1× looks rough; halving 3 times then doing the final small pass looks much better.
- Adjust quality (0.10 to 1.00) when outputting JPG or WebP. The quality slider hides itself for PNG (lossless - quality ignored).
- Check the reduction % in the stats card. If it's NEGATIVE (file got bigger), the bloat warning appears - usually because PNG was forced on a photo.
- Press Ctrl+Enter or click Re-scale to re-process, then Download (filename preserved:
cat.jpg→cat-scaled.jpg) or Copy to clipboard.
Frequently Asked Questions
Why does PNG output sometimes bloat my photos?
PNG is lossless and uses DEFLATE compression – it works well on flat-color images (logos, screenshots, UI) but POORLY on photos because photos have too many unique pixel values for the entropy coder. A 200 KB JPG photo at 1000×1000 px decoded and re-encoded as PNG typically lands at 1.5-2 MB. For photos: always pick JPG (lossy, photo-tuned DCT) or WebP (lossy or lossless, modern). The bloat warning fires automatically when JPG → PNG is detected, or when output size > input size.
What does “Halving passes” mean?
Canvas’s built-in imageSmoothingQuality: 'high' implementation varies by browser, but no browser does proper multi-tap polyphase decimation in a single drawImage. At large reductions (0.1×, 0.25×) single-pass produces aliasing/Moiré – fine detail (text edges, brick patterns, fabric weave) ringings into wrong-frequency artifacts. Solution: halve repeatedly. Each halve is a 4-pixel → 1-pixel average that browsers handle well. So 0.125× = 3 halvings (1 → 0.5 → 0.25 → 0.125). 0.1× of a 10000-px image: 3 halvings to 1250 px, then a final pass to 1000 px.
Why is SVG rejected?
SVG is vector – it scales infinitely without quality loss. “Downscaling” SVG would mean rasterizing it to a chosen pixel size and saving the bitmap, which loses the vector advantage entirely. If you actually want SVG → PNG/JPG conversion, use a vector → raster export tool. If you want to make an SVG file smaller in bytes, that’s a separate task (SVGO-style minification, removing metadata).
What about GIF animation?
Only the FIRST frame is preserved. Canvas’s drawImage on an HTMLImageElement decoded from a GIF reads only the static-display frame (which is typically the first). To downscale animated GIF properly you’d need to decode each frame, downscale each, and re-encode as GIF – Canvas can’t encode GIF natively (it can’t write the GIF87a/89a container). For animated content, use a video format (MP4/WebM) or APNG instead. Output for GIF input is forced to PNG (the first frame).
Does this work offline?
Yes. Once the page loads, no network requests are made. All processing uses Canvas 2D API in your browser. Your images never leave your device. You can verify by disconnecting your internet, reloading the cached page, and using the tool.
Is there an upper image size limit?
Soft limit: 50 MB triggers an info toast warning the browser may freeze. Hard limit: Canvas dimensions are browser-capped (Chrome ~32k × 32k, Safari ~16k × 16k). Images larger than the cap will fail to decode into a Canvas. For very large images consider a desktop tool – browser memory pressure can crash the tab around 100 MP source images.
Why not use bicubic / Lanczos in JavaScript?
A pure-JS Lanczos resampler would give better-than-Canvas results but is slow (seconds per megapixel) without WebGL or WebAssembly. The pragmatic engineering choice for a 100% client-side, instant-feedback tool is multi-pass halving + final single-pass – visually 95% as good as Lanczos for the common case (scale 0.25-0.5) and 10× faster. If you need photo-grade resampling for print, use a dedicated tool like ImageMagick or Photoshop offline.
Can I batch process?
Not in this version. One image at a time is intentional – batch processing in a single tab risks running out of memory on mobile devices (browser kills the tab). For batch use, run the tool in multiple tabs or use a desktop tool. The tool’s logic.js is pure functions, so you could script it in Node with canvas npm package if needed.
Is my data private?
Yes. 100% client-side. No fetch/XHR calls. No analytics. No telemetry. Your image is read with FileReader, decoded into an in-memory Image, downscaled in a Canvas, and returned as a Blob that lives only in your browser’s memory until you download or close the tab. Verify via your browser’s Network tab – only the initial HTML/CSS/JS load happens, no uploads.