ImageMagick单次调用中的多个操作

Mic*_*ael 3 imagemagick imagemagick-convert

我试图让ImageMagick在一次调用中执行多个操作(在本例中为crop),但似乎不可能.例如,我可以裁剪,旋转,然后另一个裁剪作为两个单独的命令:

$ convert test.jpg -crop 223x187+588+757 -rotate 330 crop2.jpg 
$ convert crop2.jpg -crop 200x100+43+87 crop3.jpg
Run Code Online (Sandbox Code Playgroud)

但是如果我尝试将它们组合成一个命令,我会收到一个错误:

$ convert test.jpg -crop 223x187 + 588 + 757 -rotate 330 -crop 200x100 + 43 + 87 crop3.jpg convert:geometry不包含图片`test.jpg'@ warning/transform.c/CropImage/666.

显然我可以创建一个管道,但如果可能的话,我想避免多个进程的额外开销.有没有办法做到这一点?

更新:此外,管道似乎有问题:我不想要额外的压缩/解压缩阶段,所以我尝试将其管道为RGB,但我似乎无法正确获取参数:

convert test.jpg -crop 223x187+588+757 -rotate 330 rgb:- | convert -size 287x273 -depth 8 rgb:- -crop 200x100+43+87 crop3.jpg
convert: unexpected end-of-file `-': No such file or directory @ error/rgb.c/ReadRGBImage/231.
Run Code Online (Sandbox Code Playgroud)

好的,所以事实证明上面的错误是因为我计算的图像大小与ImageMagick的计算相差两个像素.因此,显然必须尝试使图像大小计算与IM完全相同,这是管道两个命令的需要引入的额外问题.

Kur*_*fle 16

这是一个更通用的问题方法.

ImageMagick提供了一些巧妙的技巧,有助于优化处理速度......

  1. ...你想处理大图像和
  2. ...当您想要从同一原稿创建不同的输出时.

有不同的方法甚至可以组合:

  1. 利用ImageMagick的特殊mpr:{label}格式和语法.这告诉ImageMagick暂时将输入图像保存到一个命名的magick程序寄存器标签中.(我也看到它被解释为magick持久性(存储器)寄存器存储器程序寄存器.)然后命令管道可以稍后(在处理时)从那里读取图像数据比从硬盘读取更快.并且命令可以根据需要多次读取它.
  2. 利用ImageMagick的特殊mpc:{name}格式和语法.这类似于mpr:.它的长名称是magick像素缓存.我也把它看作magick持久性(磁盘)缓存.MPC是ImageMagick 的本机内存中未压缩文件格式,但转储到磁盘.一旦写入磁盘,它就可以比JPEG,TIFF或PNG更快地重新读入内存,因为不需要转换.
  3. 构造一个聪明的命令序列.使用"侧向"处理,\( ... \)在适当的情况下使用转义括号中的语法.

MPC

convert命令读取输入图像(JPEG,TIFF,GIF,PNG ......它当前可能采用的任何格式)时,它首先将此格式处理为MPC.

此处理结果作为未压缩的栅格格式保存在RAM中.从那里进行进一步的转换和图像处理.如果要将MPC写入磁盘作为MPC,可以使用+write mpc:myfilename.这基本上只是直接内存转储到磁盘.

ImageMagick然后写两个,而不是一个(并且比通常更大)二进制文件:myfilename.mpcmyfilename.cache.该.mpc文件保存图像的元数据,.cache保存实际的像素缓存数据.

从该磁盘文件中读取的是根据需要从磁盘到内存的快速内存映射(类似于内存页交换).但由于初始+write操作确实存储了本机未压缩的内部IM本机栅格格式,因此现在不需要图像解码.

所以这可以更快(特别是对于大图像)使用,如果您无法避免写入需要再次读入的临时文件. 但是,请小心磁盘空间.一旦不再需要磁盘上的MPC文件,请记得清理.IM不会自动+write为您跟踪您的命令.

(更多技术细节:MPC作为磁盘文件格式不可移植.它也不适合作为长期存档格式.它唯一的适用性是作为高性能图像处理的中间格式.它需要两个文件来支持一个图像.在ImageMagick版本之间不能保证"稳定".它可能无法在与您创建它的机器不同的机器上工作.)

