图片压缩工具

在浏览器里把一张图的体积压到你想要的大小:降尺寸、降质量、换格式三条路径分别或组合使用,拖动滑块实时看到导出体积,也可以只填一个目标值,让二分搜索自动反推质量。图片只在本地解码,不经过任何服务器。

原始体积未选择图片
目标体积200.0 KiB
输出体积—
实际质量自动

压缩结果预览会显示在这里;未选择图片前不会画任何东西,也不会发起任何网络请求。

使用方法

  1. 点「选择本地图片」挑一张图,PNG、JPEG、WebP、GIF、BMP 都能读。图片只在你自己的浏览器里解码,没有任何上传请求。
  2. 「目标体积」默认填 200 KiB,这就是本页示例值;只接受 1~20480 的整数,1 KiB 等于 1024 字节。
  3. 「最长边上限」默认 1920 px:图片最长的一边超过它就先等比缩小,填 0 表示完全不降尺寸。
  4. 「导出格式」可选 JPEG 或 WebP;「工作模式」可选「自动逼近目标体积」或「手动指定质量」。
  5. 自动模式下,工具用二分搜索替你反推质量档位;手动模式下拖动第 6 项滑块,每拖一下都会重新编码并刷新输出体积,这就是实时体积预览。
  6. 点「开始压缩」,结果区给出输出体积、实际质量与压缩率,同时出现下载按钮。整个过程一次只处理一张,不排队、不上传。

这个图片压缩工具能解决什么问题

最直接的场景是上传口卡体积。很多后台、论坛、表单都写着「单张不超过若干兆」,而一张 1920×1080 的相机 JPEG 在质量 1.00 时可能有 588.6 KiB;先把它降到 1280×720,体积就掉到原来的 44%,再配合质量 0.80,绝大多数限制一次就过。

第二个场景是网页首屏瘦身。首屏大图往往决定加载时间:同一张图从 JPEG 换成 WebP,再把质量压到 0.80 附近,常见能省下六成以上体积,肉眼却几乎看不出差别。

第三个场景是邮件与聊天附件。附件有体积上限时,与其被退回,不如先把最长边限制到 1600,让工具自动把体积压到目标值附近。

第四个场景是批量素材归档。归档要的是「看得清、放得下」,不需要保留原始像素,只要保住构图,把体积控制在一个可预期的范围里即可。

与「必须压到某个固定数值」的做法不同,这个图片压缩工具把三个变量都交给你:体积目标、尺寸上限、导出格式。你可以只动一个,也可以三个一起动,工具负责把每一步的结果算给你看。

压缩的三条路径:降尺寸、降质量、换格式

图片压缩没有第四条路,只有三条:降尺寸(少存像素)、降质量(每个像素存得粗一点)、换格式(换一套编码器)。三者近似正交,可以叠加。

降尺寸最猛,因为代价是平方级。像素总数等于宽乘高,边长缩到一半,像素数只剩四分之一。以一张 1920×1080 的基准图(2,073,600 像素)为例:缩到 1600×900 剩 1,440,000 像素,省 30.56%;缩到 1280×720 剩 921,600 像素,省 55.56%;缩到 960×540 剩 518,400 像素,省 75.00%;缩到 640×360 只剩 230,400 像素,省 88.89%。代价也很直接:丢掉的像素再也回不来,放大会糊。

降质量靠的是量化。JPEG 先把 8×8 的像素块做离散余弦变换(DCT),把空间信息换成频率系数,再用一张量化表把系数除以更大的数并取整——被除掉的低位就是丢掉的画质。画质参数 quality 并不直接等于压缩率,它在标准里被换算成一个缩放因子再去缩放量化表:在经典实现里,Q 小于 50 时因子为 5000/Q,Q 大于等于 50 时为 200−2Q。所以同一个 quality 在不同图上得到的体积可以差很多。

