用这个Bash脚本实现图像处理的自动化

277 阅读3分钟

作家不仅要用文字工作,他们还经常要用图像工作。技术写作涉及呈现大量的屏幕截图,以传达技术和流程。不同的出版平台可能对图片有不同的要求,如图片格式或文件大小。

作为一名IT顾问和系统工程师,我写过很多技术文件作为客户的交付物,一般都是以Microsoft Word(.doc)作为要求的格式。任何文件都会随着内容的增加而快速增长。在早期,屏幕截图通常是位图(.bmp),它的文件大小可能非常大。一份描述在服务器上安装操作系统的文件最终可能会成为一个非常大的文件。

在不使它们变得不可读的情况下缩小图片的大小是一项艰苦的工作。位图可以被转换成jpeg文件,后来又转换成png文件。即使后来我把我的办公套件换成LibreOffice,编辑仍然是一个挑战。幸运的是,今天大多数截图工具都能以较小的格式保存,如png。

Opensource.com对其文章中使用的图片有一定的限制。我开发了一个快速的三步法来为我的文章准备图片。第一步是巧妙地进行分期,如调整窗口的大小或改变字体。另外两个步骤变得非常重复。那就是确保图片不超过600像素的宽度限制和应用边框。

prepimg.sh脚本

我写了一个名为prepimg.sh 的Bash脚本来处理这些任务。这个脚本使用了ImageMagick套件中的两个工具。

调整图像的大小

屏幕截图工具将图像保存到Pictures 目录中,并有一个通用的名字--如Screenshot-20210923222312.png 。我的prepimg.sh 脚本检查这个目录下的文件的像素宽度,并调整任何超过限制的文件的大小。这一步使用ImageMagick套件中的识别程序来确定宽度(%w)。

$ identify -format %w Screenshot-20210903202655.png
1217

该宽度值被分配到变量W ,作为与600的限制的比较器使用。限制本身可通过变量$MAXWIDTH 进行配置。如果宽度被确定为超过了MAXWIDTH,那么就会调用另一个名为convert的ImageMagick程序来减少图像的宽度。下面是我脚本中的图像处理功能。

     if [ "$W" -gt "$MAXWIDTH" ]
     then
         [[ $VERBOSE -gt 0 ]] && echo "${1} is ${W} - reducing"
         convert -resize "${MAXWIDTH}" \
                 "${SCREENSHOTS}"/"${1}" \
                 "${READY}"/"${1}"
     ...     

该图像根据需要被缩小,并保存到由$READY 变量定义的不同目录中。在这种情况下,图像的大小实际上被调整得稍微小了一些--598像素,以便为添加边框留出空间,我接下来会展示这个。

给图像添加边框

有时,图像会显得与网页的背景融为一体。这是因为图像的前景颜色到其边缘是与网站的背景颜色相同的。这里有一个例子。

Image with no border blends into the background

一张没有边框的图片。(CC BY-SA 4.0)

正如你在上面的图片中所看到的,不可能分辨出图片的边缘在哪里。这个问题并不限于白色。它取决于每个单独的网站和它使用的主题颜色。因此,如果背景是红色的,而图像的边缘也是红色的,也会出现这种问题。我的脚本通过使用转换工具解决了这个问题。-border选项为每个图像文件添加一个大小为1像素的边框。这个选项本身就足够了,但我还想通过使用*-bordercolor*选项来设置颜色。这里有一个例子。

convert -bordercolor black -border 1 Screenshot-20210903202655.png

下面是有边框的同一张图片。这看起来不是更漂亮吗?

Image with a border doesn't blend into background

一个有边框的图片。(CC BY-SA 4.0)

你的图片已经准备好了

我使用一个for 循环来遍历屏幕截图目录。它为每个文件调用函数process_img 。该函数同时处理宽度和边框。完整的代码做了一些理智的检查,如确保文件实际上是一个图像。

process_img() {
     # verify that file is an image file, and then get dimensions
     if file "${SCREENSHOTS}"/"${1}" | grep -qE 'image|bitmap'; then
         [[ $VERBOSE -gt 0 ]] && echo "${1} is an image"
         W=$(identify -format %w "${SCREENSHOTS}"/"${1}")
     else
         echo "File ${SCREENSHOTS}/${1} is not an image."
         W=0
     fi
     # resize and border
     if [ "$W" -gt "$MAXWIDTH" ]
     then
         [[ $VERBOSE -gt 0 ]] && echo "${1} is ${W} - reducing"
         convert -resize "${MAXWIDTH}" \
                 -bordercolor $BORDER \
                 -border 1 \
                 "${SCREENSHOTS}"/"${1}" \
                 "${READY}"/"${1}"
     else
         convert -bordercolor $BORDER \
                 -border 1 \
                 "${SCREENSHOTS}"/"${1}" \
                 "${READY}"/"${1}"
     fi
 }

脚本的最后一步是将处理过的文件保存在一个叫做Ready的子目录下*,*该目录由名为$READY 的变量决定。这样就保留了原始文件,以便进一步使用。

使用方法

Prepimg.sh 包括预期的帮助工具,描述它的参数和它们的用法。

$ prepimg.sh -h
prepimg.sh Version 0.7 - written by Alan Formy-Duval
prepimg.sh [OPTIONS]
--verbose, -v Be verbose
--directory, -d Screenshot directory (default: /home/alan/Pictures/Screenshots)
--ready, -r Ready directory (default: /home/alan/Pictures/Screenshots/Ready)
--border, -b Border color (default: black)

代码和结论

文章中介绍的代码是不完整的,应该被视为伪代码。你可以在我的Git资源库中查看完整的脚本。

ImageMagick套件是一套强大的处理图像的工具。除了我的小脚本中包含的功能外,你还可以做很多事情。通讯员Jim Hall最近也写了关于用它来调整图像大小的文章。

无论你是喜欢Bash脚本还是用其他语言如C或Python编码,自动化都是一个很大的帮助。一次又一次,我看到一点点的代码可以减少许多令人头痛的事情,使我们能够更好地利用我们的时间。