压缩图片转50KB

把一张图压到接近 50KB:先用二分搜索反推 JPEG 质量,找到「不超过目标里最大的那一档」;如果质量已经降到 0.10 还超标,就自动按最长边 0.85 缩小一轮重新搜,最多三轮。打开页面已用合成演示图跑过一遍。

原始体积计算中…
目标体积50.0 KiB
输出体积—
实际质量—
输出尺寸—

正在为合成演示图(480×270,渐变加噪点)按默认设置 50 KiB / 最长边 1600 / JPEG 搜索质量档位…

1600×900 画布上「目标体积 → 每像素可用字节」对照,默认显示 12 行(数值仅作演示)
目标体积可用字节每像素字节 bpp判定
10 KiB102400.007111质量触底仍需降分辨率
20 KiB204800.014222质量触底仍需降分辨率
30 KiB307200.021333质量约 0.10~0.25
40 KiB409600.028444质量约 0.10~0.25
50 KiB512000.035556降质量可达(默认示例)
60 KiB614400.042667质量约 0.25~0.45
75 KiB768000.053333质量约 0.25~0.45
100 KiB1024000.071111质量约 0.45~0.70
150 KiB1536000.106667质量 0.70 以上
200 KiB2048000.142222质量 0.70 以上
300 KiB3072000.213333质量 0.70 以上
500 KiB5120000.355556质量 0.70 以上

使用方法

  1. 点「选择图片」挑一张 PNG / JPEG / WebP / GIF / BMP。不选也能用:页面打开时已经生成了一张 480×270 的合成演示图并跑完了压缩。
  2. 在「目标体积」填你要的 KiB 数,默认示例 50。本页按 1 KiB = 1024 字节处理,所以 50 KiB 等于 51200 字节,比「50 KB = 50000 字节」多 1200 字节。
  3. 「最长边上限」默认 1600 px:先按这个上限等比缩一次,作为后续搜索的固定画布;填 0 表示保持原始像素不缩。
  4. 选「JPEG」或「WebP」。JPEG 兼容性最好,WebP 在同等画质下通常更小。
  5. 点「压到目标体积」。工具先试质量 0.10,如果这一档就已经达标,就用二分搜索往上找「不超过目标里最大的那一档」;如果 0.10 都超标,就按最长边 0.85 缩一轮重来,最多三轮。
  6. 结果区给出原始体积、输出体积、实际质量与输出尺寸,并出现下载按钮;点「导出 CSV」把对照表存成带 BOM 的文件。

这个压缩图片转50KB能解决什么问题

最常见的场景是卡在体积门槛上。很多报名表、论坛、审核后台写的是「单张不超过 50KB」,而你手里的照片动辄两三兆;手动在修图软件里反复调质量既慢又不可复现,本页把「反复试」这一步交给二分搜索,一次点完。

第二个场景是证件与材料上传。这类系统往往同时限制体积与像素尺寸(例如最长边不超过 1600),恰好对应本页的两个核心参数;先设最长边再压体积,顺序正好。

第三个场景是网页与邮件的缩略图。列表页的小图不需要高分辨率,压到几十 KB 既快又省流量;把同一张源图分别跑 20 KiB 与 50 KiB 两档,就能得到两套备选。

这个压缩图片转50KB 不做的事也说清楚:它不做无损压缩(PNG 无损优化属于另一类,省下的比例通常只有个位数);不改图片内容,不裁剪、不旋转、不加水印;不含透明通道保留逻辑——导出 JPEG 时透明区域会被填成黑色,需要保透明请改用 WebP 或先换格式。

原理与规则说明

能不能压到目标体积,先要回答「这份体积预算是多少字节给一个像素」。把目标字节数除以画布像素数就得到 bpp(bytes per pixel)。本页按默认最长边 1600 得到 1600×900 = 1440000 像素;目标 50 KiB = 51200 字节,于是 bpp = 51200 ÷ 1440000 = 0.035556。参照经验值:有损 JPEG 在 bpp 低于 0.02 时几乎一定糊到不可用,0.02 到 0.10 是「只靠降质量就能达成」的区间,高于 0.10 则相当宽松。所以 50 KiB 在 1600×900 上属于「降质量可达」,而 20 KiB 的 bpp 只有 0.014222,已经低于 0.02,必须动分辨率。

