9.11 图像文件的批量缩放及格式转换

我们大家都会使用数码相机,也会从Internet上获取数码照片。如果需要处理大量图像文件,我们可以轻松地用脚本批量处理。这通常会涉及的任务是调整照片的大小,有时也需要转换图像格式(例如,将JPEG格式转换成PNG格式)。当我们从数码相机中获取到照片时,大分辨率的图片通常体积都比较大,我们可能需要减少图片的大小,以便于存储以及通过电子邮件发送给他人。因此我们就需要对其进行调整来降低分辨率。这则攻略将讨论如何用脚本管理图像。

9.11.1 新手上路

Imagemagick是一款出色的图像处理工具,它包含丰富的选项,能够处理多种图像格式。大多数GNU/Linux发行版并没有安装Imagemagick。你得自己手动安装这个软件包。convert是我们经常要使用的命令。

9.11.2 实战演练

将一种图像格式转换为另一种图像格式:

  1. $ convert INPUT_FILE OUTPUT_FILE

例如:

  1. $ convert file1.png file2.png

我们可以通过指定缩放比或输出图像的宽度和高度来将图像调整到所需要的大小。

指定WIDTH(宽度)或HEIGHT(高度)来缩放图像:

  1. $ convert image.png -resize WIDTHxHEIGHT image.png

例如:

  1. $ convert image.png -resize 1024x768 image.png

必须提供WIDTHHEIGHT,这样才能够使脚本自动计算其他数值,以便于在保留图像比例的同时进行缩放。

  1. $ convert image.png -resize WIDTHx image.png

例如:

  1. $ convert image.png -resize 1024x image.png

指定百分比缩放图像:

  1. $ convert image.png -resize "50%" image.png

让我们看一个用于图像管理的脚本:

  1. #!/bin/bash
  2. #文件名: image_help.sh
  3. #用途:图像管理脚本
  4. if [ $# -ne 4 -a $# -ne 6 -a $# -ne 8 ];
  5. then
  6. echo Incorrect number of arguments
  7. exit 2
  8. fi
  9. while [ $# -ne 0 ];
  10. do
  11. case $1 in
  12. -source) shift; source_dir=$1 ; shift ;;
  13. -scale) shift; scale=$1 ; shift ;;
  14. -percent) shift; percent=$1 ; shift ;;
  15. -dest) shift ; dest_dir=$1 ; shift ;;
  16. -ext) shift ; ext=$1 ; shift ;;
  17. *) echo Wrong parameters; exit 2 ;;
  18. esac;
  19. done
  20. for img in `echo $source_dir/*` ;
  21. do
  22. source_file=$img
  23. if [[ -n $ext ]];
  24. then
  25. dest_file=${img%.*}.$ext
  26. else
  27. dest_file=$img
  28. fi
  29. if [[ -n $dest_dir ]];
  30. then
  31. dest_file=${dest_file##*/}
  32. dest_file="$dest_dir/$dest_file"
  33. fi
  34. if [[ -n $scale ]];
  35. then
  36. PARAM="-resize $scale"
  37. elif [[ -n $percent ]];
  38. then
  39. PARAM="-resize $percent%"
  40. fi
  41. echo Processing file : $source_file
  42. convert $source_file $PARAM $dest_file
  43. done

下面是输出样例,将目录sample_dir中的图像调整到原来的20%:

  1. $ ./image_help.sh -source sample_dir -percent 20%
  2. Processing file :sample/IMG_4455.JPG
  3. Processing file :sample/IMG_4456.JPG
  4. Processing file :sample/IMG_4457.JPG
  5. Processing file :sample/IMG_4458.JPG

将图像宽度调整到1024:

  1. $ ./image_help.sh -source sample_dir -scale 1024x

-ext png加入上面的命令,使文件格式转换成PNG。

将文件缩放或转换到指定的目录:

  1. $ ./image_help.sh -source sample -scale 50% -ext png -dest newdir
  2. # newdir作为目的目录

9.11.3 工作原理

上面的脚本image_help.sh可以接受多个命令行参数,例如-source-percent-scale-ext-dest等。每个选项的简短描述如下。

  • -source用于指定图像源目录。

  • -percent用于指定缩放比例,-scale用于指定缩放宽度与高度。

  • -percent-scale不能同时出现,只能使用其中之一。

  • -ext用于指定目标文件格式。-ext是一个可选的选项。如果没有指定,那么不执行格式转换。

  • -dest为缩放或转换格式后的文件指定目的目录。该选项也是可选的。如果没有指定,目的目录则和源目录相同。脚本的第一步就是检查命令行参数的数量是否正确,可以出现的参数数量分别是4、6或8。

借助while循环和case语句,我们将命令行参数解析到对应的变量。$#是一个特殊的变量,它可以返回参数的数量。shift命令每执行一次,就将命令行参数向左移动一个位置,这样我们就不需要使用变量$1$2$3等,而只用一个$1来就可以对命令参数逐个进行访问了。case语句用来匹配$1的值,就像C语言中的switch语句一样。如果匹配了某个case分支,就执行对应的语句。每一个case分支都以;;作为结尾。一旦将所有的参数都解析到变量percentscalesource_dirextdest_dir中,就是用for循环对源目录中的每一个文件进行迭代,并执行对应的转换操作。

如果变量ext已定义(也就是说-ext作为命令参数出现),就将目标文件的扩展名从source_file.extension更改为source_file.$ext。接下来检查是否提供了-dest选项。如果指定了目的目录,则使用文件名切片将源路径中的目录替换成目的目录,从而形成目的文件路径。然后构造出convert命令的参数,用以执行缩放(-resize widthx-resize perc%)。参数构造完毕之后,用对应的参数执行convert命令。

9.11.4 参考

2.11节讲解了如何提取部分文件名。