Why?
如先前所述,Webp
是极其适用于 web(正如它的名字)的一种图像编码格式。截至目前,主流浏览器均已支持,包括从来不鸟开源格式的苹果
Safari
。鉴于本博客面对的人群,并非是 2022 年还在用 IE / 360
之类的魔怔人,故而果断使用 Webp
。
我们博客的方案是通过 ffmpeg
+ zsh
批处理,而不是通过 Node.js
之类自动压缩。原因其一,前者比后者性能更高,C
和
JavaScript
不用多说;原因其二,前者比后者可控、可定制化太多,本博客有诸多不能编码到
webp
的图像,因为它们本身就在展示编码的差异,例如 FFmpeg 系列文章。
How?
我们使用的脚本如下,使用方法是 cd
到特定目录后,在终端
zsh /path/to/script.zsh
,可以选择将脚本统一放到
~/scripts/
目录下方便管理。
#!/bin/zsh
[[ ! -d ./webp ]] && mkdir ./webp
for f (*.(bmp|jpg|jpeg|png)) {
ffmpeg -i $f -c:v libwebp -lossless 1 -quality 100 -compression_level 6 ./webp/${f%.*}.webp
}
注意,需要系统有 zsh
,并安装启用了 libwebp
的 ffmpeg
。(FFmpeg 默认的 Release 包括
libwebp
)
可通过此指令检查 ffmpeg
状态:ffmpeg -codecs | grep webp
。若输出了
DEVILS webp
说明安装正确。
macOS
可通过 brew install ffmpeg
安装。
详解脚本
#!/bin/zsh # 脚本开头常见写法, 这里是 zsh 所以写 /bin/zsh
# zsh 语法糖, [[ expr ]] && statement,
# 当 expr 为 true 时执行 statement,
# 如果 ./webp 文件夹(-d)不存在(!), 就创建它, 避免运行时多余的提示
[[ ! -d ./webp ]] && mkdir ./webp
# 同样是 zsh 的 forEach 语法糖,
# 遍历当前目录中以 .bmp .jpg .jpeg .png 结尾的文件,
# 实际上可以替换成 find + awk 检查文件 mime-type, 不过懒得写了
for f (*.(bmp|jpg|jpeg|png)) {
ffmpeg -i $f \ # -i 指定输入文件
# 指定输出参数, -lossless 1 开启无损转换;
# -quality 指定质量, 不过该参数只对有损有用, 90 似乎是一个不错的甜蜜点
# -compression_level 可指定 0..6 这里取最高
# 此外可以根据内容指定 -preset 选项 [none, default, picture, photo, drawing, icon, text]
# 详见: https://www.ffmpeg.org/ffmpeg-codecs.html#libwebp
-c:v libwebp -lossless 1 -quality 100 -compression_level 6 \
# 指定输出文件, ${f%.*} 是去除拓展名的文件名,
./webp/${f%.*}.webp
}