使用 ImageMagick 进行图像处理

作者:Dave Taylor

在我的专栏中,我花了很多时间谈论文本处理和分析,基本假设是如果您使用命令行,那么您专注于文本。但这并非总是如此,如果您处理图像(无论是 JPEG、PNG、GIF 还是其他格式),都有一套免费下载的图像相关实用程序可供使用,它们直接从命令行提供相当惊人的功能,因此也可以从 shell 脚本中调用。

我谈论的是 ImageMagick,这是一组程序,多年来不断发展壮大,现在还包括强大的 Perl 和 Ruby 接口。但是,呸!我们不需要什么 Perl 或 Ruby。我们将坚持使用我们硬核的 shell 命令,非常感谢。

您可以在 https://imagemagick.org.cn 找到可下载的二进制文件和源代码,并且像往常一样,我建议您下载源代码并在您的系统上编译它(如果可以)。这比寄希望于别人的编译版本针对您自己的硬件配置进行了优化要可靠得多。

ImageMagick 发行版包含各种不同的命令,我将其分为“分析”和“编辑”工具。对于本文,让我们坚持使用分析工具。首先,让我向您展示它在典型的图像文件上提供的信息比标准的 Linux 命令行多多少。

分析图像以查找非优化分辨率

如果您使用 Linux 即使是很短的时间,您可能也了解了 file 命令。它对某些文件类型很有帮助


$ file wp-content.tar.gz
wp-content.tar.gz: gzip compressed data, from Unix

但是,该命令通常对图像无用


$ file pvp.jpg
pvp.jpg: JPEG image data, EXIF standard

嗯,图像大小呢?有没有任何有用的信息?真是的。

输入 ImageMagick identify 命令


$ identify pvp.jpg
pvp.jpg JPEG 970x311 DirectClass 114kb 0.010u 0:01

啊...所以这个特定的图像的尺寸(该套件将尺寸称为图像的“几何形状”)是 970x311。这很有用。

您想要更多信息吗?-verbose 选项会输出相当多的数据


$ identify -verbose pvp.jpg
Image: pvp.jpg
  Format: JPEG (Joint Photographic Experts Group JFIF format)
  Geometry: 970x311
  Class: DirectClass
  Colorspace: RGB
  Type: TrueColor
  Depth: 8 bits
  Endianess: Undefined
  Channel depth:
    Red: 8-bits
   Green: 8-bits
    Blue: 8-bits
  Channel statistics:
    Red:
      Min: 0
      Max: 255
      Mean: 180.72
      Standard deviation: 74.2122
    Green:
      Min: 0
      Max: 255
      Mean: 168.593
      Standard deviation: 76.0343
    Blue:
      Min: 0
      Max: 255
      Mean: 169.459
      Standard deviation: 77.244
  Colors: 21864
  Rendering-intent: Undefined
  Resolution: 72x72
  Units: Undefined
  Filesize: 114kb
  Interlace: None
  Background Color: white
  Border Color: #DFDFDF
  Matte Color: grey74
  Dispose: Undefined
  Iterations: 0
  Compression: JPEG
  Orientation: Undefined
  JPEG-Quality: 94
  JPEG-Colorspace: 2
  JPEG-Sampling-factors: 1x1,1x1,1x1
  signature: bc8a6a698ca35fd8feab71452423386ff98b1fb7b5ec ...
  Profile-xmp: 811 bytes
  Profile-exif: 22 bytes
    unknown
  Profile-app12: 15 bytes
  Tainted: False
  User Time: 0.020u
  Elapsed Time: 0:01

说实话,尺寸和分辨率是这个冗长输出中最有用的信息。

只需稍加努力,您就可以提取这些信息项


$ identify -verbose pvp.jpg | grep -E '(Resolution:|Geometry:)'
  Geometry: 970x311
  Resolution: 72x72

现在想象一下,您正在开发一个网站,并希望确保网站上没有图像的分辨率高于 72dpi,这是标准的屏幕分辨率。较高的打印就绪分辨率毫无意义,因为 300dpi 的图像在屏幕上的渲染效果与其较低分辨率的兄弟图像相同,只是加载速度会更慢。

以下是一种识别目录中分辨率不正确的图像的方法


