今日已更新 470 条资讯 | 累计 25550 条内容
关于我们

Compressing an image to exactly 50KB in the browser, with no server

Manoj Pathak 2026年07月29日 20:23 0 次阅读 来源:Dev.to

Indian government exam portals have a rule that has quietly shaped a lot of my code: your photo must be under 50KB . Not "small". Not "optimised". Under 50KB, or the upload is rejected. Every free tool I found for this wanted me to upload the photo to a server, wait in a queue, and create an account. For a file I just wanted to shrink. So I wrote it myself, in the browser. This post is about the actual technique — hitting an exact byte target with canvas — and, honestly, about where my implementation still falls short. The naive version, and why it fails The obvious approach: canvas . toBlob ( blob => download ( blob ), ' image/jpeg ' , 0.7 ); Pick a quality, hope for the best. The problem is that JPEG quality has no predictable relationship to output size. Quality 0.7 on a flat, low-detail portrait might land at 18KB. The same 0.7 on a noisy, high-detail photo lands at 210KB. You cannot compute the quality you need — the encoder decides, and it depends entirely on image content. So you can't calculate it. You have to search for it. Binary search on quality toBlob is cheap enough to call repeatedly, and quality is monotonic — higher quality never produces a smaller file. That's exactly the setup binary search wants. function encode ( canvas , quality ) { return new Promise ( resolve => canvas . toBlob ( resolve , ' image/jpeg ' , quality ) ); } async function compressToTarget ( canvas , targetBytes ) { let lo = 0.05 , hi = 0.95 , best = null ; for ( let i = 0 ; i < 8 ; i ++ ) { const mid = ( lo + hi ) / 2 ; const blob = await encode ( canvas , mid ); if ( blob . size <= targetBytes ) { best = blob ; // fits — remember it, try for better quality lo = mid ; } else { hi = mid ; // too big — back off } } return best ; } Eight iterations over the range 0.05–0.95 narrows quality to about ±0.002, far finer than anyone can see. Each iteration is one encode; on a typical phone photo the whole loop runs in well under a second. Two details that matter more than they look: Keep

本文内容来源于互联网,版权归原作者所有
查看原文