ImageMagick单次调用中的多个操作

时间:2015-04-19 21:33:30

标签: 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

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

  

$ 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.

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

2 个答案:

答案 0 :(得分:16)

这是一个更通用的问题解决方法。

ImageMagick提供了一些巧妙的技巧,可以帮助优化处理速度......

  1. ...您想要处理大型图片和
  2. ...当您想要从同一原稿创建不同的输出时。
  3. 有不同的方法甚至可以组合使用:

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

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

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

      然后,

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

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

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

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

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

      • 属性写入扩展名为 .mpc 的文件。
      • 像素写入扩展名为 .cache 的文件。
      MPC的主要优势在于......

      1. ...处理非常大的图像,或
      2. ...在&#34;操作管道&#34; 中对同一个图像应用多个操作。
      3. MPC专为符合标准的工作流模式而设计&#34;多次阅读,写一次&#34;

        <强> MPR

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

        聪明的命令管道

        (我使用了&#39;管道&#39;这里不要与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:
        

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

        1. 输入文件very-very-large.png
        2. 可以使用其标签XY从内存中读取的副本。
        3. 我们不再需要这两个中的第一个了。 因此,我们使用+delete将其从堆栈中删除。

          所以这个命令使用了一个命令管道,它执行了多个命令和操作,一次创建了11个不同的输出图像: pic{1,2,3,4,5,6,7}.pngblur1.gifpic8.tiffappend.jpgfinal.png

答案 1 :(得分:7)

快速回答:在您的第一个命令中插入+repage

    convert test.jpg             \
           -crop 223x187+588+757 \
           -rotate 330           \
           +repage               \
           -crop 200x100+43+87   \
            crop3.jpg

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