质量参数走的是 JPEG 量化表缩放。JPEG 由 ISO/IEC 10918-1(等同 ITU-T T.81)定义,编码时把 8×8 像素块做离散余弦变换,再用量化表把频率系数除以更大的数并取整;画质参数 quality 并不直接等于压缩率,在经典 IJG 实现里先换算成缩放因子再去缩放量化表——quality 低于 50 时因子是 5000 ÷ Q,高于等于 50 时是 200 − 2Q。所以 0.10 对应因子 500.00,0.50 对应 100.00,0.90 对应 20.00,1.00 对应 0(不缩放,等于最精细)。

体积与质量的关系单调但呈阶梯状,不是平滑曲线。浏览器会把质量四舍五入到百分之一档,也就是只有 0.10 到 1.00 之间的 91 个离散档位;同一档位内量化表完全相同,编码出来的字节数一模一样。这带来两个后果:一是不能按比例估算「质量减半、体积减半」;二是搜索结果只要落进某一档,再精细的搜索也不会更小。

因此二分搜索的迭代次数由「档位分辨率」决定,而不是越多越好。区间是 [0.10, 1.00],宽度 0.90:迭代 6 次剩 0.0140625,7 次剩 0.00703125,8 次剩 0.003515625,已经小于档位间距 0.01。本页取 8 次,等价于把 91 个档位二分了约 6.5 层并留出余量;作为对照,按 0.01 步长线性扫完全区间要编码 91 次,二分 8 次只占其 8.79%。

第二段是分辨率回退。当质量降到 0.10 仍然超过目标,说明在现有像素数下体积下限高于预算,只能少存像素。本页按最长边乘 0.85 缩小:边长变 0.85 倍,像素数按平方变成 0.7225 倍,一轮就砍掉 27.75% 的像素。三轮之后边长是 0.85 的三次方 = 0.614125 倍,像素数只剩 0.377150;对 1600×900 来说分别落到 1360×765、1156×650 与 983×553。每缩一轮就重新做一遍完整的 8 次二分,所以最多要编码 4 轮 × 9 次 = 36 次。

格式选择是第三条路。有损 WebP 在同等主观画质下通常比 JPEG 小 25%~35%(业界经验区间,随图片内容波动),代价是极老浏览器打不开;需要最广兼容时选 JPEG,能接受新格式时优先 WebP。

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

默认设置是目标 50 KiB、最长边 1600 px、导出 JPEG,三个值与下方对照表里 50 KiB 那一行、以及页面首屏已跑完的合成演示图一致。

再看一条最坏情况的边界:把目标填成 10 KiB、最长边保持 1600,bpp 只有 0.007111,即使三轮回退到 983×553(bpp 升到 0.094)也不一定够;这时输出的是「三轮之内找到的最小体积」,并明确告诉你差距有多大,而不是假装成功。

输入范围与对照表

目标体积接受 1 到 20480 的整数 KiB;最长边上限接受 0 到 65535 的整数像素,0 表示不缩尺寸;格式只有 JPEG 与 WebP 两个选项。下面这张表把常见目标体积换算成 bpp,基准是本页默认的 1600×900 画布。

体积预算与像素的关系(数值仅作演示)
项目取值说明
体积单位KiB1 KiB = 1024 字节
默认目标50 KiB即 51200 字节
默认最长边1600 px1600×900 = 1440000 像素
质量搜索区间0.10 ~ 1.0091 个离散档位
二分迭代8 次收敛到 0.003515625
分辨率回退×0.85 / 轮最多 3 轮,像素降到 37.72%
单次压缩上限36 次编码4 轮 × 9 次

点「加载更多」把 15 行对照表补全;「导出 CSV」下载带 BOM 的表格文件;「复制对照表」复制成制表符文本。

输入范围、边界与精度说明

每个字段的非法输入都有独立文案。目标体积留空提示「不能留空」、填小数提示「要填整数」、填 0 或负数提示「要在 1 到 20480 之间」、超过上限提示「超出上限 20480」;最长边上限同理,只是区间换成 0 到 65535,并额外说明「0 表示不缩尺寸」。没有选图且合成演示图也被清掉时,会提示「请先点选择图片」,而不是静默不动。

