如何在不使用任何临时文件的情况下将 Imagemagick 蒙太奇输出和图像属性传递给转换命令?

How to pass Imagemagick montage output and image properties to the convert command without using any temporary files?

我有一组图像,我可以对它们使用 Imagemagick montage 命令来生成具有透明背景的蒙太奇图像文件(我们称之为 fgimg)。现在我有另一个现有的图像(让我们称之为 bgimg),我想使用(在使用 convert 命令进行一些特殊处理之后)作为 fgimg 的背景,它可以是在同一个 convert 命令中实现。在这一点上,避免将临时 fgimg 写入磁盘似乎微不足道,只需将 montage 的标准输出通过管道传输到 convert.

的标准输入即可

我的问题是,我对 bgimg 应用的特殊处理需要了解 fgimg 的图像属性(例如,将 bgimg 调整为相同大小as fgimg),我事先并不知道。 如何在 convert 命令中检索和使用此信息?

注意:我在 Linux 上使用 Imagemagick 版本 6.9.7-4。


我将在下面包含一些命令以进一步详细说明问题。

以下命令从一组输入图像生成蒙太奇图像 fgimg。输出采用 'special' miff 格式(这似乎最适合稍后处理的临时输出),并具有透明背景,以便稍后可以应用实际背景。这里的其他选项大部分都不重要,关键是输出的尺寸(dimensions)无法提前确定。

montage input_*.jpg -tile 5x -border 2 -geometry '200x200>+20+20' \
  -gravity center -set label '%f\n%G' -background none -fill white \
  -title 'Sample Title' miff:fgimg

接下来,我有另一个输入图像bgimg.jpg。我想在将其用作 fgimg 的背景之前对其执行一些处理。一般来说,处理过程可能相当复杂,但在这个例子中,我想:

  1. 调整大小 bgimg.jpg 以适应 fgimg 的尺寸,不进行任何裁剪;
  2. 在边缘周围应用淡入淡出效果;
  3. 使其大小与 fgimg 相同,背景为黑色;
  4. 将其与 fgimg 结合以产生最终输出。

请注意,我在两个地方需要 fgimg 的大小。我可以先将其提取到 shell 变量中:

size=$(identify -format '%G' miff:fgimg)

然后我可以在一个 convert 命令中完成上述所有步骤(注意 $size 使用了两次):

convert "bgimg.jpg[$size]" -gravity center \
  \( +clone -fill white -colorize 100% -bordercolor black \
  -shave 20 -border 20 -blur 0x20 \) -compose multiply -composite \
  -background black -compose copy -extent $size \
  miff:fgimg -compose over -composite final_out.jpg

现在问题来了:我想避免将临时文件 fgimg 写入磁盘。

我可以在 montageconvert 命令中将 miff:fgimg 替换为 miff:-,然后通过管道将其中一个传递给另一个:montage ... | convert ...。但是我该如何处理 $size?

我尝试使用文件描述符 (miff:fd:3),但这似乎不起作用,this question.

的评论证实了这一点

有没有办法在不创建临时文件的情况下执行此操作(在 Imagemagick v6 中)?

此示例命令在 bash shell 上使用 ImageMagick v6。它不是使用“蒙太奇”,而是首先使用“转换”创建一个“徽标:”,这是 IM 的内置示例图像之一,然后将其作为 MIFF 输出并输入随后的“转换”命令。您可以同样轻松地通过管道传输“蒙太奇”的输出。它使用另一个 IM 内置图像“rose:”作为您的“bgimg.jpg”...

convert logo: miff:- | convert - rose: \
   +distort SRT "%[fx:t?min(u.w/v.w,u.h/v.h):1] 0" \
   -shave 1 +repage -gravity center -bordercolor black \
   \( -clone 1 -fill white -colorize 100 -shave 6 -border 6 \
      -blur 0x6 -clone 1 -compose multiply -composite \) -delete 1 \
   \( -clone 0 -alpha off -fill black -colorize 100 \
      -clone 1 -compose over -composite \) -delete 1 \
   +swap -composite final_out.jpg

读取管道图像“-”和背景图像“rose:”。

然后它使用带有 FX 表达式的“+distort”将“rose:”缩放到仍适合原始管道输入图像的最大尺寸。该操作在周围添加了一个像素,因此我们使用“-shave 1”来摆脱它。

接下来在括号内克隆重新缩放的背景图像,制作边缘模糊蒙版,并将它们合成以在背景图像上制作淡入淡出的黑色边缘。紧跟在括号之后,它会删除无边背景图像。

在下一个括号中,它克隆输入图像,使其变黑,克隆修改后的背景图像,并将其合成到黑色图像的中心。再次,非扩展背景图像在带有“-delete 1”的括号后被丢弃。

最后,修改后的背景和输入图像通过“+swap”以正确的顺序放置并合成最终输出。 运行 此命令没有最后一个“-composite”,以查看命令前面部分产生的两个图像。

主输入图像和背景图像都可以是任意大小、任意尺寸和任意纵横比。这适用于 bash shell 上的 v6.8.9。它应该适用于任何更新的 ImageMagick。它应该通过删除所有转义括号的反斜杠并将续行反斜杠“\”更改为脱字符“^”来在 Windows 上工作。

编辑添加:

您可以使用该 FX 表达式找到缩放量,将其保存为变量,然后隔离括号内的背景图像并使用该变量在那里进行缩放和修整。这样它只会影响背景图像。这可能存在舍入误差,但决定最终输出尺寸的主图像不会受到影响。请注意此命令前几行的区别...

convert logo: miff:- | convert - rose: \
   -set option:v1 "%[fx:min(u.w/v.w,u.h/v.h)]" \
   \( -clone 1 +distort SRT "%[v1] 0" -shave 1 \) -delete 1 \
   +repage -gravity center -bordercolor black \
   \( -clone 1 -fill white -colorize 100 -shave 6 -border 6 \
      -blur 0x6 -clone 1 -compose multiply -composite \) -delete 1 \
   \( -clone 0 -alpha off -fill black -colorize 100 \
      -clone 1 -compose over -composite \) -delete 1 \
   +swap final_out.jpg