ImageMagick命令行使用方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ImageMagick命令行使用方法相关的知识,希望对你有一定的参考价值。

参考技术A ImageMagick 的命令行由下面这些元素构成:

一个, 或多个文件名.
零个, 一个, 或多个图像设置项.
零个, 一个, 或多个图像操作项.
零个, 一个, 或多个图像序列操作项.
零个, 一个, 或多个图像组.
零个, 或一个图像输出名(convert, composite, montage, compare, import, conjure).

ImageMagick 扩展了“输入文件名”它原本的含义, 现在它包括了:

文件名通配符.
明确的图片格式.
内置图像或图案.
标准的输入输出, 文件描述符.
选取图片的某些帧.
选择图片部分区域.
缩放了的内嵌图像.
裁切了的内嵌图像.
文件名引用.

在 Unix shell 环境下, 有一些特殊的字符是作为通配符使用的, 如 * 和 ? . ImageMagick 在各个平台上都支持文件名通配符. 假如你想把某目录下的 1.jpg, 2.jpg, 3,jpg, 4.jpg 和 5.jpg 这些文件转成一个 GIF 动画, 那么你可以使用这条命令方便地引用所有的 JPEG 文件:

图像的数据, 都是以一种确定的格式存储的, 比如常见的 JPEG, PNG, TIFF 等. ImageMagick 在读取, 解析图片之前, 必须要知道图片的格式.

多数图像格式, 在文件中都设有一些标识来表明它属于哪种格式. 如果没有, ImageMagick 会根据文件的扩展名来判断. 如 image.jpg 会告诉 ImageMagick 这是一张 JPEG 格式的图片. 某些情况下, ImageMagick 不知道图片的格式, 那么这时就需要手动指定了. 如, 我们有一张名为 image , 存储了 RGB 三原色位深原始信息的图片(未经过任何压缩的位图), ImageMagick 当然无法自己得知它是什么格式的图片, 所以, 这时就需要我们明确指定图片格式.

ImageMagick 有许多内置的图像和图案, 要使用 checkerboard 中的图案:

Unix 和 Windows 都支持通过管道来重定向输入输出. ImageMagick 支持从标准的输入输出流中读写图像数据, 由依次使用一个虚文件名 ‑ 来实现. 下面的例子把 convert 的输出通过管道重定向到了 display .

第二个用于确定图像格式的 gif: 是可选的, 因为 GIF 这种格式有自己的标识, ImageMagick 认识它. convert 同样能以这种方式接受标准输入:

其它的一些管道, 你可以通过它们的文件描述符来访问. 文件描述符0, 1, 2已经被预定义为标准输入, 标准输出, 错误输出. 如果一个管道被指定为文件描述符 N, 那么你可以通过 fd:N 来使用它. 下一个例子展示了如何通过管道重定向, 把文件描述符3, 4的数据添加到文件描述符5中.

ImageMagick 6.4.9-3 中才添加了对文件描述符的支持.

对于 Python, 你可以通过调用 File 对象的 fileno() 方法来获取文件描述符.

在需要的时候, 你也可以为文件描述符指定具体的图像格式:

某些图片格式可以包括有多个图像帧. 你可以只获取第一帧, 最后一帧, 或中间的某些帧. 为此, 你可以在文件名之后, 以方括号括起来的形式指定帧. 下面的例子中, 对于一个有多帧的 GIF 图片, 我们只取其第一帧.

在 Unix shell 的环境下, 一般中括号是会被转义的, 所以, 我们需要使用单引号把文件名引起来. Windows 的命令行环境下不用单引号也可以, 但多写一对单引号并不会有什么问题. 另外, 对于单引号和双引号的作用, 在 Unix 和 Windows 这两个平台上, 常常是相反的, 所以, 如果你使用 Windows ,那么请注意将我们例子中的单引号改为双引号.

你也可以一次获取多帧, 在方括号中标出一个范围即可, 如下面的例子, 我们获取了前四帧的图像:

最后, 你可以一次获取非连接的多帧. 下面的命令以3,2,4的顺序获取图像:

注意上面的最后两个命令, 输出被写入了一个类型为 MNG 的文件当中. 因为 MNG 支持保存多帧图像, 而如 JPG 之类的格式只是保存单帧的图像. 在下面“图像输出名”一节我们还会介绍这方面的内容.

最原始的位图图像, 就是一个表示出各像素点颜色的序列, 它的文件中没有任何的其它像宽, 高, 格式标识等附加信息. 对于这类原始的图像数据, 在处理时我们必须明确指定图像的宽和高, 或者给出一个范围. 在下面的例子中, 我们要处理的图片是一个8位的 RGB 位图, 宽是 6000, 高为 4000, 而我们只需要获取一块中心附近 600×400 的图像信息.

