在 IBM Bluemix 云平台上开发并部署您的下一个应用。 本文展示了如何使用命令行工具执行图像操作。这种任务对我而言相当常见,因为我拥有几部数码相机,并且现在管理着一个拥有几千张精彩照片的资料库。对于经常需要对大量图像进行批处理的 Web 开发人员和管理员而言,命令行工具是特别具有吸引力的选择,因为开发人员可以将它们合并成脚本。但即使您只想执行一两次操作,选择命令行也可以节省时间。 本文中讨论的命令行工具是优秀的 ImageMagick 套件的一部分,该套件是随 Red Hat Linux 一起提供的,并可免费在线下载(请参阅 参考资料)。也可以通过 C、C++、Perl、Python、Java 和其它几种语言使用 ImageMagick,Linux 程序员会喜欢这样做。 请注意,有许多种方法可以完成本文中所讨论的任务。我讨论了我所使用的方法,它对我确实很有效。这并不意味着除此之外的其它工具就很差劲;仅仅表示我对于现在所使用的工具很满意。 本文采用了以具体问题作为示例进行讨论这种形式,但其思想应该也适用于其它问题领域。 生成缩略图我对照片集所执行的第一个操作是生成缩略图。我还想减少图像的大小,以适用于网站版本因为许多人实际上并不想看到我儿子的 1920 x 1440 像素的照片。 ImageMagick 是如何工作的ImageMagick 是作为包含了一大堆不同的图像处理库的包装器实现的,这些图像处理库包括 libtiff 和 libpng(请参阅 参考资料以获取我先前所著的关于 libtiff 文章的链接)。在 ImageMagick 术语中,这些库称为 代表(delegate)。这是 ImageMagick 不如定制应用程序执行得那么快的原因之一;它必须以一种通用方式编写,该方式可以处理这些库表示图像数据的不同方法。 我使用
让我们假定我希望为这幅非常美丽的玫瑰图像制作缩略图: 图 1. 玫瑰的照片要用
# convert -sample 80x40 input.jpg output.jpg 这生成了如下的缩略图: 图 2. 生成缩略图的第一次尝试ImageMagick 会自动地考虑在缩放图像大小时图像的两条邻边所产生的比例。这意味着新的图像的高宽比与原图相同。在上面的示例中,这意味着缩放后的图像实际上是 53 x 40 像素,而不是所要求的 80 x 40 像素。指定输出图像大小的另一种方法是使用百分数。如果您不能确定输入图像的大小,或者并不是刻意地要得到确切大小的新图像,那么这种方法比较方便。以下是关于如何使用百分数的示例: # convert -sample 25%x25% input.jpg output.jpg 现在,我们得到了如下所示的缩略图: 图 3. 生成缩略图的第二次尝试使用该命令,您可以在某个目录中生成图像的缩略图。虽然本文并不是关于 shell 脚本编制的,但我会迅速地向您展示一个示例,以说明如何生成当前目录中每个 JPEG 的缩略图: 清单 1. 为当前目录中的所有 JPEG 生成缩略图for img in `ls *.jpg` do convert -sample 25%x25% $img thumb-$img done 这会生成一系列大小为实际图像 25% 的缩略图,其文件名称是在 JPEG 文件名的前面加上 thumb-前缀。 获取关于图像文件的信息另一个常见任务是确定图像文件的尺寸(dimension)。例如,您可能需要知道前一个示例中的缩略图有多大。 许多图像处理库提供了用于此用途的优秀工具。例如,libtiff(TIFF 库,我先前曾写过有关这个库的文章;请参阅
参考资料)提供了
# tiffinfo sample.tif 清单 2. tiffinfo 的样本输出TIFF Directory at offset 0x146 Image Width: 352 Image Length: 288 Bits/Sample: 8 Compression Scheme: Deflate Photometric Interpretation: RGB color Samples/Pixel: 3 Planar Configuration: single image plane 这并不是一个关于如何使用
类似地,有一个返回 PNG 文件的类似信息的
# pnginfo sample.png 清单 3. pnginfo 的样本输出sample.png... Image Width: 640 Image Length: 480 Bitdepth (Bits/Sample): 8 Channels (Samples/Pixel): 3 Pixel depth (Pixel Depth): 24 Colour Type (Photometric Interpretation): RGB Image filter: Single row per byte filter Interlacing: No interlacing Compression Scheme: Deflate method 8, 32k window Resolution: 0, 0 (unit unknown) FillOrder: msb-to-lsb Byte Order: Network (Big Endian) Number of text strings: 0 of 0 我不清楚是否存在用于其它格式(诸如 BMP、GIF 和 JPEG)功能相当的单个工具。但是,ImageMagick 又一次帮了我们的忙,这次是使用名为
# identify -verbose sample.png 清单 4. identify 的样本输出Image: sample.png Format: PNG (Portable Network Graphics) Geometry: 640x480 Class: DirectClass Type: true color Depth: 8 bits-per-pixel component Colors: 142360 Filesize: 555.6k Interlace: None Background Color: grey100 Border Color: #DFDFDF Matte Color: grey74 Dispose: Undefined Iterations: 0 Compression: Zip signature: 361fe70ae623ef6f1fca44e0d29d157c2d701039fcf0f8625862925d881e13a4 Tainted: False User Time: 0.190u Elapsed Time: 0:01 您可以看到
pnginfo当我开始使用 PNG 时,我成为 libtiff 用户已经有相当长一段时间了。当时,没有与
# identify -format "%wx%h" sample.png 输出类似于: 640x480 此处,
旋转图像另一种经常需要用到的图像操作是旋转图像。例如,我用数码相机所拍摄的许多照片都旋转了九十度,因为我是把相机竖过来拍摄它们的。相机不会为我旋转这些照片,因此我编写了一个脚本,以便在从相机下载这些图像之后完成旋转任务。 例如,这是我在最近去塔斯马尼亚岛的亚瑟港旅游时拍摄的一幅照片: 图 4. 横卧的亚瑟港为了旋转该照片,我们再次求助于
# convert -rotate 90 input.jpg output.jpg 该命令生成了如下所示的图像: 图 5. 亚瑟港请注意
更改图像的格式
在我撰写本文时,ImageMagick 支持 89 种图像格式。查看 ImageMagick 网站(请参阅 参考资料)以获取更多信息。 向图像添加文本注释有时您需要向图像添加文本注释。例如,假设您的公司拥有标准的名片图像,并希望在将名片发送到打印机之前将每个雇员的详细信息都添加到名片上面。另一个示例是为通过您网站上的在线课程的用户生成表示证书(presentation certificate)。 让我们假定您从这幅图入手: 图 6. 2002 年芙萝莉雅蝶园艺博览会(FLORIADE 2002)照片您可以使用下列命令行,为该图注释一些标识信息: # convert -font helvetica -fill white -pointsize 36 这里是结果: 图 7. 加注释的 2002 年芙萝莉雅蝶园艺博览会照片迄今为止,这是我在本文中所展示的最复杂的
以下是结果: 图 8. 带标记的图像
其它更富艺术性的转换
图 9. 乌奴奴(Uluru)夕照这张乌奴奴(以前称为艾尔斯岩(Ayers Rock))的照片是在日落时分照的。 炭笔炭笔效果模拟出该图像的素描画。 # convert -charcoal 2 input.jpg output.jpg 其结果如下所示: 图 10. 应用炭笔效果之后的乌奴奴夕照增加
# convert -charcoal 10 input.jpg output.jpg 它产生了如下结果: 图 11. 应用更多炭笔效果之后的乌奴奴夕照如果您真的想近乎疯狂地使用大量炭笔: # convert -charcoal 200 input.jpg output.jpg 您会得到这样的结果: 图 12. 应用过量炭笔效果之后的乌奴奴夕照指定三个值要指定三个值,每个值分别代表红色、绿色和蓝色三个采样,使用
red/green/blue 形式的参数。例如,
着色着色是将每个像素的颜色与指定颜色混合的过程。该效果的参数就是要用来混合的颜色。可以用一个百分数(它将分别用于红色、绿色和蓝色),也可以用三个百分数来指定这个参数。也可以提供三个实际值中的一个。 # convert -colorize 255 input.jpg output.jpg 以下是着色之后的乌奴奴: 图 13. 应用着色效果之后的乌奴奴夕照内爆(Implode)内爆效果模拟了您图像的中心被吸入虚拟黑洞的情形。所用的参数是您所期望的内爆效果量。 # convert -implode 4 input.jpg output.jpg 内爆的乌奴奴如下所示: 图 14. 内爆之后的乌奴奴夕照solarize 参数ImageMagick 文档声明
曝光曝光是在相片冲洗过程中把底片暴露在光线中所发生的效果。这里,输入参数是应用于该效果的亮度,可以指定为绝对值,也可以是可用于像素的最大可能值的百分数。如果像素超过阈值,则对它求反。 # convert -solarize 42 input.jpg output.jpg 在曝光之后,我们的图像如下所示: 图 15. 曝光之后的乌奴奴夕照发散
# convert -spread 5 input.jpg output.jpg 再次使用乌奴奴,这次是发散之后的情形: 图 16. 发散之后的乌奴奴夕照在一次 ImageMagick 调用中执行多条命令您已经看到了将命令与注释示例联系起来的示例。但是,可以将本文中提到的任意 ImageMagick 命令链接起来。例如,也许我们希望制作某图像的缩略图,然后对它应用发散。在发散发生之后,我们将应用炭笔效果: # convert -sample 25%x25% -spread 4 -charcoal 4 input.jpg output.jpg 这会产生: 图 17. 应用了一系列效果之后的乌奴奴图像操作技巧在迫不及待地动手修改您所拥有的每一幅图像之前,您应该记住一些关于图像操作的事情。首先,您应该考虑一下打算长期使用什么图像格式,免得最终有了一大堆某种格式的图像之后再来后悔就晚了。这一点特别容易做到,因为正如本文先前所讨论的,您可以使用
JPEG 压缩对于诸如照片之类的大图像很适合。但其压缩通常是 有损的(换句话说,在压缩过程中会丢弃图像数据)。这使得 JPEG 非常不适于压缩需要保持字迹清晰的文本。另一件需要牢记的事情是:损失是累积的。 如果您不希望在一系列操作之后产生的累积损失会影响到彩色图像的图像品质,通常 PNG 是个不错的选择。 有关该主题的更多信息,请参阅我所著的关于用 libtiff 处理彩色图像的文章“ Graphics programming with libtiff,Part 2”(请参阅下面的 参考资料中的链接)。 您还应该记住本文中所展示的大多数操作是单向的。例如,如果您将图像缩小了,则图像数据就丢失了。如果此后您再放大该图像,则输出将很粗糙。例如,让我们拍一幅照片,制作缩略图,然后再扩大该图像。为了节省一些篇幅,在此,我将只包括最初和最后的图像,而省略中间的缩略图。 图 18. 凯恩斯瀑布现在,我们将把缩小和放大操作链接在一起: # convert -sample 10% -sample 1000% input.jpg output.jpg 这产生了如下所示的图像: 图 19. 斑驳的瀑布很难在最终的图像中看出瀑布来,尽管分散您的眼光似乎有些帮助。 结束语在本文中我们讨论了一些有趣的事情,ImageMagick 可以完成这些任务以满足您的命令行图像处理需求。这里所描述的工具并不能解决所有问题,有时您会需要定制代码段,但是通用的命令行图像处理工具通常可以大幅度地减轻工作负担。 |
|