YJ在ubuntu: 批量处理照片的问题里介绍了他找到的在Ubuntu下批量处理照片的方法。他讲的两种方法都是基于GUI的。我到不是反对GUI,不过就像Andrew Tanenbaum (大牛阿,MINIX的作者,一堆经典CS教材的作者)的在他的FAQ (推荐读一下,挺有意思) 里说到的一条:
Do you like WYSIWYG systems?
Definitely not. I can type faster than I can point. And my mother told me that pointing is impolite.
没错,type faster than point,所以很多时候CLI会比GUI更高效便捷一点。我这一贴就说说我发现或找到的用CLI批量处理图片的方法。
这里都假设使用ImageMagick里的工具,YJ说的那个用Nautilus Image Scripts,最终调用的还是ImageMagick,相当一部分Linux(甚至Win下)的图像相关的自由软件都选择了调用ImageMagick提供的命令。
好了,假设在CLI下,resize一张照片A.JPG,用convert:
- convert -resize 60% -quality 80 A.JPG A-resize.JPG
现在用同样的命令来批量处理同一个目录(及其子目录)下的所有JPG结尾的照片,我在Bash下用的命令是这样的:
- find . -name \*.JPG -print | awk -F.JPG '{ output = $1"-resize.JPG" ; cmd = "convert -resize 60% -quality 80 "$0" "output; system(cmd)}'
要是你嫌这条命令太过于安静,而你要同时处理很多照片,希望屏幕上能报告一下执行情况,可以这样:
- find . -name \*.JPG -print | awk -F.JPG '{ output = $1"-resize.JPG" ; cmd = "convert -resize 60% -quality 80 "$0" "output; print cmd; system(cmd)}'
这样之后,resize的照片是在当前目录下的,但是都重名了。Linux CLI下千变万化,同一件事情可能有无数种作法,比如我随便google了一下,就找到一篇,列一下里面提到的方法。
假设你在当前目录下,新建了一个目录/tmp/output,用来放resize后的照片,并且,你可以这样做:
- mkdir /tmp/output
- find . -name \*.JPG -exec convert -resize 60% -quality 80 {} /tmp/output/{} \;
用这个方法,你的output目录不能建在当前目录下(试试看,就知道为什么了), 而且没办法向上面那样重命名文件。用find的-exec还会有其他问题。find配合xargs会更有效率,比如
- find . -name "*.JPG" | xargs -l -i convert -resize 60% -quality 80 {} /tmp/output/{}
当然了,还可以使用perl强大的-e功能了,基本上是为所欲为了:
- mkdir output
- find . -iname "*.JPG" | perl -e 'for(<>) { chomp $_;@a=split ( /\// , $_ ) ;$str = "convert -resize 60% -quality 80 $_ output/".$a[-1];print $str."\n";`$str`}'
也可以调用shell的loop功能来通过循环做这件事情,比如在bash里可以
- for file in `find . -name \*.JPG`; do convert -resize 60% -quality 80 ${file} ${file%.*}-resize.JPG; done
总之,CLI下利用UNIX/LINUX的命令组合,常常会有非常简洁的实现,我上面提到的方法可能是很笨的,欢迎指正,补充。
如果要实现较为复杂的功能, 可以自己写Shell脚本,或者perl脚本等等。网上也有很多写好现成的,能实现各种功能,比如BBIPS: Bash Batch Image Processing Script,也是在CLI下用,看看它的screenshot。


Recent Comments