使用 ‑extract 选项也可以实现相同的功能:

读入一些图片的同时, 重新定义它们的尺寸是很方便的. 假设你有很多的大的 JPEG 图片需要转换成一组 PNG 格式的缩略图:

这里, 所以的图片都会被读入并且分别被重定义大小. 在读入的同时定义尺寸在效率上更好, 同时资源占用也更少:

同上.

靠一个另外的文件名, 来表示实际要读取的图像文件名, 实现这个功能有两种方法, 第一种方法是使用 @ 这个符号, 来指定一个文件, 这个文件中包含有实际需要读取的图像文件名, 如一个名为 myimages.txt 的文本文件中有如下内容:

下面的命令, ImageMagick 就会读入 frame001.jpg, frame002.jpg, frame003.jpg .

另一种方法, 是在文件名中使用格式化字符串, 然后在后面的方括号中指定一个范围. 看下面的例子:

ImageMagick 实际上会去读取如下的图像:

命令行中的一个设置项, 可以作用于读入的图像, 图像操作, 或者将会被输出的图像. 一个设置项被设置后会一直发挥作用除非它被重置或命令执行完毕. 图像设置命令包括有:

下面例子中的 ‑channel 会被作用于每一个图像, 就像我们说的那样, 设置项会持续起作用.

图像操作项与图像设置项不同, 它只作用于紧接着存在的一个图像, 仅仅是这一个图像, 之后, 图像操作项就会失效. 在这里, 我们说明一下. 命令行参数有三种, 前面讲过的图像设置项, 这里的图像操作项, 以及后面会讲到的序列操作项. 图像操作项包括下面这些.

下面例子, ‑negate 这项只对 wand 有效, 对 wizard 是无效的(但是, 如果把它放在 wizard 后的话, 则会作用于这两张图).

一个图像序列操作项, 只作用于紧接着存在的一个图像序列, 它们是.

许多命令行选项都有一个 geometry 参数, 用于指定图像的宽, 高等信息. 因为图像的坐标系, 尺寸, 位置等信息是我们经常会用到的, 所以为了方便, geometry 这个参数可以用不同的格式给出. 关于这点, 接下来我们会详细地介绍.

一些命令行选项可接受如下多种格式的 geometry 参数. 请记住, 它们处理具体参数时的效果是不同的, 详细的内容可查阅它们各个的说明文档.

geometry 参数可以使用下表列出的多种格式指定. 最常用的一种格式是 size[offset] , 意为 size 是必须给出的, 而 offset 则是可选的. 不过, 有时 [size]offset 也行. 同时要注意, geometry 这个参数中, 绝不允许出现空格符.

下面展示了一些简单的例子, 用以说明如何给出 ‑resize 的 geometry 参数. 我们将使用内置的 logo: 这张图作为我们的“输入图像”. logo: 这张原始图片宽为640像素, 高480像素, 记为 640×480. 就像你看到的, 宽总在高的前面. 这条规则同样适用于我们可能会讲到的“坐标”或“偏移”.

看一些例子:

(@的作用前面已经提到过了)

请注意引号的使用. 上面的例子, 包括后面的例子中, 我们都使用引号把 geometry 引起来了的. 很多时候, 这样做不是必须的, 但当你使用了 < 和 > 的时候, 就一定要使用引号, 否则这两个符号会被当成命令行的重定向操作处理. 另外, 在 Windows 平台上, ^ 也必须使用引号. 所以, 为了安全起见, 我们最好养成对于 geometry 总是使用引号的习惯.

我们通过一些例子来说明 geometry 参数中的 offsets. 使用它的一个典型情形是在 ‑region 这个选项中. ‑region 跟在一些其它的命令后, 用于指定一块矩形区域. 所以, 你除了需要指定这个矩形区域的宽和高, 还需要指定它的一个起始点(左上角的点). 下面的第一个例子中, 我们指定了一个 100×200 的区域, 位置在 x=10, y=20, 或者我们应该写成 (x,y) = (10,20).

注意, offsets 必须带上 +/‑. 它表示的是一个相对偏移, 而不是一个绝对坐标. offsets 的参照点不是固定的, 但默认情况下, 它是 (0,0), 即左上角, 上面的第一个例子就是这种情况.

offsets 有可能“出界”, 就像第二个例子中的那样, -10+20, 对于这个有一部分出界的矩形执行 ‑negate, 实际的效果也就相当于 90×200+0+20.

