如何在终端中批量/多进程裁剪图像?

我尝试裁剪几张相同大小的图片,但是当我裁剪5张图片并且过程完成后,只有4张图片被裁剪了,还有1张图片没有被裁剪,如果我裁剪1张图片会出现错误...
我正在使用以下命令:
convert -crop 599x500+147+200 *.jpg

screenshot batch crop 5 picture but processes 4 pictures only

screenshot batch crop 1 picture but get error

如何调整我的命令?
1个回答

第一个问题似乎是因为当convert接收到一个列表时,它会将最后一个指定的文件作为输出文件名。所有新的文件都以最后一个文件命名,而其本身则保持不变(这可能不是您想要或期望的,但应该比意外覆盖文件要好)。
当目录中只有一个文件时(因此您的glob扩展为一个文件),convert会抱怨缺少定义的图像,因为它期望至少指定一个输入文件和一个输出文件名。您在glob中使用的位置是输出文件名的位置,所以convert在第二个图像中抱怨缺少输入文件。
为了获得更可靠的结果,您应该指定输入和输出文件:
 convert input-file.jpg -crop 599x500+147+200 new-file.jpg

如果名字很长,你可以使用制表符补全(输入前几个字符后按下制表键使shell自动完成剩余的名字)来输入文件和输出文件的名称(对我而言,运行良好)。

对于批处理,你可以使用shell在每个文件上运行命令,并使用一些字符串操作来构建新的名称,以便新文件具有合理的名称,类似于:

for f in *.jpg; do 
    echo convert "$f" -crop 599x500+147+200 "${f/.jpg/-cropped.jpg}"
done

在第二行的echo中,这显示了新名称将是什么。如果新名称看起来正确,您可以删除echo并再次运行命令以实际裁剪图像。

将新文件放入一个新目录可能更容易,特别是如果您的文件名具有不同的扩展名...

mkdir cropped
for f in *.jpg *.png; do
    echo convert "$f" -crop 599x500+147+200 cropped/"$f" 
done

再次强调,在这之前你需要移除echo,否则它将不会起作用。

在一行命令中,类似于 find . -maxdepth 1 -iname "*.jpg" -type f -exec convert "{}" -crop 900x340+180+50 cropped/"{}" \; - Pablo Bianchi