905 字
5 分钟
Linux如何批量任务处理(转换图片格式)
2025-02-07

一.Magick#

magick 是 ImageMagick 命令行工具的一部分,它是一个功能强大的开源软件套件,用于创建、编辑、合成和转换位图图像。ImageMagick 支持超过 200 种图像格式,包括 PNG、JPEG、GIF、TIFF、PDF、SVG 等。

在 Linux 系统中,magick 是 ImageMagick 7.x 版本中引入的命令行工具,用于替代旧版本中的 convert、identify、montage 等命令。magick 提供了一个统一的接口来执行各种图像处理任务。

在大多数 Linux 发行版中,你可以通过包管理器安装 ImageMagick,这里不再介绍ImageMagick的安装。

1.图像格式转换:#

magick ./image.png ./image.jpg

2.调整图像大小:#

将图像调整为宽度 300 像素,高度按比例缩放:

magick input.jpg -resize 300x output.jpg

将图像调整为 300x200 像素(可能会变形):

magick input.jpg -resize 300x200! output.jpg

3.裁剪图像:#

从图像的左上角开始裁剪一个 200x200 的区域:

magick input.jpg -crop 200x200+0+0 output.jpg

4.添加水印:#

在图像上添加文本水印:

magick input.jpg -gravity center -pointsize 36 -fill white -annotate 0 'Watermark' output.jpg

在图像上添加图片水印:

magick input.jpg watermark.png -gravity southeast -composite output.jpg
TIP

更多用法请查看magick文档

二.批量处理图片#

面对大量图片,像上面的操作显然是不能满足需求的。我们可以利用Shell脚本进行批量处理。

创建一个脚本

touch convert.sh && chmod +x convert.sh 

i:写一个简易的批量处理脚本#

input_dir="/input directory path"
output_dir="/output directory path"

# 获取输入目录下的所有图片文件
image=$(ls $input_dir | grep -E "jpg|jpeg|png")

# 记录脚本开始时间
start_time=$(date +%s)

# 遍历所有图片并转换
for i in $image; do
    filename="${i%.*}.jpg"
    magick $input_dir/$i $output_dir/$filename
done

# 记录脚本结束时间
end_time=$(date +%s)
elapsed_time=$((end_time - start_time))

echo "脚本执行时间:$elapsed_time 秒"

有了上述脚本,我们可以轻松的处理内容了。只需要运行脚本,我们就可以喝杯小饮料放松一下了。

什么?饮料喝完了,还没处理完?

ii:脚本并发执行#

查看我们的任务管理器发现,CPU只有一个核心被利用,有没有什么办法利用更多CPU资源呢? 多进程并发!

像上述脚本中的多个任务之间高度独立,这种情况是非常适合并发解决的。

在 Shell 脚本中,可以通过 & 将命令放到后台执行,从而实现多进程并发执行。使用 wait 命令可以等待所有后台进程完成。

将上述脚本进行简单改造后得到下列脚本:

# 最大并行进程数
max_processes=16
# 当前运行的进程数
current_processes=0

input_dir="/input directory path"

output_dir="/output_dir directory path"

image=$(ls $input_dir | grep -E "jpg|jpeg|png")

start_time=$(date +%s)


for i in $image; do
    filename="${i%.*}.jpg"
    magick  $input_dir/$i $output_dir/$filename &
    ((current_processes++))
    # 当达到最大进程数时,等待一个进程完成
    if [ $current_processes -eq $max_processes ]; then
        wait -n
        ((current_processes--))
    fi
done
end_time=$(date +%s)
elapsed_time=$((end_time - start_time))
echo "脚本执行时间:$elapsed_time 秒"

wait

for循环中启动进程处理任务时将不再被阻塞,for循环会迅速创建大量进程耗尽我们的CPU资源,造成系统卡死。所以我们需要控制同时运行的进程数量,以避免系统资源耗尽。可以通过一个计数器来实现这一点。我们使用max_processes current_processes分别表示最大进程数,和当前进程数。当当前进程达到最大时,for循环停止,待进程结束。实现最终效果,即脚本运行时启动16个进程,每执行完一个任务,脚本便会再启动一个进程任务,实现最大化利用CPU。 执行脚本

./convert.sh

等待脚本执行完毕即可

Linux如何批量任务处理(转换图片格式)
https://milkfunc.top/posts/linux如何批量任务处理转换图片格式/
作者
CapCake
发布于
2025-02-07
许可协议
CC BY-NC-SA 4.0