☰
浏览器导出JPEG,质量参数其实只有101档
2026/10/1 6:50:41 网站建设 项目流程

前端做「上传前把图压到指定大小」时常见的写法是对导出质量做二分,也就是 canvas 的quality参数。这轮我在测二分法要找到多精确时顺手把 JPEG 的质量从 0.950 到 0.970 一格一格试了一遍。0.955、0.959、0.960、0.961、0.964 这五个值编出来的文件都是 362 299 字节。一个字节都不差;二分要是把精度收到 0.001,后面几次编码其实是在反复生成同一个文件。这组数据的样本是一张文字加界面的 1440×2400 截图。截图样本我用的是图映 ImgIng(一个在线的免费图片处理工具)PNG 压缩说明页的整页截图。机器是一台 Apple M4 / 16 GB 的 Mac。浏览器用的是 Chromium 149 开源构建;JPEG 走它内置的 libjpeg-turbo,WebP 走内置的 libwebp。

0.950 和 0.951 出来都是 336 289 字节。0.955 到 0.964 这五个值都是 362 299 字节。0.965、0.969、0.970 三个又是同一个文件(393 304 字节)。从实测看浏览器像是把 0 到 1 的小数乘 100、四舍五入成整数再交给 libjpeg。0.951 还算 95 档,0.955 已经算成 96 档。这是我从字节数反推出来的,Chromium 里具体是哪一行做的取整我没去翻。这个行为我不意外:我以前在音视频 SDK 公司做了三年编解码。libjpeg 的质量接口本身就收整数。它拿这个整数去缩放量化表,小数根本进不去。浏览器给 JS 的却是 0 到 1 的浮点参数,中间总得有人把它变成整数。这么算下来 JPEG 的质量最多只有 0 到 100 共 101 个取值。两端的 0 和 1 会不会被夹成同一档我没测。0.955 这种正好压在 .5 上的数在浮点里往哪边走我也没拆。

这张图是复现页跑完的字节表,要看的是 JPEG 那一列。同一个字节数连着出现好几行,每一段正好对应一个整数档。WebP 那一列在 0.960 和 0.961 之间就变了,两列放在一起对比最直观。截图是单次运行的结果。

换成 WebP 就不一样。同一张截图在 0.960 是 193 098 字节,0.961 是 195 376 字节。0.964 又变成 197 578 字节。它的质量参数能吃进小数。不过它也有几段是平的:0.955 到 0.960 三个值输出一样大,0.969 和 0.970 也一样。真正要小心的是顶端。WebP 在 0.999 时是 222 292 字节,到 1.0 一下跳到 771 126 字节(前者的 3.5 倍)。我把 1.0 编出来的文件解码回来和源图逐个对过:13 824 000 个通道值差异为 0。说明那一档已经切成无损了。JPEG 的顶端也有台阶:0.99 是 512 151 字节,0.995 却已经被算成 100 档,和 1.0 一样是 791 712 字节。

搞清楚取整之后二分的写法就好定了。我拿一张系统自带的风景照(3840×2160)压 JPEG 到 2MB 做对比。质量取小数的浮点二分一直找到区间小于 0.01 才停,一共编了 8 次、用了 259 ms,最后停在质量 0.962。质量只取整数的二分编了 6 次、用了 189 ms,停在质量 96。两个结果是同一个文件,都只用掉了额度的 96.7%。多出来的两次编码只是在同一个整数档里来回。WebP 的浮点二分偶尔能多挤出一点。拿程序生成的 24MP 仿照片图压 WebP 到 2MB,浮点二分找到的文件能用掉额度的 99.7%,整数二分是 95.8%。代价是这张图用 WebP 编一次的中位数接近 1 秒。多编两次用户就多等两秒左右。为了这点额度多等不值得。我跑下来觉得整数二分对 WebP 也够用。

上限反而要单独处理。限制很松时整数二分会一路走到 100。那张截图压成 2MB 以内的 WebP 时,整数二分就停在了 1.0,拿到一个 753 KB 的无损文件;浮点二分停在 0.995,只有 217 KB。上限我会封在 0.99。另一个办法是先比一下原图,已经小于目标就不重编。

图映的压缩界面给的是 30 到 100 的整数质量滑杆,按内容推荐的质量值也都是整数。这块编码归我管。整数刻度跟编码器实际能分辨的档位是对得上的。

想在自己的浏览器里验证取整,可以打开浏览器控制台,找一张图画到 canvas 上再调 toBlob 导出。在 0.95 附近按 0.001 的间隔编十来次并把每次的 blob.size 打出来。打出来的 JPEG 字节数会一段一段地重复。如果你的二分还在取两个小数的中点,就先改成整数再二分,编过的整数档直接复用结果。上限封在 0.99,WebP 那一档无损大文件就不会冒出来。以上只在 Chromium 149 上验证过。别的浏览器怎么取整我手上没有数据。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询