如果您仍想将此格式保存到磁盘,请记住:

  • 图像属性将写入扩展名为.mpc的文件.
  • 图像像素被写入扩展名为.cache的文件中.

MPC的主要优势在于......

  1. ...处理非常大的图像,或者何时处理
  2. ...在"操作管道"中对同一个图像应用多个操作.

MPC专门针对符合"多次读,写一次"标准的工作流模式而设计.

MPR

MPR格式(存储器持久寄存器)与MPC类似.它通过命名的内存寄存器使图像可用.您可以使用您想要的任何名称(偶数).如果需要,您的流程管道也可以从该寄存器再次读取图像 - 甚至多次.图像将mpr:label保留在寄存器中,直到当前命令管道退出.(这与磁盘写入的区别在于mpc:filename.这会持续完成当前管道;它甚至可以在系统重新启动后继续存在.)

聪明的命令管道

(我在这里使用'管道'这个词不要与shell中的管道相混淆,因为shell中有多个命令和进程被启动和链接.这里我只讨论一个单独的调用,convert它将多个图像操作和操作链接到一个处理.)

因此,可以完成所有调整大小,裁剪,追加,缩略图,颜色操作,模糊,...在一个单一过程中执行什么操作,写出您需要的不同中间输出.

实际例子......

......嗯,我不太知道这是SOOOO实用.我没有对它进行过测试,我只是用我的幻想来构建一个示例,该示例显示了不同概念的使用原则.

注意:+write someimage是一样的-write someimage +delete.

convert \
    very-very-large.jpg \
   -write mpr:XY \
   +delete \
   -respect-parentheses \
     \( mpr:XY -crop '3000x2001+0+491' -resize '170x116!>'   +write pic1.png   \) \
     \( mpr:XY -crop '2981x2883+8+0'   -resize '75x75!>'     +write pic2.png   \) \
     \( mpr:XY -crop '1100x1983+0+0'   -resize '160x160!>'   +write pic3.png   \) \
     \( mpr:XY -crop '2000x2883+0+0'   -resize '1024x960!>'  +write pic4.png   \) \
     \( mpr:XY -crop '1000x2883+0+0'   -resize '190x188!>'   +write mpr:pic5   \) \
     \( mpr:pic5                                             +write pic5.png   \) \
     \( mpr:XY -crop '3000x2000+0+0'   -resize '2048x2047!>' +write pic6.png   \) \
     \( mpr:XY -crop '3000x2883+0+0'   -resize '595x421!>'   +write pic7.png   \) \
     \( mpr:XY -crop '3000x2883+0+0'   -resize '3000x2883!>' +write mpr:AB     \) \
     \( mpr:AB                                               +write pic8.tiff  \) \
     \( mpr:AB -blur 0x8                                     +write blur1.gif  \) \
     \( mpr:pic5 mpr:AB +append mpr:pic5 -append             +write append.jpg \) \
     \( mpr:pic5 -rotate -130 mpr:AB -gravity center                              \
                 -compose difference -composite +write final.png               \) \
null:
Run Code Online (Sandbox Code Playgroud)

在第一次操作之后,-write mpr:XY堆栈中有两个图像:

  1. 输入文件very-very-large.png,和
  2. 它的副本,可以使用其标签从内存中读取XY.

我们不再需要这两个中的第一个了.因此我们使用+delete它从堆栈中删除它.

所以这个命令所使用的一个单一的命令管道,其在一气呵成进行多个命令和操作创建11个不同的输出图像: pic{1,2,3,4,5,6,7}.png,blur1.gif,pic8.tiff,append.jpgfinal.png.


Kur*_*fle 7

Quick'n'dirty回答:+repage你的第一个命令中插入一个:

    convert test.jpg             \
           -crop 223x187+588+757 \
           -rotate 330           \
           +repage               \
           -crop 200x100+43+87   \
            crop3.jpg
Run Code Online (Sandbox Code Playgroud)

长而全面的回答:将会跟进.我必须先完成另一项任务.较长的答案将为您提供更通用的方法,如何在一个命令中裁剪多个部分,同时保持性能.