图片解码走两级回落:优先 createImageBitmap(file, { imageOrientation:'from-image' }),它的好处是能顺便按 EXIF 方向把竖拍图摆正;如果这个 API 在当前浏览器不可用或解码失败,就退回 <img> + URL.createObjectURL。两级都失败才报错,文案会带上文件名与判定原因(不是图片类型 / 无法解码 / 文件损坏),并把 blob 的 URL 及时释放掉。

画布面积有一条硬上限:Math.max(w,h) 缩放后如果总像素超过 268435456(约 16384×16384),部分浏览器会拒绝绘制或直接崩溃,本页在绘制前就拦下并提示把最长边上限调小。

「无法达到目标体积」是本页最重要的一条边界。它发生在质量已经降到区间下界 0.10、分辨率也已经回退满三轮之后仍然超标的时候。此时工具不清零、不报错退出,而是输出三轮里体积最小的那一份结果,同时用黄色提示条给出「目标 X KiB / 实际 Y KiB / 差 Z%」三个数,让你判断是接受这个结果还是继续降分辨率。

最后两条误用值得单独说。其一,质量与体积不是线性关系,因为体积是质量的阶梯函数:0.8130 与 0.8199 会被四舍五入到同一档,得到完全相同的字节数,所以不要用「质量降一半、体积也降一半」去心算。其二,反复压缩同一张图不会更省体积——第二次编码只能在已经丢掉的高频系数上重新分配比特,体积基本持平,画质却持续下滑,正确做法是从原图一次性压到目标。

常见问题

为什么结果比 50KB 略大或略小,而不是正好 51200 字节?

因为质量只有 91 个离散档位,输出体积是这个阶梯上的离散点,不可能精确落在任意字节数上。工具的规则是「不超过目标里最大的那一档」,所以结果通常略小于或等于目标;如果所有档位都超标,就进入分辨率回退。

为什么质量已经是最低了还是压不到 50KB?

说明在当前的像素数下体积下限就高于预算。可以看对照表的 bpp 列:低于 0.02 就属于这种情形。解决办法是降分辨率——把最长边上限从 1600 调到 1000 以内,或者填更小的目标体积让工具自动走 0.85 回退。

「50KB」到底是 50000 字节还是 51200 字节?

两种口径都有人用。本页统一按 1 KB = 1024 字节处理,也就是 50 KiB = 51200 字节。如果你的平台按 1000 进制算,两者差 1200 字节(2.4%);填目标时可以稍微留一点余量,比如填 48。

先降质量还是先降分辨率?

本页的顺序是「先降质量、降不动再降分辨率」,因为降质量只损失高频细节,降分辨率丢的是像素本身且不可逆。只有当 bpp 预算低于 0.02 时才必须动分辨率,此时降质量已经到极限。

JPEG 和 WebP 怎么选?

要体积最小选 WebP,同等画质下通常比 JPEG 小 25%~35%;要兼容性好、下游系统只认 JPEG 时选 JPEG。注意导出 JPEG 时透明区域会被填成背景色,有透明通道的 PNG 请改用 WebP。

图片会上传到服务器吗?

不会。文件通过 File 对象在本地解码,缩放与编码都在浏览器 canvas 里完成,导出走 canvas.toBlob() 拿到 Blob;开发者工具的 Network 面板里不会有任何上传请求,页面首屏看到的合成演示图也是本地用 canvas 画出来的。

一次要编码多少次?慢不慢?

质量达标时是 1 次探底加 8 次二分共 9 次;每多一轮分辨率回退再加 9 次,最坏 36 次。每次编码都在主线程上跑,因此大图(超过 400 万像素)会明显感到停顿,建议先把最长边设到 2000 以内。

压完看起来没差别,为什么体积小了一大截?

因为丢的是人眼不敏感的高频细节而不是画面结构。在手机屏幕上看,质量 0.25 与 1.00 常常难以分辨;但放大到 200% 或拿去打印,块状和边缘模糊就会显出来。压缩本质是在「当前观看尺寸」下做的取舍。

相关工具

压缩图片转50KB 只做「按目标体积压缩」这一件事,相邻的尺寸、格式与体积查询各有专门页面。