一键压缩avif图像
使用FFmpeg批量压缩avif或webp图像
一键压缩avif图像
背景介绍
传统的 JPEG 和 PNG 格式在现代网页开发中已经不再是唯一选择。Google 推出的 WebP 格式和新兴的 AVIF 格式都能在保持高质量的同时大幅减小文件体积。WebP 通常比 JPEG 小 25-35%,而 AVIF 则可以再减少 20-30% 的体积。
功能简介
这套工具包含四个主要功能:
- img2webp - 将单张图片转换为 WebP 格式
- img2avif - 将单张图片转换为 AVIF 格式
- batch_img2webp - 批量转换目录中的所有图片为 WebP
- batch_img2avif - 批量转换目录中的所有图片为 AVIF
质量参数说明
- WebP:质量范围 0-100(数值越大质量越高,默认85)
- AVIF:质量范围 0-63(数值越小质量越高,默认25)
- 硬件加速优化:针对 M4 Mac 设备进行了特别优化
- 尺寸对比:转换完成后显示文件大小变化
使用方法
1. 安装依赖
首先确保系统已安装 FFmpeg:
1
2
# 使用 Homebrew 安装(macOS)
brew install ffmpeg
2. 配置终端函数
将提供的代码直接复制到终端中执行,即可在当前会话中使用这些函数。 如为永久可用,可将代码添加到你的 shell 配置文件中(如 ~/.zshrc
或 ~/.bashrc
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# 将图片转换为 WebP 格式
# 用法: img2webp <输入文件> [质量] [输出文件]
# 质量范围: 0-100 (默认: 85)
img2webp() {
if [[ $# -eq 0 ]]; then
echo "用法: img2webp <输入文件> [质量] [输出文件]"
echo "示例: img2webp photo.jpg 90 photo.webp"
echo " img2webp photo.jpg 90"
echo " img2webp photo.jpg"
return 1
fi
local input="$1"
local quality="${2:-85}"
local output="${3:-${input:r}.webp}"
if [[ ! -f "$input" ]]; then
echo "错误: 输入文件 '$input' 不存在"
return 1
fi
# 针对 M4 Mac 使用硬件加速
ffmpeg -i "$input" \
-c:v libwebp \
-quality "$quality" \
-preset picture \
-threads 0 \
"$output" -y -loglevel error
if [[ $? -eq 0 ]]; then
local input_size=$(du -h "$input" | cut -f1)
local output_size=$(du -h "$output" | cut -f1)
echo "✓ $output ($input_size -> $output_size)"
else
echo "✗ 转换失败: $input"
return 1
fi
}
# 将图片转换为 AVIF 格式
# 用法: img2avif <输入文件> [质量] [输出文件]
# 质量范围: 0-63 (数字越小质量越高,默认: 25)
img2avif() {
if [[ $# -eq 0 ]]; then
echo "用法: img2avif <输入文件> [质量] [输出文件]"
echo "示例: img2avif photo.jpg 20 photo.avif"
echo " img2avif photo.jpg 20"
echo " img2avif photo.jpg"
echo ""
echo "注意: AVIF 质量参数 0-63,数字越小质量越高"
return 1
fi
local input="$1"
local quality="${2:-25}"
local output="${3:-${input:r}.avif}"
if [[ ! -f "$input" ]]; then
echo "错误: 输入文件 '$input' 不存在"
return 1
fi
# 检测是否有透明通道
local has_alpha=$(ffprobe -v error -select_streams v:0 -show_entries stream=pix_fmt -of default=noprint_wrappers=1:nokey=1 "$input" | grep -c "a$")
# 针对 M4 Mac 优化的 AVIF 转换
if [[ $has_alpha -gt 0 ]]; then
# 带透明通道
ffmpeg -i "$input" \
-c:v libaom-av1 \
-crf "$quality" \
-cpu-used 4 \
-row-mt 1 \
-threads 0 \
-pix_fmt yuva420p \
"$output" -y -loglevel error
else
# 不带透明通道
ffmpeg -i "$input" \
-c:v libaom-av1 \
-crf "$quality" \
-cpu-used 4 \
-row-mt 1 \
-threads 0 \
-pix_fmt yuv420p \
"$output" -y -loglevel error
fi
if [[ $? -eq 0 ]]; then
local input_size=$(du -h "$input" | cut -f1)
local output_size=$(du -h "$output" | cut -f1)
echo "✓ $output ($input_size -> $output_size)"
else
echo "✗ 转换失败: $input"
return 1
fi
}
# 批量转换目录下的所有图片为 WebP
# 用法: batch_img2webp [目录] [质量]
batch_img2webp() {
local dir="${1:-.}"
local quality="${2:-85}"
for file in "$dir"/*.{jpg,jpeg,png,JPG,JPEG,PNG}(N); do
if [[ -f "$file" ]]; then
img2webp "$file" "$quality"
fi
done
}
# 批量转换目录下的所有图片为 AVIF
# 用法: batch_img2avif [目录] [质量]
batch_img2avif() {
local dir="${1:-.}"
local quality="${2:-25}"
for file in "$dir"/*.{jpg,jpeg,png,JPG,JPEG,PNG}(N); do
if [[ -f "$file" ]]; then
img2avif "$file" "$quality"
fi
done
}
3. 基本使用示例
转换单张图片为 WebP:
1
2
3
img2webp photo.jpg # 使用默认质量(85)
img2webp photo.jpg 90 # 指定质量为90
img2webp photo.jpg 90 output.webp # 指定输出文件名
转换单张图片为 AVIF:
1
2
3
img2avif photo.png # 使用默认质量(25)
img2avif photo.png 20 # 指定质量为20
img2avif photo.png 20 output.avif # 指定输出文件名
批量转换目录中的所有图片:
1
2
batch_img2webp ~/blog/images # 转换目录中所有图片为WebP
batch_img2avif ~/blog/images 50 # 指定质量并转换为AVIF
快捷指令
为了进一步简化操作流程,我还创建了一个Mac快捷指令,可以在移动设备上快速处理图片:
这个快捷指令可以与终端工具配合使用,提供更加完整的图片优化工作流。
本文由作者按照 CC BY 4.0 进行授权