批量转换图片为 WebP 格式的几种实用方案

批量转换图片为 WebP 格式的几种实用方案
周言志WebP 是 Google 推出的一种现代图片格式,在同等画质下体积比 JPEG 小 25%-35%,比 PNG 小得更多。对于博客网站和前端项目来说,全量切到 WebP 能显著减少页面加载时间。
为什么要用 WebP
在介绍方案之前,先简单说说为什么值得花时间做这件事:
| 对比项 | PNG | JPEG | WebP |
|---|---|---|---|
| 无损压缩 | 支持 | 不支持 | 支持,比 PNG 小 26% |
| 有损压缩 | — | 基准 | 比 JPEG 小 25-35% |
| 透明度 | 支持 | 不支持 | 支持 |
| 动图 | — | — | 支持(替代 GIF) |
根据 Google 的官方数据,WebP 无损图片比 PNG 体积小 26%,有损图片比同等 SSIM 质量的 JPEG 小 25-35%。对于流量来自移动端的场景,省下来的每一 KB 都在加快首屏速度。
浏览器兼容性方面,主流现代浏览器(Chrome、Firefox、Edge、Safari 14+)都已原生支持 WebP。如果你需要兼容老旧浏览器,可以用 <picture> 标签做降级兜底:
1 | <picture> |
这行代码不会增加太多维护成本,但对用户体验的提升是实打实的。
方案一:使用 cwebp(Google 官方工具)
cwebp 是 Google 提供的 WebP 编码器,也是性能最好、控制最细的方案。
安装
macOS:
1 | brew install webp |
Ubuntu/Debian:
1 | sudo apt install webp |
Windows(用 Scoop):
1 | scoop install webp |
单文件转换
1 | cwebp -q 80 input.png -o output.webp |
-q 80 是质量参数(0-100),80 通常是在画质和体积之间比较好的平衡点。
批量转换
用一行 find 配合 xargs 就能处理整个目录:
1 | # 将当前目录下所有 PNG/JPEG 转换为 WebP |
这个命令会遍历当前目录及其子目录下的所有图片,为每张图片生成一个同名的 .webp 文件。
如果你只想处理单层目录,用 for 循环更直观:
1 | for img in *.png *.jpg *.jpeg; do |
保留目录结构批量转换
如果你想把源文件放在 images/,输出到 webp_output/ 并保持相同的目录结构:
1 | find images/ -type f \( -name "*.png" -o -name "*.jpg" -o -name "*.jpeg" \) | while read -r file; do |
方案二:使用 ImageMagick
如果你已经在用 ImageMagick 处理图片,它内置的 WebP 支持足够应对大多数场景,值得优先考虑。
安装
macOS:
1 | brew install imagemagick |
Ubuntu/Debian:
1 | sudo apt install imagemagick |
批量转换
1 | mogrify -path ./webp_output -format webp -quality 80 *.png *.jpg |
mogrify 是 ImageMagick 的批量处理命令,-path 指定输出目录(会自动创建),-format 指定输出格式。
如果需要递归处理子目录,配合 find:
1 | find . -type f \( -name "*.png" -o -name "*.jpg" \) -exec \ |
ImageMagick 的优势在于你可以在转换的同时做其他处理——调整尺寸、裁剪、加水印:
1 | mogrify -path ./webp_output -resize 1920x1080 -quality 80 -format webp *.jpg |
方案三:使用 Squoosh CLI(Google 出品,Web 版命令行)
Squoosh 是 Google Chrome Labs 推出的图片压缩工具,它的 CLI 版本适合 Node.js 生态的开发者。
安装
1 | npm install -g @squoosh/cli |
批量转换
1 | squoosh-cli --webp '{"quality":80}' *.png *.jpg --output-dir ./webp_output |
Squoosh 的好处是编码器参数通过 JSON 传递,非常灵活。它还支持 AVIF、JPEG XL 等新一代格式,未来迁移很方便。
方案四:用 Node.js + Sharp 写脚本
如果你的项目已经用 Node.js,用 sharp 库写一个批量转换脚本是最灵活的方式——可以精确控制输出路径、添加日志处理、与 CI/CD 流程集成。
安装依赖
1 | npm install sharp glob |
批量转换脚本
创建一个 convert-to-webp.mjs 文件:
1 | import sharp from 'sharp'; |
运行:
1 | node convert-to-webp.mjs |
脚本会输出类似下面的日志:
1 | ✓ hero.png 120.5KB → 32.1KB |
如果你想把这个流程加到 GitHub Actions 里也很容易,就是在构建前跑一遍脚本的事。
方案五:macOS 用户的神器——sips + ImageMagick
macOS 自带 sips(Scriptable Image Processing System),可以配合 cwebp 做迂回转换。如果你不想装太多东西,这个组合够用:
1 | # 批量将 PNG 转为 WebP(需 brew install webp) |
sips 能转换大部分常见格式,但原生不支持输出 WebP,所以这里用了一个迂回策略:先用 sips 转成 JPEG,再用 cwebp 编码成 WebP。
避坑指南
1. 处理后的文件比原文件大?
WebP 对照片类图片压缩效果最好,但对某些简单图形、截图、扁平色块的 PNG,WebP 无损模式的文件体积可能反而比原文件大。遇到这种情况,可以尝试有损模式或者保持原格式。
2. 不要删除原始文件
建议转换完成后统一清理,而不是转换时直接覆盖。万一对质量不满意,还能用原图重新压。
3. 质量参数选择建议
| 场景 | 推荐质量 |
|---|---|
| 产品图、照片 | -q 80 ~ -q 85 |
| 图标、UI 元素 | -q 90 ~ -q 95(或无损) |
| 缩略图、背景图 | -q 60 ~ -q 70 |
| 存档、无损需求 | -lossless |
4. 文件命名冲突
如果源文件有 photo.jpg 和 photo.png,转换后都会变成 photo.webp,两个文件会互相覆盖。建议转换前检查一下文件名:
1 | find . -type f \( -name "*.png" -o -name "*.jpg" -o -name "*.jpeg" \) \ |
有重复就单独处理,或者给输出文件加上后缀区分。
总结
五个方案各有侧重,选哪个取决于你的具体场景:
| 方案 | 适合人群 | 特点 |
|---|---|---|
cwebp |
命令行用户 | 最快、最可控 |
| ImageMagick | 已有该工具链 | 可同时做其他处理 |
| Squoosh CLI | Node 开发者 | 参数灵活,格式友好 |
| Sharp 脚本 | 前端项目 | 可集成 CI/CD |
| sips + cwebp | macOS 用户 | 零安装(brew 即可) |
无论用哪种方式,WebP 迁移都是一次性的工作,带来的加载速度提升却是长久的。如果你还在用原始图片格式往外丢,花半小时做一次全量迁移吧,值得。
如果你有更好的方案或踩过什么坑,欢迎留言补充。






