如何将项目中的图片转换成webp格式
webp 是谷歌最早在 2010 年推出的一种全新的图片格式,它的主要特点是跟 JPEG、PNG 图片相比,在同等质量下 webp 格式的图片大小要少 26%~35%,在有损压缩下甚至能减少 80%左右, 虽然说是有损压缩,但肉眼几乎很难看出区别来,目前已经有 94%的浏览器支持 webp 格式,所以大胆的在项目中采用吧😄
安装
要将图片转换成 webp 格式首先要在系统中安装一个 libwebp 的命令行工具,去官网下载,
下载下来后解压到任意目录下,然后将此目录下的 bin 目录添加到系统环境变量,打开 cmd 命令窗口,输入cwebp -version查看是否设置成功
cwebp 使用介绍
cwebp 是将普通图片压缩成 webp 格式的命令行工具,下载的包 的 bin 目录下有很多工具,一般只需要使用 cwebp 即可, 如果需要将 gif 图片转换成 webp,请使用 gif2webp 工具,另外 img2webp 用来转换动态 webp 图片, dwebp 是 cwebp 的逆向过程,将 webp 转换成 png、jpg 格式图片,这些工具我们都不常用就不在此介绍了,重点介绍 cwebp 的使用。
cwebp 语法
cwebp [options] input_file -o output_file.webp
cwebp 选项
cwebp 的参数选项有很多,这里挑几个常用的介绍,如果需要查看更多选项的用法可以输入命令cwebp -longhelp
-o string 指定输出的文件名
-lossless 使用无损压缩模式
-near_lossless int
接近无损压缩的级别,范围是 0 到 100(无预处理,默认值),一般设为60。 请注意,使用有损压缩-q 100 有时会产生更好的结果。
-q float 有损压缩模式(默认模式),指定 RGB 通道的压缩系数,范围从 0 到 100, 默认值为 75,值越大质量越好文件也越大,当和-lossless选项一起使用时,较小的值会提高压缩速度, 但产生较大的文件
-resize width height 将原图调整为width * height尺寸大小的图片
-crop x y width height 从图片左上角坐标 x, y 开始裁剪为尺寸大小是width * height的图片,如果和-resize一起使用,会先进行裁剪处理
-size int 指定输出图片的大小, 以字节为单位,只在有损压缩模式下才生效
例子
使用默认压缩
cwebp images/flower.jpg -o images/flower.webp
使用质量级别为50转换文件
cwebp -q 50 images/flower.jpg -o images/flower.webp
调整图片分辨率为 1920 * 1080
cwebp -resize 1920 1080 images/flower.jpg -o images/flower.webp
图片批处理
项目中会用到很多图片,如果通过命令行一张张的手动去转换不现实,我们可以通过写一个 nodejs 程序进行批处理
const { execFile } = require("node:child_process");
const fs = require("fs");
const util = require("util");
const stat = util.promisify(fs.stat);
const path = require("path");
const imgDir = path.resolve(__dirname, "src/assets/img");
// 将图片转换成webp格式并输出到源文件同级目录
const readFile = (dir) => {
fs.readdir(dir, (error, files) => {
files
.filter((file) => !file.endsWith(".webp"))
.forEach((file) => {
const filePath = path.join(dir, file);
stat(filePath).then((stats) => {
const isDirectory = stats.isDirectory(filePath);
if (isDirectory) {
readFile(filePath);
} else {
const newFile = path.join(dir, getFileName(filePath) + ".webp");
// png格式图片使用无损压缩
if (filePath.endsWith(".png")) {
convert(filePath, newFile, "-lossless");
} else {
convert(filePath, newFile);
}
}
});
});
});
};
const convert = (inputFile, outputFile, ...args) => {
execFile("cwebp", [...args, inputFile, "-o", outputFile], (err) => {
if (err) {
throw err;
}
console.log("图片转换成功!");
});
};
const getFileName = (filePath, keepSuffix = false) => {
const begin = filePath.lastIndexOf(path.sep),
end = filePath.lastIndexOf(".");
return filePath.substr(
begin + 1,
keepSuffix ? filePath.length : end - begin - 1
);
};
readFile(imgDir);我们可以把这个批处理文件放到项目中,然后在package.json的scripts字段中配置一下脚本命令,如:
{
"scripts": {
"webp": "node ./toWebp.js"
},
}
需要转换的时候就执行一下npm run webp命令即可,是不是很方便呢👏
说了这么多来看下效果图
转换前: 格式.jpg, 分辨率1920 * 1362,大小161kb

转换后: 格式.webp,分辨率1920 * 1362,大小47.2kb

其他方案
如果批处理程序无法满足你的需求,或者你需要集成到你的打包工具中,如webpack、vite、gulp,你可以使用imagemin-webp插件,这是一个npm包。
小结
本文介绍了cwebp命令常用选项的用途和在命令行中的使用,以及如何通过脚本程序将普通图片批量转换成webp格式,各种参数选项的设置可以影响输出图片的大小和质量,如何在两者之间找到一个平衡,需要你反复的尝试。