#!/bin/sh
identify=/usr/bin/identify
# check images to ensure that they're all 72x72 resolution.
for filename
do
  resolution=$($identify -verbose $filename | \
     grep -i "Resolution:" | grep -v 72x72)
  if [ ! -z "$resolution" ] ; then
    echo "Warning: Image $filename has $resolution"
  fi
done
exit 0

当我在我自己的系统上的图像目录(我的 http://www.AskDaveTaylor.com 网站上的一组 JPEG 格式文件)上运行此命令时,我得到以下结果


$ checkres.sh *.jpg
Warning: Image auction-seller-img1.jpg has Resolution: 75x75
Warning: Image auction-seller-img2.jpg has Resolution: 75x75
Warning: Image browsing-the-photo-folder.jpg has Resolution: 96x96
Warning: Image brushed-metal.jpg has Resolution: 300x300
...

这是一个惊喜!我没有意识到我有 300x300 和这些其他奇怪的分辨率。因此,加快我的网站速度的一种简单方法是将这些图像的分辨率降低到标准的 72dpi。这也是可以使用另一个 ImageMagick 实用程序来完成的,但让我们在另一篇文章中解决这个问题。

处理图像大小

由于我编写了很多脚本来从网站收集图像或其他内容,并将其重新用于我自己的(通常是私有的,不对外公开的)用途,因此我发现在 shell 脚本中能够确定我刚抓取的图像的大小也非常有帮助。

如果您猜到 identify 是关键,那么您是对的。事实上,给定一个图像,这是一种获取其高度和宽度的简单方法


height=$(identify $image | cut -d\   -f3 | cut -dx -f1)
width=$(identify $image | cut -d\   -f3 | cut -dx -f2)

不需要详细输出,因为图像的几何形状包含在默认输出中。

现在可以轻松生成更高质量的 HTML,例如,通过包含具有正确尺寸的图像


echo "<img src=$image height=$height width=$width>"

更好的是,Web 浏览器能够自动缩放图像,因此如果您指定的 height 和 width 与图像的默认尺寸(哎呀,抱歉,“几何形状”)不同,它会自动缩放。

这意味着如果我想在自动生成的页面上包含 pvp.jpg 图像,但认为 970 像素太宽,我可以简单地将其包含为


<img src=pvp.jpg height=207 width=646>

浏览器(无论是 Chrome、Safari 还是甚至 MS IE)都会对其进行适当的缩放。

使用 bc(另一个被低估的 Linux 命令)计算较小的尺寸很简单。整个序列可能如下所示,将图像缩放到其原始尺寸的 66%


#!/bin/sh
identify=/usr/bin/identify
scale=0.666
image=$1   # add input validation code

height=$($identify $image | cut -d\   -f3 | cut -dx -f1)
width=$($identify $image | cut -d\   -f3 | cut -dx -f2)
newwidth="$(echo $width \* $scale | bc | cut -d. -f1)"
newheight="$(echo $height \* $scale | bc | cut -d. -f1)"
echo "<img src=$image height=$newheight width=$newwidth>"
exit 0

在实际使用中


$ scaledown.sh pvp.jpg
<img src=pvp.jpg height=646 width=207>

这很简单!

凭借一些创造力,您可以看到,即使只是 ImageMagick 附带的 identify 命令也开启了图像文件脚本可能性的世界,无论您是直接处理网站还是只是寻求分析图像目录以查找异常值或设置。

在接下来的文章中,我将深入探讨一些真正巧妙的编辑和修改功能,包括一种简单的方法来为您的图形添加所谓的水印,以及您可以自动化修复 300dpi 分辨率图像甚至缩放图像的方法。

作为最后的说明,尽管我解释了如何使用不同的 height 和 width 值来使大图像在网页上显示得更小,但我不得不提的是,如果您只使用较小的尺寸,那么调整原始图像的大小会更明智。这可以使您的页面加载更快,传输更少不必要的数据,并且一切都会更愉快(包括搜索引擎)。现在您知道了。

Dave Taylor 长期以来一直在 UNIX 和 Linux 系统上编写 shell 脚本。他是 Learning Unix for Mac OS XWicked Cool Shell Scripts 的作者。您可以在 Twitter 上找到他,账号为 @DaveTaylor,您可以通过他的技术问答网站联系他:Ask Dave Taylor

加载 Disqus 评论