我试图让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完全相同,这是管道这两个命令的需要引入的额外问题。
答案 0 :(得分:16)
这是一个更通用的问题解决方法。
ImageMagick提供了一些巧妙的技巧,可以帮助优化处理速度......
有不同的方法甚至可以组合使用:
mpr:{label}
格式和语法。
这告诉ImageMagick将输入图像暂时保存到命名的 magick程序寄存器标签中。
(我也看到它被解释为 magick persistent(内存)寄存器或内存程序寄存器。)
然后,命令管道可以稍后(在处理时)从那里读取图像数据的速度比从硬盘读取的速度快得多。
并且命令可以根据需要多次读取它。mpc:{name}
格式和语法。
这类似于mpr:
。
它的长名称是 magick像素缓存。
我还将其视为 magick persistent(磁盘)缓存。
MPC是ImageMagick的本机内存未压缩文件格式,但转储到磁盘。
一旦写入磁盘,它就可以比JPEG,TIFF或PNG更快地重新读入内存,因为不需要转换。\( ... \)
语法。<强> MPC 强>
当convert
命令读取输入图像(JPEG,TIFF,GIF,PNG ......当前的格式)时,它首先将此格式处理为MPC。
此处理结果作为未压缩的栅格格式保存在RAM中。
从那里进行进一步的转换和图像处理。
如果要将MPC写入磁盘 作为MPC ,可以使用+write mpc:myfilename
。
这基本上只是直接内存转储到磁盘。
ImageMagick写入两个,而不是一个(并且比通常更大)的二进制文件:myfilename.mpc
和myfilename.cache
。
.mpc
文件保存图像的元数据,.cache
保存实际的像素缓存数据。
从该磁盘文件读取的是根据需要从磁盘到内存的快速内存映射(类似于内存页交换)。
但由于最初的+write
操作确实存储了本机未压缩的内部IM本机栅格格式,因此现在不需要图像解码。
所以这可以更快(特别是对于大图像)使用, IF 您无法避免编写需要再次读入的临时文件。
但是,请小心磁盘空间。
一旦不再需要磁盘上的MPC文件,请记得清理。
IM不会自动跟踪您的+write
命令。
(更多技术细节:MPC作为磁盘文件格式不可移植。 它也不适合作为长期存档格式。 它唯一的适用性是作为高性能图像处理的中间格式。 它需要两个文件才能支持一个图像。 不保证是稳定的#39;在ImageMagick发布之间。 它可能与您创建它的机器不同。)
如果您仍想将此格式保存到磁盘,请记住:
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
之后,堆栈中有两个图像:
very-very-large.png
和XY
从内存中读取的副本。我们不再需要这两个中的第一个了。
因此,我们使用+delete
将其从堆栈中删除。
所以这个命令使用了一个命令管道,它执行了多个命令和操作,一次创建了11个不同的输出图像:
pic{1,2,3,4,5,6,7}.png
,blur1.gif
,pic8.tiff
,append.jpg
和final.png
。
答案 1 :(得分:7)
快速回答:在您的第一个命令中插入+repage
:
convert test.jpg \
-crop 223x187+588+757 \
-rotate 330 \
+repage \
-crop 200x100+43+87 \
crop3.jpg
长而全面的回答:稍后会跟进。我必须先完成另一项任务。较长的答案将为您提供更通用的方法,如何在一个命令中裁剪多个部分,同时保持性能。