第三个例子中, 一来就使用了 ‑gravity 选项, 它把当前坐标原点(或叫参照原点)设置为图像的正中, 即 (320,240) 的位置, 因为这张图的尺寸是 640×480. 这意味着后面的 offsets 的实际效果与前面两例就有所不同, 变成了 (320-10, 240+20) = (310,260). 同时 100×200 也不再是根据左上角来计算, 而是根据中心点计算. 即以 (310,260) 为中心的一个 100×200 的矩形. 显然, 它的左上角在 (310-50,260-100) = (260,160).

它让你在一个隔离的组中处理一张图像或一个图像序列, 处理完后, 把结果返回到正常流程中. 图像组用一对括号标示, 里面的所有操作只对当前组有效. 如下例, 我们限制 ‑rotate 操作只对 wizard.gif 有效:

特别注意, 在 Unix 平台下, 用于图像组的括号是需要使用 \ 转义的, 因为小括号在 shell 中有其它的特殊作用. 但是, Windows 平台下的小括号不需要转义. 另外, 在小括号内的两侧, 都有一个空格, 请留意.

前面我们已经谈到了一些命令行中的操作项, 不过, 下面这几个操作项对于处理一个图像组是比较常用的:

上面几个操作项的参数, 都是一个索引值, 用以表示在图像组中的某个图像. 图像组中的第一个图像的索引值是 0. 同时, 这个索引值你也可以使用负数, -1 就是图像组中的最后一个图像.

ImageMagick 扩展了原来的“输出文件名”的概念, 在 ImageMagick 中, 一个图像输出可以是:

一种明确的图像格式.
输出到系统的标准输出.
文件名引用.

图像信息都是以某种即定的格式存储起来的, 这些格式包括我们熟悉的 JPEG, PNG, TIFF 等. ImageMagick 在写出某个图像时, 必须知道应该使用哪一种格式写出. 通常情况下, ImageMagick 可以根据扩展名来判断格式, 如, 对于 image.jpg ImageMagick 会以 JPEG 格式来写出. 某些情况下没有给出图像的格式信息, 而你又没有明确指定, 这时, ImageMagick 会以图像原来的格式写出. 比如, 我们希望把图像存为名为 image 的原始 RGB 位图:

Unix 支持通过管道在各个程序间重定向输入输出. ImageMagick 可以使用一个特殊的文件名 ‑ 来实现管道间的重定向操作. 下面的例子中, 我们把 convert 的输出重定向到 display 中:

这里, 你不一定要明确指定图像格式, GIF 这种格式有它自己的标示, ImageMagick 可以自动正确地识别出.

另外还有一种输出方式, 是使用格式化字符串来输出多个图像. 假如我们把输出图像名写成 image‑%d.jpg , 同时我们的图像序列中有 3 个图像, 那么会得到如下的多个输出结果:

还有一种情况, 假如你希望用图像的某些属性来作为其文件名的一部分, 那么可以这样:

其结果是:

PHP Imagick:转换 ImageMagick 命令行代码的问题

【中文标题】PHP Imagick:转换 ImageMagick 命令行代码的问题【英文标题】:PHP Imagick: problem converting ImageMagick command-line code 【发布时间】:2020-04-20 14:04:20 【问题描述】:

我在 Windows 8.1 上使用 ImageMagick 7.0.8-66 Q16 x64 我的 PHP 在 XAMPP 上是 7.4.1。

我已经在 PHP 中使用 exec() 成功运行了以下命令:

