Compress Image to Target Size

Set a target in kilobytes and this tool binary-searches JPEG quality — and, if you allow it, steps down the dimensions — until your image fits.

Compression runs locally in your browser. Your image never leaves your device.

Pick a target, get the file

Drop an image here

PNG, JPEG, WebP or GIF input — output is JPEG. Click to browse.

Output is JPEG: the browser's WebP encoder would usually hit small targets better, but WebP encoding support varies between browsers, so JPEG is the reliable choice.

How It Works

JPEG size is driven by one dial the browser exposes: the toBlob(type, quality) parameter. The tool treats it as a search problem — find the highest quality value whose output still fits under your target in bytes.

Binary search on quality
Quality is bracketed between 0.05 and 0.95 and halved in for about seven rounds, encoding a throwaway canvas blob at each probe. Size is monotonic in quality, so a plain binary search lands on the best fitting value in a fraction of a second for normal photos.
The downscale ladder
If even quality 0.05 overshoots the target at full resolution, pixels — not just precision — have to go. The image is redrawn at 90 %, then 80 % … of its dimensions, with the quality search retried at each rung, until it fits or the short side hits 64 px and the tool honestly reports defeat. The checkbox keeps this behaviour opt-in.
Why JPEG output, not WebP
WebP at the same visual quality is typically 25–35 % smaller, so it would hit aggressive targets with less damage. But canvas.toBlob('image/webp') silently falls back to PNG in Safari versions without WebP encoding support, which would break the size promise — JPEG is universally supported, so it is the dependable contract here.

Frequently Asked Questions

Is this lossy or lossless compression?

Lossy — and deliberately so. Hitting a kilobyte target like 200 KB from a typical camera JPEG (3–8 MB) is impossible with lossless methods, so the tool tunes the JPEG quantization tables via the quality parameter and, if needed, throws away pixels by downscaling. Your original file is never touched; every attempt is a fresh canvas re-encode.

Can I batch-compress a whole folder?

No — one image at a time, by design. A size target is judged per file, and quality behaves differently for a flat graphic than for a busy landscape, so serial processing keeps you honest about each output. For bulk work without size targets, the plain image compressor on this site handles batches.

Why 200 KB? That number keeps showing up.

Passport and visa portals (India's PVNTRV, many US e-services, UN agencies) and job-application forms cap uploads at roughly 100–300 KB, and 200 KB is the common middle ground that keeps faces crisp at 600–900 px width. The default here matches that use case, but any positive target works — 20 KB for forum avatars, 500 KB for print-ready proofs.

Will the result be exactly my target size?

It will be at or below it, never above. The search finds the highest quality whose encoding fits — and because JPEG size jumps in steps, the result usually lands somewhat below the target. If the fit is much smaller than requested, raise the target or you had a very flat image that compressed effortlessly.

Is anything uploaded to a server?

No. Decoding, the encode loop and the size checks are pure Canvas API work inside your browser tab — no network request carries your image. The tool keeps working with the network switched off.