Featured image of post 通过 FFmpeg 批量转换目录下图片至 WebP

通过 FFmpeg 批量转换目录下图片至 WebP

通过 Shell 脚本批量转换目录下文件至 WebP 格式,便于统一 Blog 图像格式

Why?

先前所述,Webp 是极其适用于 web(正如它的名字)的一种图像编码格式。截至目前,主流浏览器均已支持,包括从来不鸟开源格式的苹果 Safari。鉴于本博客面对的人群,并非是 2022 年还在用 IE / 360 之类的魔怔人,故而果断使用 Webp

我们博客的方案是通过 ffmpeg + zsh 批处理,而不是通过 Node.js 之类自动压缩。原因其一,前者比后者性能更高,CJavaScript 不用多说;原因其二,前者比后者可控、可定制化太多,本博客有诸多不能编码到 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,并安装启用了 libwebpffmpeg。(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
}
comments powered by Disqus