使用方法
- 点「1. 选择本地图片」挑一张 JPG。PNG、WebP、GIF、BMP 也能读进来,但本页主打的是 JPG 进、WebP 出这条链路。
- 载入后结果区立刻显示原始尺寸与原始 JPG 体积,两个值都来自文件本身,不做估算。
- 拖动「2. WebP 质量」滑块,范围 0.30~1.00,默认 0.80。也可以在右边的数字框手填,按 Enter 生效。
- 松手后大约四分之一秒,结果区会给出这一档质量下的实际 WebP 体积与体积比——那是真的编码了一次,不是查表。
- 点「转换并下载 WebP」,浏览器在本地编码后直接下载,文件名形如
converted-1920x1080-q80.webp。 - 拿不准质量该取多少,就查下面那张 12 行对照表:它给出 1920×1080 基准图在各档质量下的 WebP 期望字节数与上下界。
JPG转WebP转换器能解决什么问题
一是把老图换成更小的 WebP。Google 官方口径是同质量下 WebP 比 JPEG 小 25%~34%,实测本页基准图在质量 0.80 时从 371.1 KiB 降到 127.7 KiB,省 65.6%。网站图片体积直接换成加载时间,这一档差距值得转。
二是给「已经是 JPG 的素材」做一次收口。设计稿导出的、从别处下载的、历史遗留的 JPG 往往带着很高的质量值(0.92 甚至更高),体积远大于实际需要。用本页把它们统一收到 0.80,视觉上很难看出差别,体积却能掉一半以上。
三是在动手前就看清代价。JPG 和 WebP 有损都走「量化 + 熵编码」,第二次量化会把第一次的误差再放大一次。本页把「输入已经是有损的」这件事写在流程里:它不会假装转完是「无损优化」,而是明确告诉你这是有损转有损。
四是保留透明通道。JPG 没有 alpha,但如果你随手丢了张带透明的 PNG 进来,WebP 能把透明区原样保住——因为有损 WebP 把 alpha 放进独立的 ALPH 块,用无损方式压缩,边缘不会像 PNG转JPG 那样必须铺底色。
本页不做的事:不做批量转换(编码是 CPU 密集操作,而且每张图合适的质量并不相同),不做尺寸缩放(要边转边缩请先用尺寸调整工具),也不做无损 WebP——canvas 只暴露有损通道,真要无损得用桌面端的 cwebp 加 -lossless。
原理:canvas.toBlob 的 image/webp 通道与 RIFF 容器
编码只调一个方法。canvas.toBlob(callback, 'image/webp', quality)——第一个参数是回调,第二个是 MIME 类型,第三个是 0 到 1 的质量。它返回一个 Blob,直接拿到二进制,不需要 toDataURL() 那条 base64 路线。这个选择很关键:toDataURL() 会把二进制膨胀 33.33%,一张 130,734 字节的 WebP 会变成约 174,312 个字符,大图足以把主线程卡住;而 toBlob 是异步的,编码在后台完成。
WebP 由 RFC 9649 定义,容器是 RIFF。IETF 在 2024 年 11 月把 WebP 正式发布为 RFC 9649(信息类)。它沿用 WAV 音频那套 RIFF 分块结构,文件开头的魔数是 52 49 46 46 xx xx xx xx 57 45 42 50,也就是 RIFF + 四字节文件长度 + WEBP。简单有损文件的固定开销只有 20 字节:RIFF 头 12 字节,加上 VP8 数据块的 8 字节块头。也就是说一张 1×1 像素的 WebP 大约是 30 字节(再算上 VP8 帧头),容器本身几乎不占体积。
两个压缩引擎,canvas 只用其中一个。有损数据走 VP8 帧内编码:把画面切成宏块,用上方与左侧的已编码块做预测,再把残差放进 4×4 子块做 DCT 或 Walsh–Hadamard 变换,色度按 YCbCr 4:2:0 抽样,色深 8 位。无损数据走 VP8L,是另一套算法,用预测变换、颜色缓存和 LZ77 式反向引用,与 VP8 无关。浏览器给 canvas 暴露的只有 VP8 这条有损路径——质量填 1.00 也还是在 VP8 里跑,量化表被压到最小值 1,但系数取整与 8 位回落照样发生,所以 canvas 出不了无损 WebP。
质量参数改的是量化步长。质量值越高,量化表里的步长越小,被丢弃的高频细节越少,体积越大。本页基准图在质量 0.30 时 WebP 约 23,855 字节,0.80 时 130,734 字节,1.00 时涨到 421,916 字节——同样一张图,仅质量一项就是 17.7 倍的体积跨度。这也是默认取 0.80 的理由:从 0.80 走到 1.00,体积涨了 3.2 倍,画面上的差别却要看放大才能分辨;而 0.80 相对 0.50,体积只涨 1.55 倍,观感改善更明显。
有损转有损是在叠加误差。JPG 已经经历过一次 RGB 到 YCbCr 转换、一次 4:2:0 抽样、一次 8×8 DCT 量化。转 WebP 时这些步骤要再做一遍,等于对已经带误差的像素再量化一次。误差不会互相抵消,只会累积:假设单次质量 0.80 的保真度损失约 1.5%,连做五次后累计损失升到约 7.3%。所以正确的做法是「从原始素材转一次就定稿」,而不是「先在 JPG 里压一轮,再转 WebP,不满意再压一轮」。
alpha 在有损 WebP 里是被单独保护的。RFC 9649 的扩展格式把透明通道放在独立的 ALPH 块里,这个块本身用无损方式压缩,颜色数据才走 VP8 有损。结果是「照片部分可以掉画质,透明边缘依然锐利」——这正是 PNG 与 JPEG 都做不到的组合。如果你输入的是带透明的 PNG,本页不需要铺底色,透明区会原样保留。
完整示例(数值仅作演示)
页面打开时的默认条件是:WebP 质量 0.80、尺寸不变。输入侧基准图是一张 1920×1080 的 JPG,质量 0.92、379,959 字节(≈371.1 KiB)。下面这组数字按「WebP / JPEG 中位比 0.70」建模,依据是 Google 官方公布的「同质量下 WebP 比 JPEG 小 25%~34%」。
- 默认档质量 0.80:WebP 期望 130,734 字节 ≈ 127.7 KiB,相对原始 JPG 省 65.6%,压缩比 2.91×;
- 把质量压到 0.30:WebP 期望 23,855 字节,是原始 JPG 的 6.3%,画面会出现明显块状锯齿;
- 把质量顶到 1.00:WebP 期望 421,916 字节,比 0.80 档大了 3.2 倍,但仍然是有损结果;
- 同一档质量下 WebP 体积的合理区间:0.80 时是 123,264(比 JPEG 小 34%)到 140,072 字节(小 25%);
- 1920×1080 的像素数是 2,073,600;按 YCbCr 4:2:0 每像素 1.5 字节算,未压缩数据是 3,110,400 字节,也就是默认 WebP 只用了原始数据的 4.2%;
- 容器固定开销 20 字节,占默认 WebP 体积的 0.015%——可以忽略。
再看一个尺寸边界的例子:WebP 的边长上限是 16383 像素。一张 1920×1080 远没到线,但如果你有一张 20000×10000 的拼接长图,直接转会在编码阶段失败——必须先用尺寸调整工具把长边压到 16383 以下。注意 canvas 自己的单边上限是 65535,比 WebP 宽得多,所以「canvas 装得下但 WebP 编不出来」这种情况是真实存在的。
输入范围与体积对照表
下表是 1920×1080 基准图在 12 档质量下的体积。第二列是 JPG 侧基准(来自同批 PNG转JPG 页的实测曲线),第三列是本页的 WebP 期望值,后两列给出 25%~34% 这段浮动区间,最后一列是相对质量 0.92 原始 JPG 的节省比例。
| WebP 质量 | JPG 基准(字节) | WebP 期望(字节) | 下界(小 34%) | 上界(小 25%) | 相对原始 JPG 节省 |
|---|---|---|---|---|---|
| 0.30 | 34,079 | 23,855 | 22,492 | 25,559 | 93.7% |
| 0.40 | 49,943 | 34,960 | 32,962 | 37,457 | 90.8% |
| 0.50 | 73,191 | 51,234 | 48,306 | 54,893 | 86.5% |
| 0.60 | 100,016 | 70,011 | 66,011 | 75,012 | 81.6% |
| 0.65 | 116,916 | 81,841 | 77,165 | 87,687 | 78.5% |
| 0.70 | 136,672 | 95,670 | 90,204 | 102,504 | 74.8% |
| 0.75 | 159,766 | 111,836 | 105,446 | 119,825 | 70.6% |
| 0.80(默认) | 186,763 | 130,734 | 123,264 | 140,072 | 65.6% |
| 0.90 | 337,543 | 236,280 | 222,778 | 253,157 | 37.8% |
| 0.92 | 379,959 | 265,971 | 250,773 | 284,969 | 30.0% |
| 0.95 | 451,735 | 316,215 | 298,145 | 338,801 | 16.8% |
| 1.00 | 602,737 | 421,916 | 397,806 | 452,053 | 10.9% |
点「加载更多行」补上 0.35、0.45、0.55、0.85 四个中间档;点「导出 CSV」把当前整张表存成带 BOM 的 CSV(Excel 打开不乱码),点「复制对照表」复制成制表符分隔的文本,可直接粘进表格软件。
边界与精度说明
- WebP 边长上限 16383 像素。这是 RFC 9649 规定的硬上限,超过时编码直接失败,且多数浏览器不会抛异常、只给一张空图。canvas 自己的单边上限是 65535、总面积上限 268,435,456 像素(约 16384×16384),比 WebP 宽,所以这个 JPG转WebP转换器必须在编码前单独校验 WebP 这一条。
- 质量只接受 0.30~1.00。HTML 规范规定,传给
toBlob的 quality 只要不在 0.0~1.0 之间,就按 UA 默认值处理(Chromium 是 0.92)。填 0 和填 1.5 都会被静默改成 0.92,本页因此直接拦下并说明原因,而不是让你以为参数生效了。 - 质量的物理分辨率是 0.01。编码器把质量取整成百分数档位,0.795、0.799、0.8001、0.804 都会落到同一档,量化表完全相同、输出字节数一模一样。滑块步长设 0.01 已经覆盖全部可用档位。
- canvas 只有有损 WebP。不管质量填多少,走的都是 VP8 有损通道。要真正的无损 WebP 必须用
cwebp -lossless或浏览器新的 ImageEncoder 接口,两者都不是本页能提供的。 - 二次压缩不可逆。输入是 JPG 就意味着它已经被量化过一次。本页转出的 WebP 是在这次量化的结果上再量化一次,误差叠加而不是抵消。反复转同一张图会持续掉画质,且没有算法能还原。
- 色度按 4:2:0 抽样。Cb、Cr 各缩到一半宽高,色度数据只有亮度的四分之一,整体折合每像素 1.5 字节。细红线、小字、高频色差会出现可见损失;纯灰度图不受影响,因为它本来就不带色度。
- 输出不含 EXIF。canvas 出来的是纯像素位图,相机的型号、镜头、光圈、快门、拍摄时间和 GPS 都不会带过去,方向标记也一并消失(方向已在解码阶段应用,画面是正的)。对在意隐私的人是好事。
- 解码走两层兜底。优先用
createImageBitmap(file, { imageOrientation: 'from-image' }),它按 EXIF 把方向摆正;失败时回落到new Image()加URL.createObjectURL。两条路径都能解码,差别是回落路径在某些内核上不处理方向标记。
常见问题
转成 WebP 一定更小吗?
不一定。如果源图本来就是极度压缩的小尺寸 JPG,或者画面是纯色截图、线框图,JPEG 的熵编码对这类内容效率很高,换 WebP 后可能只小几个百分点甚至持平。WebP 的体积优势在「同质量下的连续色调照片」上最明显,Google 给出的口径是 25%~34%;对已经压到极限的小图,别再压第二遍。
质量填 1.00 是不是就是无损?
不是。canvas 只实现了 VP8 有损通道,质量 1.00 只是把量化步长压到最小值 1,DCT 系数照样要四舍五入取整、像素照样要落回 8 位整数,这两步都不可逆。要无损 WebP 请用桌面端的 cwebp -lossless,它走的是完全不同的 VP8L 引擎。同一张图在 canvas 里质量 1.00 仍会有约 421,916 字节的体积,这本身就说明它不是无损。
JPG 转 WebP 会不会掉两次画质?
会。JPG 本身已经过一次 8×8 DCT 量化与 4:2:0 抽样,转 WebP 时这些操作要再做一遍,误差叠加而不是抵消。这个 JPG转WebP转换器的定位就是「有损转有损」,界面上不把它说成无损优化。想减少损失,正确的做法是从原始素材(RAW、PNG、TIFF)直接转 WebP,绕开 JPG 这一步。
带透明的 PNG 转成 WebP 会丢透明吗?
不会。WebP 在扩展格式里把 alpha 放进独立的 ALPH 块,这个块用无损方式压缩,颜色数据才走 VP8 有损。所以透明边缘会保持锐利,照片部分可以掉画质。这和 PNG转JPG 完全不同——JPEG 没有 alpha 平面,那一页必须先铺一层底色。
为什么质量 0.80 是默认值?
因为它是体积与观感的性价比拐点。看对照表:从 0.50 提到 0.80,体积从 51,234 涨到 130,734 字节(1.55 倍),画面清晰度提升明显;从 0.80 提到 1.00,体积从 130,734 涨到 421,916 字节(3.2 倍),多出来的体积买到的画质提升却要放大才看得出来。默认给 0.80,是要把预算花在看得见的地方。
图片会上传到服务器吗?
不会。文件通过 File 对象在本地解码,编码走 canvas.toBlob('image/webp', 质量),导出用 URL.createObjectURL 触发下载。想自己确认,打开开发者工具的网络面板,选一张 JPG 再点转换,全程不会有任何新的图片上传请求。
转出来的 WebP 在旧软件里打不开怎么办?
这是 WebP 目前唯一的结构性短板:浏览器支持率很高,但部分旧版桌面软件、旧版 Office、某些上传表单仍不认 .webp。遇到这种情况有两个选择——留在 JPG(本页不做这件事,可用图片压缩工具直接压 JPG),或者用 WebP转JPG 把文件转回去。给「只在网页上用」的素材转 WebP 是安全的,给「要交给第三方系统」的素材就要先确认对方支持。
为什么有些图转完体积反而变大了?
三种情况最常见。一是源图色块极大、颜色极少,JPEG 能把它压到几十字节,而 WebP 有损对这类画面效率不占优;二是源图质量极低(比如 0.30)本来就很小,再转一次等于重新走一遍完整编码,容器开销反而显出来;三是输入其实是无损 PNG,转成有损 WebP 时把无损信息换成了量化数据。遇到前两种,建议保留 JPG。