FormFix

Compressing Images Without Visible Quality Loss

How binary search quality reduction + smart resizing achieves tiny file sizes while keeping images sharp.

FormFix Team
  • #image
  • #compression
  • #webp

Image compression feels like magic: you start with a 6 MB photo from your phone, click one button, and get back a 200 KB JPEG that looks identical. Under the hood, though, there is no magic — just a careful negotiation between two lossy processes, quality reduction and resizing, each of which trims away information your eye is unlikely to miss. FormFix’s compressor combines both, and a binary search picks the smallest output that still meets a target size.

The first lever is JPEG (or WebP) quality. When you encode an image at quality 92, the encoder throws away high-frequency detail that the human eye is bad at seeing — subtle texture in skies, fine grain in shadows, micro-contrast in flat areas. Drop the quality to 80 and most viewers still cannot tell. Drop it to 60 and you might notice a faint blockiness in smooth regions; at 40, artifacts become obvious. The sweet spot for “indistinguishable from the original” is usually somewhere between 75 and 85, depending on content. Photographs tolerate aggressive compression; screenshots and line art do not, because their sharp edges make artifacts obvious.

The second lever is resolution. A 4000×3000 photo printed at wallet size can be downscaled to 1200×900 with no perceptible loss; the same photo displayed on a website at 800 pixels wide can be downscaled much further. Modern browsers and createImageBitmap support high-quality resampling (typically Lanczos or Mitchell filters), which means downscaling preserves edges and color accuracy far better than naive nearest-neighbor or bilinear sampling. The trick is to scale only as much as the use case allows — a passport photo that must be 600×600 pixels should never be downscaled further, but a hero image bound for a 1080p screen has a lot of headroom.

The hard part is hitting an exact target size, like “under 20 KB” for an online form. Quality is not a linear function of file size — a photo with lots of detail might compress to 60 KB at quality 80, while a flat logo compresses to 8 KB at the same setting. FormFix solves this with a binary search: try quality 0.92, measure the output, and if it is too big, try 0.5, then narrow in between. After about a dozen iterations the search converges on the highest quality that still fits the budget. The whole loop runs inside a Web Worker, so the main thread stays responsive.

If even the lowest quality (around 0.15) cannot bring the file under target, the compressor switches strategy and downscales. Typically it halves the longest edge, re-runs the binary search, and repeats until either the target is met or the image becomes unreasonably small. This two-stage approach — quality first, then size — is what allows FormFix to nail targets like 20 KB or 50 KB on real-world inputs without producing a 200×150 pixel thumbnail.

Format choice matters too. WebP typically beats JPEG by 25–35% at the same visual quality, and it supports transparency, which JPEG does not. PNG is lossless and great for screenshots and logos, but its file sizes are usually much larger than JPEG for photographic content. FormFix defaults to JPEG for compression targets (because almost every web form accepts it) but offers WebP and PNG where it makes sense. When you need both small size and transparency — say, a signature overlay — WebP is almost always the right answer.

A few practical tips: always start from the highest-quality source you have. Re-compressing an already-compressed JPEG compounds artifacts quickly, so a “20 KB” image re-compressed to “20 KB” again can look noticeably worse than a fresh encode from the original. If your target is a passport photo or other official document, prefer JPEG at quality 70–80 over WebP, since government portals sometimes reject WebP. And if you are not bound by a hard size limit, prefer a quality of around 80 with no resizing — the result will be visually lossless and still far smaller than the source.

Related posts