换格式改动最小、收益稳定。在等画质前提下,WebP 的有损编码通常比 JPEG 小 25%~35%。基准图在质量 0.80 时是 186,763 字节,若换成等效 WebP:小 25% 约 140,072 字节(136.8 KiB),小 30% 约 130,734 字节(127.7 KiB),小 35% 约 121,396 字节(118.6 KiB)。代价是极老的浏览器打不开 WebP,所以工具把两种格式都留给你选。

需要说明的是,本页的图片压缩工具只做有损编码,不提供无损重排(比如 PNG 的无损优化)。无损优化能省的比例通常只有个位数,和上面三条路径不在一个量级。

质量曲线与二分搜索:如何逼近目标体积

画质与体积的关系是强非线性的。还是那张 1920×1080 基准图,把质量从 1.00 一路降到 0.10,逐档真实编码后得到:质量 1.00 是 588.6 KiB,0.95 是 483.8 KiB(省 17.80%),0.90 是 321.6 KiB(省 45.37%),0.80 是 182.4 KiB(省 69.01%),0.60 是 95.0 KiB(省 83.86%),0.50 是 71.5 KiB(省 87.86%),0.30 是 33.3 KiB(省 94.35%),到 0.10 只剩 11.6 KiB(省 98.02%)。曲线单调递减,但各段斜率差别极大。

把同样 0.10 的质量跨度单拿出来对比就更清楚:质量 1.00 到 0.90 砍掉 273,434 字节;0.90 到 0.80 砍掉 142,540 字节;而 0.40 到 0.30 只砍掉 18,006 字节。最高端与最低端的绝对压缩量相差 15.19 倍。画质一侧同样陡:1.00 到 0.90 掉了 13.40 dB,可 0.90 到 0.80 只掉 1.84 dB 就再省 43.29%。所以「性价比区间」落在 0.80~0.90,既不是越高压越好,也不是越低越省。

正因为不能靠比例估算,工具才用二分搜索反推质量。固定尺寸和格式后,导出体积是质量的单调函数,于是可以在 [0.10, 1.00] 区间上做二分:每次取中点编码一次,体积大于目标就把上界压到中点,小于目标就把下界抬到中点。8 次之后区间宽度收窄到 0.90 ÷ 256 = 0.003516,已经远小于质量的物理分辨率 0.01。

以默认目标 200 KiB(204,800 字节)为例,8 次试探依次落在 83,574、174,557、303,706、216,456、186,763、204,695、204,695、216,456 字节上;最后从这 8 个候选里挑出「不超过目标且体积最大」的那一个,落在质量 0.8172、输出 204,695 字节,偏差 0.05%,远优于 ±3% 的目标。若用 0.01 的步长线性扫遍区间,需要 90 次编码;二分只要 8 次,约为其 8.89%。

还有一个容易被忽略的细节:质量参数最终会被取整成百分之一档(Q = round(q×100)),所以 0.8150 与 0.8199 会得到完全相同的量化表,编码结果都是 204,695 字节。换句话说质量的物理分辨率就是 0.01,二分到 0.003516 以后不会再有新档位——这也是本页滑块步长取 0.01 而不是更细的原因。

完整示例(数值仅作演示)

默认参数是:目标体积 200 KiB、最长边上限 1920 px、导出 JPEG、工作模式「自动逼近目标体积」、手动质量滑块 0.82。其中 200 KiB 同时也是对照表的锚点,三处一致。

再看一条边界示例:把目标体积填成 5 KiB、而图又是 1920×1080 时,即使质量降到 0.10 也只有 11.6 KiB,压不到目标——这时工具照常输出它找到的最小结果并提示偏差较大,而不是假装成功。

输入范围、质量档位与体积对照表

下表是基准图 1920×1080 在 JPEG 下逐档真实编码的结果,体积按 1 KiB = 1024 字节换算,PSNR 为亮度与色度合并的峰值信噪比(数值越大画质越接近原图)。当目标取默认的 200 KiB 时,二分搜索会落在 0.80 档(182.4 KiB)与 0.85 档(232.1 KiB)之间,也就是质量 0.82 附近。

