ImageMagick能否从一个输入生成多个输出?

3
我正在命令行中执行以下命令:

magick.exe input.png -shave '1x0' output_%d.png
magick.exe input.png -shave '2x0' output_%d.png
magick.exe input.png -shave '3x0' output_%d.png
magick.exe input.png -shave '4x0' output_%d.png
magick.exe input.png -shave '5x0' output_%d.png
magick.exe input.png -shave '0x1' output_%d.png
magick.exe input.png -shave '0x2' output_%d.png
magick.exe input.png -shave '0x3' output_%d.png
magick.exe input.png -shave '0x4' output_%d.png
magick.exe input.png -shave '0x5' output_%d.png

第一个命令创建了output_0.png,但是接下来的命令会覆盖同一个文件。 有没有一条命令可以生成output_0.pngoutput_9.png ImageMagick文档中提到:

Filename References

Optionally, use an embedded formatting character to write a sequential image list. Suppose our output filename is image-%d.jpg and our image list includes 3 images. You can expect these images files to be written:

image-0.jpg 
image-1.jpg
image-2.jpg

我找到的最接近证据表明在ImageMagick中可以实现我正在寻找的功能。我不确定是否需要利用shell脚本来完成这个操作,还是ImageMagick提供了命令行功能。


请查看此处的Method2 https://dev59.com/m2oy5IYBdhLWcg3wUcb_#51822265 - Mark Setchell
@MarkSetchell 谢谢!我无法确定您是否在暗示必须使用 shell 来完成此操作。 - Daniel Kaplan
1
不,我实际上建议你使用-write来创建每个文件,但是你已经有了GeeMack的好解决方案。 - Mark Setchell
我在思考 magick IMAGE -shave ... -write ... -shave ... -write ... -shave FINAL.PNG - Mark Setchell
2个回答

4

使用ImageMagick,您可以通过克隆输入并将操作隔离在括号中来在单个命令中对不同实例的输入图像运行多个操作,如下所示...

magick input.png \
   \( -clone 0 -shave '1x0' \) \
   \( -clone 0 -shave '2x0' \) \
   \( -clone 0 -shave '3x0' \) \
   \( -clone 0 -shave '4x0' \) \
   \( -clone 0 -shave '5x0' \) \
   \( -clone 0 -shave '0x1' \) \
   \( -clone 0 -shave '0x2' \) \
   \( -clone 0 -shave '0x3' \) \
   \( -clone 0 -shave '0x4' \) \
   \( -clone 0 -shave '0x5' \) \
   -delete 0 output_%02d.png

这将会创建10张输出图片,每个文件名都是按顺序编号并且数字用两位数表示,例如"output_00.png … output_10.png"。

要将此转换为Windows CMD语法,您可以删除转义括号的所有反斜杠,并将续行反斜杠 "\" 替换为插入符号 "^"。

编辑后添加:有许多方法可以使用ImageMagick完成此任务。以下是另一个示例命令,可以产生相同的结果,但它使用FX表达式,因此只能在IMv7中使用。(以上命令应该通过将“magick”更改为“convert”来在IMv6中使用。)

magick input.png -duplicate 9 -shave "%[fx:t<5?t+1:0]x%[fx:t>4?t-4:0]" output_%02d.png

该命令读取输入并将其复制9次,然后使用FX表达式作为-shave操作的参数,以便可以遍历所有10个图像,并根据FX表达式中的公式对每个图像进行修剪。


谢谢!实际上我正在使用WSL,你能把这个转换成bash语法吗?我认为这会帮助大多数阅读你答案的人。 - Daniel Kaplan
另外,让我确认一下我的理解是否正确:clone 操作创建了一个名为 0 的文件,output_%02d.pngshave 的输出文件名,而 -delete 0 在最后删除了克隆文件? - Daniel Kaplan
1
不,-clone 0会在内存中创建第零个图像的副本,即你加载的第一个图像。 - Mark Setchell
1
对于bash,使用反斜杠“\(...\)”转义所有括号,并将所有续行符“^”替换为反斜杠“\”。此外,“-clone 0”是一个新的副本(在这种情况下是输入图像),正如马克所描述的那样。另一个克隆体被创建并刮掉每组括号内部,从而创建了一个图像列表。然后,“-delete 0”只删除列表中的第一个图像,即未修改的输入图像。 - GeeMack
好的,这很值得知道,因为我不想删除原始文件。感谢您提供的信息。我明白您已经描述了如何将其转换为Bash,但在我接受答案之前,您能否用Bash语法编写它?我请求这个更改是为了社区,因为我相信人们在这里倾向于将Bash转换为其他命令行语法,而不是反过来。 - Daniel Kaplan
1
我编辑了命令,使其在*nix shell中工作。我还添加了另一个示例命令,展示了另一种解决任务的方法。 - GeeMack

3
如GeeMack所指出的,使用ImageMagick有很多种方法来实现这个功能。在他神奇的FX表达式的启发下,我尝试了其他几种方法 - 只是为了好玩!以下是我最初提出的方案:
magick input.png -write MPR:orig \
  -shave 1x -write out_1.png \
  -shave 1x -write out_2.png \
  -shave 1x -write out_3.png \
  -shave 1x -write out_4.png \
  -shave 1x -write out_5.png \
  -delete 0--1               \
  MPR:orig                   \
  -shave x1 -write out_6.png \
  -shave x1 -write out_7.png \
  -shave x1 -write out_8.png \
  -shave x1 -write out_9.png \
  -shave x1 out_10.png 

它加载输入图像并保存一个副本在称为 MPR "Magick Persistent Register"orig中。然后从左右两侧各削减一个像素并写入out_1.png,接着再从左右两侧各削减一个像素并保存到out_2.png中,并继续进行,直到左右两侧被削减了5个像素。然后重新从MPR中加载原始图像,将其从上下两侧各削减5次。

对于1080p的图像,即1920x1080,这需要3.4秒并使用96MB的RAM。相比之下,GeeMack在我的机器上需要3.5秒,并使用291MB的RAM。

然后我将左右刮胡须和上下刮胡须的创建并行化如下:

magick input.png \
  -shave 1x -write out_1.png \
  -shave 1x -write out_2.png \
  -shave 1x -write out_3.png \
  -shave 1x -write out_4.png \
  -shave 1x out_5.png &

magick input.png \
  -shave x1 -write out_6.png \
  -shave x1 -write out_7.png \
  -shave x1 -write out_8.png \
  -shave x1 -write out_9.png \
  -shave x1 out_10.png &

wait

那只需1.97秒,峰值达到68MB的RAM。

我认为GeeMack的解决方案对于大多数情况来说可能是最简单和最简洁的,但对于某些情况,即可能是较大的图像,其中的一些想法可能会有所发挥。


如果有人对如何测量峰值RAM使用情况感兴趣,我使用了这个:

/usr/bin/time -l ./go
    1.97 real         6.01 user         2.48 sys
        68354048  maximum resident set size
               0  average shared memory size
               0  average unshared data size
               0  average unshared stack size
           10343  page reclaims
               0  page faults
               0  swaps
               ...
               ...

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接