JPG转WebP转换器

选一张 JPG,这个 JPG转WebP转换器就用 canvas.toBlob 的 image/webp 有损通道按质量参数重新编码,转换前后都给你真实字节数与体积比。页面同时讲清 WebP 的 RIFF 容器、16383 像素边长上限,以及「JPG 有损再转 WebP 有损」会累积的二次损失。全部在浏览器里完成。

未选择图片,下面是默认参数(质量 0.80)下对基准图 1920×1080 的估算:期望 WebP 体积 127.7 KiB,相对该图的 JPG 原体积 371.1 KiB 省 65.6%。
原始尺寸1920×1080(演示值)
原始 JPG 体积371.1 KiB
预期 WebP 体积127.7 KiB
体积比2.91×(演示值)

转换结果会显示在这里。上面这组数字是基准图 1920×1080(JPG 质量 0.92、371.1 KiB)在 WebP 质量 0.80 下的演示值,选出你自己的图片后会换成实测值。

提示:质量框里按 Enter 可以直接重新估算;图片只在本地解码并编码,关闭标签页后不留副本。

使用方法

  1. 点「1. 选择本地图片」挑一张 JPG。PNG、WebP、GIF、BMP 也能读进来,但本页主打的是 JPG 进、WebP 出这条链路。
  2. 载入后结果区立刻显示原始尺寸与原始 JPG 体积,两个值都来自文件本身,不做估算。
  3. 拖动「2. WebP 质量」滑块,范围 0.30~1.00,默认 0.80。也可以在右边的数字框手填,按 Enter 生效。
  4. 松手后大约四分之一秒,结果区会给出这一档质量下的实际 WebP 体积与体积比——那是真的编码了一次,不是查表。
  5. 点「转换并下载 WebP」,浏览器在本地编码后直接下载,文件名形如 converted-1920x1080-q80.webp。
  6. 拿不准质量该取多少,就查下面那张 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.3034,07923,85522,49225,55993.7%
0.4049,94334,96032,96237,45790.8%
0.5073,19151,23448,30654,89386.5%
0.60100,01670,01166,01175,01281.6%
0.65116,91681,84177,16587,68778.5%
0.70136,67295,67090,204102,50474.8%
0.75159,766111,836105,446119,82570.6%
0.80(默认)186,763130,734123,264140,07265.6%
0.90337,543236,280222,778253,15737.8%
0.92379,959265,971250,773284,96930.0%
0.95451,735316,215298,145338,80116.8%
1.00602,737421,916397,806452,05310.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。

相关工具

  • PNG转JPG:反方向的转换,重点在透明背景必须先铺底色,和本页「透明可以保留」正好对照。
  • WebP转JPG:把 WebP 换回兼容性更广的 JPG,遇到不认 WebP 的旧软件时用。
  • 图片尺寸调整:本页的上游,先把像素改小,长边压到 16383 以下再转 WebP。
  • 图片压缩工具:只想减体积、不在意格式时用它,不必先转 WebP。
  • 图片格式转换:多种格式互转的通用入口。
  • 图片转Base64转换器:想看清 base64 会把体积撑大 33.33% 的过程,用这一页。
  • 图片工具:查看全部图片工具。