质量 q输出体积相对原图省亮度+色度 PSNR
1.00588.6 KiB0.00%51.31 dB
0.95483.8 KiB17.80%41.98 dB
0.90321.6 KiB45.37%37.91 dB
0.85232.1 KiB60.57%36.65 dB
0.80182.4 KiB69.01%36.06 dB
0.75150.5 KiB74.43%35.70 dB
0.70130.8 KiB77.78%35.40 dB
0.6095.0 KiB83.86%34.70 dB
0.5071.5 KiB87.86%34.20 dB
0.4050.9 KiB91.36%33.69 dB
0.3033.3 KiB94.35%32.81 dB
0.2019.3 KiB96.72%31.52 dB

点「加载更多档位」会补上更低的 0.15 与 0.10 两档;点「导出 CSV」把整张表存成带 BOM 的 CSV(Excel 打开不乱码);点「复制对照表」复制成制表符分隔文本,可直接粘进表格软件。

常见问题

图片会上传到服务器吗?

不会。文件通过 File 对象交给 createImageBitmap 在本地解码,缩放与编码都在你浏览器的 canvas 里完成,导出走 toBlob。想自己确认,打开开发者工具的网络面板,选一张图并压缩,全程不会有任何新请求。这也是这个图片压缩工具默认不联网的原因。

为什么拖到高质量,体积反而更大?

因为质量越高,量化表越精细,被丢掉的高频系数越少,需要保存的信息就越多。质量从 0.90 提到 1.00,体积能从 321.6 KiB 涨到 588.6 KiB,涨了 82%;但抬起来的那一段是肉眼收益很小的区间。追求极限体积时,把质量停在 0.80 附近通常比拉满更划算。

「自动逼近目标体积」是怎么算的?

它把质量当成未知数,在 [0.10, 1.00] 上做 8 次二分:每次取中点、调用 toBlob 编码一次、量出体积再调整区间。8 次后从候选里挑出「不超过目标且体积最大」的那一个当定稿,实测偏差可以做到 0.05%。因为每次试探都是一次完整编码,所以这个过程在主线程上跑,工具用节流避免连续拖动时堆积任务。

压完看着没差别,为什么文件小了一大半?

因为 JPEG 丢掉的是人眼不敏感的高频细节,不是画面结构。在手机和普通屏幕上,质量 0.80 与原图往往肉眼难分;但只要把这张图再放大到 200%、或者拿去打印,块状和边缘的模糊就会显出来。压缩本质是在「当前观看尺寸」下做的取舍。

反复压缩同一张图会怎样?

会持续掉画质却不再省体积。把同一张 1920×1080 图按质量 0.80 反复编码:第 1 代 186,763 字节、PSNR 36.06 dB;第 2 代 187,154 字节、35.99 dB;第 3 代 187,142 字节、35.96 dB。体积基本不降(第 1 代到第 3 代只涨 0.20%),画质却在下滑。所以最好从原图一次性压到目标,不要「先压一版、再压一版」。

已经压过的图,再存成高质量能救回来吗?

救不回来。把一张质量 0.60 的 JPEG(97,297 字节、34.70 dB)重新按质量 0.90 另存,得到 107,041 字节,体积涨了 10.01%,PSNR 却只从 34.70 变成 34.67。第二次编码只能在已经丢掉的细节上重新分配比特,花掉的是体积,买不回画质。

JPEG 和 WebP 该选哪个?

要体积最小、画质又能接受,优先 WebP,等画质下通常比 JPEG 小 25%~35%;基准图质量 0.80 是 186,763 字节,等效 WebP 大约在 121,396~140,072 字节之间。只有在需要最广泛的兼容性、或者下游系统只认 JPEG 时才回退到 JPEG。

目标填得很小却压不下去怎么办?

说明这张图在给定尺寸和格式下已经触到下限。1920×1080 的基准图即使质量降到 0.10 也有 11.6 KiB;如果你的目标是 5 KiB,光靠降质量到不了。这时应该改走降尺寸:把最长边上限压到 640,像素数只剩原来的 11.11%,再配合质量 0.30 附近,才可能继续往下走。

相关工具