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

问题描述

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

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

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


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

以下命令从一组输入图像生成蒙太奇图像 convert输出采用“特殊”fgimg 格式(这似乎最适合以后处理临时输出),并且具有透明背景,以便以后可以应用实际背景。这里的大多数其他选项并不重要,但关键是无法预先确定输出尺寸(尺寸)。

miff

接下来,我有一个输入图像 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 的背景之前,我想对其进行一些处理。一般来说,处理过程可能相当复杂,但在本例中,我想:

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

请注意,我需要在两个地方使用 fgimg 的大小。我可以先把它提取一个 shell 变量中:

fgimg

然后我可以在一个 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 写入磁盘。

我可以将 fgimgmiff:fgimg 命令中的 miff:- 替换为 montage,然后将一个命令通过管道连接到另一个convert。但是我该如何处理 montage ... | convert ...

我尝试使用文件描述符 ($size) 但这似乎不起作用,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 表达式的“+失真”将“玫瑰:”缩放到仍然适合原始管道输入图像的最大尺寸。该操作会在周围添加一个像素,因此我们使用“-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