江湖夜雨十年灯

使用 ffmpeg 批量处理图片

李二花 / 2023-07-28


2020 年做素材模块的时候,就用过 ffmpeg 这个工具,当时是需要获取视频的详细码率等信息,并且需要截取视屏中的某一帧作为视频的封面,发现 ffmpeg 很强大。

但是因为是工作中很小的一个需求点,大部分的素材维护管理都跟这个没有太大关系,因此在项目结束后,就没有再过多的研究过他了。

这次是因为有很多的图片需要压缩处理,并且想生成缩略图,github 找了好多现成的工具,发现使用效果都不理想(不满足我的使用需求),因此决定使用 ffmpeg。 在此记录一下常用的图片操作的命令,对于视频等的详细命令,可以参考这里

常用命令

1.自动压缩图片(按给定权重)

ffmpeg -i ~/Desktop/circle.jpg -q 10(compress_level) ~/Desktop/circle-10.jpg
#compress_level:压缩等级为正整数,数值越大压缩等级越高

2.压缩至指定的宽高

ffmpeg -i ~/Desktop/circle.jpg -vf scale=-1:500(width:height) ~/Desktop/circle-thumbnail.jpg
#width为压缩后的图片宽度
#height为压缩后的图片高度
#当width或height其中有一个数值为-1时将保持原来图片尺寸比例压缩

3.图片裁切

ffmpeg -i image_source -vf crop=width:height:from_x:from_y out_source
#width是要裁剪出的图片的宽度
#height是要裁剪出的图片的高度
#from_x是裁剪的起始X轴的位置
#from_y是裁剪的起始Y轴的位置

4.添加水印图片

ffmpeg -i image_source -vf movie=logo_source,scale=logo_width:logo_height,lut=a=val*opacity_num[watermask];[in][watermask] overlay=from_x:from_y[out] -y  out_source
#logo_source为水印图片地址
#logo_width为水印图片的宽度
#logo_height为水印图片的高度
#opacity_num为水印图片的透明度
#from_x为水印的起始X轴的位置
#from_y为水印的起始Y轴的位置

5.添加文字水印

ffmpeg -i image_source -vf drawtext=fontfile=font_ttf_path:fontcolor=font_color:fontsize=font_size:text=message_info:x=from_x:y=from_y  out_source
#font_ttf_path为字体路径,此项必须设置否则会出现字体无法找到的错误;
#字体路径要设置绝对路径并且要注意路径正反斜线转义(例如C\\:/Windows/Fonts/simhei.ttf)
#font_color为字体的颜色
#font_size为字体的大小
#message_info为水印文字内容
#from_x为水印的起始X轴的位置
#from_y为水印的起始Y轴的位置
#如果水印内容是中文需要设置中文字体否则会文字显示乱码

快速压缩

为了更加快速的压缩图片文件,写了一个 shell 脚本批量处理将对应的图片快速处理成想要的压缩权重或者缩略图大小,具体的代码如下:

#!/bin/zsh

# 定义图片压缩函数
function compress_pics_small() {

  # 获取参数  
  pic_dir=$1
  output_dir=$2
  compression_ratio=$3
  
  # 创建输出目录
  mkdir -p $output_dir
  # 遍历源图片目录中的图片文件
  for pic in $pic_dir/*.JPG; do
    # 获取图片文件名
    pic_name=$(basename "$pic")
    # 使用 ffmpeg 压缩图片
    ffmpeg -i "$pic" -q $compression_ratio "$output_dir/$pic_name"
  done
}

function compress2specific_scale() {
  # 获取参数  
  pic_dir=$1
  output_dir=$2
  height=$3
  
  # 创建输出目录
  mkdir -p $output_dir
  # 遍历源图片目录中的图片文件
  for pic in $pic_dir/*.JPG; do
    # 获取图片文件名
    pic_name=$(basename "$pic")
    # 使用 ffmpeg 压缩图片
    ffmpeg -i "$pic" -vf scale=-1:"$height" "$output_dir/$pic_name"
  done
}

# 调用函数
compress_pics_small ~/Desktop/摩托旅行 ~/Desktop/摩托旅行_small 30
compress2specific_scale ~/Desktop/摩托旅行_small ~/Desktop/摩托旅行_thumbnail 500