convert _temp_.jpg 
( +clone -background black -shadow 88x3+2+2 ) 
+swap -background none -layers merge 
+repage -background #eeeeee -layers flatten 
+repage -shave 3x3 
( -size 100x100 xc:#eeeeee ) 
+swap -gravity northwest -geometry +5+5 -compose over -composite output.jpg

它需要一张图片,调整它的大小以适应 100x100 的缩略图,然后在中性的 #eeeeee 背景画布上为图片添加阴影。它有效。

我想重写它以使用 Imagick PHP 扩展,但我在翻译它时遇到了麻烦。这是我翻译它的方式(带有注释),但它不起作用:

// convert _temp_.jpg 
$im = new imagick();
$im->readImage('_temp_.jpg');

// ( +clone -background black -shadow 88x3+2+2 ) 
$im_clone = clone $im;
$im_clone->setImageBackgroundColor('black');
$im_clone->shadowImage(88, 3, 2, 2);

// +swap -background none -layers merge 
$im->setImageBackgroundColor('none');
$im->addImage($im_clone);
$im->mergeImageLayers(imagick::LAYERMETHOD_MERGE);

// +repage -background #eeeeee -layers flatten 
$im->cropImage(88, 88, +5, +5);
$im->setImagePage(88, 88, 0, 0);
$im->setImageBackgroundColor('#eeeeee');
$im->mergeImageLayers(imagick::LAYERMETHOD_FLATTEN);

// +repage -shave 3x3 
$im->cropImage(88, 88, +5, +5);
$im->setImagePage(88, 88, 0, 0);
$im->shaveImage(3, 3);

// ( -size 100x100 xc:#eeeeee )
$im_pseudo = new Imagick();
$im_pseudo->newPseudoImage(100, 100, 'xc:#eeeeee');

// +swap -gravity northwest -geometry +5+5 -compose over -composite output.jpg
$im->setImageGravity(imagick::GRAVITY_NORTHWEST);
$im->compositeImage($im_pseudo, Imagick::COMPOSITE_OVER, 5, 5);

$im->writeImage('output.jpg');

我错过了什么?

源图片:

结果图片:

【问题讨论】:

什么不起作用?在我进入下一步之前,我会完成每一步并让它发挥作用。我会尝试更改的一件事是将“”更改为“” 我已经做到了。当我只处理与“convert temp.jpg ( +clone -background black -shadow 88x3+2+2 ) +swap -background none -layers merge ”对应的部分时,结果不一样.此外,使用单引号和双引号没有区别。 你应该附上你的输入图像和预期的输出图像以及你得到的结果。 完成。见上文。 也许您可以添加它的外观。 【参考方案1】:

正如我所说,如果您按步骤进行,您可以看到正在发生的事情。这是来自 php Imagick 手册并创建了阴影:

/* Read the image into the object */ 
$im = new Imagick( 'DOqeZ.jpg' ); 
$im->setImageFormat("png"); 

/* Make the image a little smaller, maintain aspect ratio */ 
$im->thumbnailImage( 200, null ); 

/* Clone the current object */ 
$shadow = $im->clone(); 

/* Set image background color to black 
        (this is the color of the shadow) */ 
$shadow->setImageBackgroundColor( new ImagickPixel( 'black' ) ); 

/* Create the shadow */ 
$shadow->shadowImage( 80, 3, 5, 5 ); 

/* Imagick::shadowImage only creates the shadow. 
        That is why the original image is composited over it */ 
$shadow->compositeImage( $im, Imagick::COMPOSITE_OVER, 0, 0 ); 

/* Display the image */ 
$shadow->writeImage('shadow.png');

更新: 我想我会让你看看你能不能做剩下的事情

创建背景和合成它应该可以工作,但范围应该更好。我还有其他事情要做,但下面有一些更新的代码供您使用:

/* Read the image into the object */ 
$im = new Imagick( 'DOqeZ.jpg' ); 
$im->setImageFormat("png"); 

/* Make the image a little smaller, maintain aspect ratio */ 
$im->thumbnailImage( 80, null ); 

/* Clone the current object */ 
$shadow = $im->clone(); 

/* Set image background color to black 
        (this is the color of the shadow) */ 
$shadow->setImageBackgroundColor( new ImagickPixel( 'black' ) ); 

/* Create the shadow */ 
$shadow->shadowImage( 80, 3, 5, 5 ); 

/* Imagick::shadowImage only creates the shadow. 
        That is why the original image is composited over it */ 
$shadow->compositeImage( $im, Imagick::COMPOSITE_OVER, 0, 0 ); 

/* Create the background image 100x100 with a background colour */
/* Gravity seems to have no effect  */
/* $shadow->setImageGravity(imagick::GRAVITY_CENTER);*/
$shadow->setImageBackgroundColor( '#eeeeee' );
$height = $shadow->getImageHeight();
$width =  $shadow->getImageWidth();
$shadow->extentImage( 100, 100, (((100 - $width)/2)*-1 ), (((100 - $height)/2)*-1 ));    

$shadow->writeImage('shadow.jpg');

**** 更新代码以使图像居中并使用十六进制值作为颜色****

【讨论】:

我不知道您是否理解所需的结果是调整输入图像的大小以保持纵横比但适合(在顶部)100x100 灰色背景。您在上面创建的内容很可爱,只是它只是一个带有阴影的图像。我的例程的目标(以及它在命令行版本中正确获得的结果)是原始的纵横比保留调整大小,阴影漂浮在中性灰色背景之上,因此所有步骤我的命令行过程。 ...并且“漂浮在中性灰色背景之上”我的意思是背景是合成图片的一部分。保存我上面提供的第二张图片,你会看到。

以上是关于ImageMagick命令行使用方法的主要内容,如果未能解决你的问题,请参考以下文章

通过 ImageMagick 或 GhostScript 命令行旋转 .EPS 文件

Imagemagick魔杖使用深度不像命令行

ImageMagick 命令行:将 PDF 转换为高清图像

使用 ImageMagick 调整大小,然后从命令行裁剪图像

图片处理命令行工具ImageMagick介绍

尝试使用 ImageMagick 制作 9 张图像的 3 x 3 蒙太奇,但命令行命令出错