How Exact-Size Image Compression Works
By the PNGful team · Published July 13, 2026 · 6 min read
Upload forms love hard limits: a signature under 20 KB, a passport photo under 100 KB, an attachment under 1 MB. But image encoders don’t take a file size as input — only a quality setting whose output size is unpredictable. Hitting an exact target is therefore a search problem, and here’s how a tool like PNGful’s exact-size compressor actually solves it.
Why exact size targets are hard
A JPEG or WebP encoder exposes a quality dial, usually 0–100. The catch: the same quality value produces wildly different file sizes depending on the image. Quality 80 might yield 90 KB for a simple portrait and 600 KB for a busy street scene, because compression efficiency depends on how much fine detail the pixels contain.
There’s no formula to compute “the quality that produces exactly 100 KB” — the only way to know what a setting produces is to run the encoder and measure the output. So an exact-size tool has to encode the image multiple times, strategically, and converge on the target. Done naively (try 100, then 99, then 98…) that’s a hundred encodes. Done well, it takes a handful.
Step 1: choose an efficient format
The first decision is the output format, because it sets the entire playing field. If the destination accepts it, a modern lossy format like WebP typically reaches any given target size with visibly better quality than JPEG — often 25–35% more efficient. If the form insists on JPG (many government portals do), the tool encodes to JPEG instead.
Either way, metadata is stripped first: EXIF blocks, embedded thumbnails, and color profile baggage spend precious bytes of the budget on data nobody will see.
Step 2: binary search the quality
File size increases with the quality setting, and that monotonic relationship is exactly what binary search needs. The tool keeps a low and high bound on quality and repeatedly tests the midpoint:
lo = 1, hi = 100, best = none
while hi - lo > 1:
q = (lo + hi) / 2
size = encode(image, q).bytes
if size <= target:
best = q # fits — try higher quality
lo = q
else:
hi = q # too big — try lower qualityEach iteration halves the search space, so about seven encodes narrow 100 quality levels down to the single best one. Say the target is 100 KB: quality 50 produces 210 KB (too big), quality 25 produces 84 KB (fits), quality 37 produces 112 KB (too big), quality 31 produces 96 KB (fits)… a few steps later the search settles on the highest quality that stays at or under the limit.
The result typically lands within a few percent below the target — 96 KB against a 100 KB limit, say — because quality settings are discrete steps, and the next step up would cross the line. That’s the right side to err on: the whole point is a file the form will accept. Seven or eight encodes of a normal-sized photo take well under a second in a modern browser, which is why the search feels instant even though it’s doing real work.
Step 3: scale dimensions if needed
Sometimes even the minimum quality overshoots — a 12-megapixel photo simply contains too many pixels to fit in 30 KB at any quality worth having. Quality has a floor; dimensions don’t. So when the search bottoms out above the target, the tool scales the image down — say to 85% of its width and height, which removes roughly 28% of the pixels — and runs the quality search again on the smaller image.
This repeats, stepping dimensions down progressively, until a result fits. Reducing pixels is far more effective per unit of visible damage than crushing quality: a slightly smaller image at reasonable quality almost always looks better than a full-size image at quality 5, which is a mess of blocky artifacts. If you already know the required dimensions, resizing before compressing saves the tool the trouble and gives you control over the trade-off.
Why lossless PNG can’t hit small targets
PNG has no quality dial to search. It’s lossless: every pixel must be reconstructed exactly, so the file can only be as small as the image’s actual information content. Photographs are the worst case — sensor noise makes neighboring pixels subtly different, and that near-random variation is mathematically incompressible without discarding it, which PNG is forbidden to do.
In practice, a photo at a given size as a PNG is often 5–10× larger than as a JPEG, and no PNG optimizer can change that by much. So if a form demands “PNG under 50 KB” for a photographic image, the only honest levers are shrinking the dimensions or reducing the number of distinct colors. For graphics — signatures, logos, line art — PNG shines, which is why a signature resizer can produce crisp transparent PNGs under tight KB limits: flat strokes on empty background compress extremely well.
Getting the best result
The algorithm always returns the closest result at or under the target — never over, since “101 KB when the limit is 100” is a rejection. A few tips to help it help you:
- Start from the original, not an already-compressed copy — recompression stacks artifacts.
- Allow WebP if the destination does. More efficient encoding means more quality within the same byte budget.
- Crop away what you don’t need first. Every discarded pixel frees budget for the ones that matter.
- Set realistic targets.A detailed photo at 10 KB will look rough in any format; at 100 KB it can look great.
Common limits have shortcuts — for the classic case there’s a dedicated compress to 100 KBpage — and when there’s no hard limit at all, a regular image compressor with a quality preview is the better tool. Either way the whole search runs locally in your browser: your photo is encoded a dozen times on your own device and uploaded exactly zero times.