【问题标题】:How can I automatically generate composite images by layering source images randomly?如何通过随机分层源图像来自动生成合成图像?
【发布时间】:2015-02-21 10:55:47
【问题描述】:

我正在从事一个个人创意项目,需要帮助查找或创建一个脚本,该脚本将从 4 个不同文件夹中随机选择 4 个图像,将它们堆叠并创建一系列 png 合成图像作为输出。如果每个文件夹的图像都可以分配到一个固定的图层,则加分(例如,“背景”文件夹中的图像将始终出现在后面)。 注意:我不知道如何编码。

【问题讨论】:

  • 您使用的是 Linux 或 OSX 等体面的操作系统吗?如果图像尺寸不同 - 重新缩放到固定尺寸怎么办?
  • 感谢您的回答马克。我正在使用 OSX,我的源图像都是 png,alpha 通道以最终大小保存,因此无需进行更改。最终的图像应该有 4 层,我在单独的文件夹中为每一层都有一组图像。

标签: image-processing scripting imagemagick photoshop


【解决方案1】:

更新

好的,我已经将脚本更新如下:

  1. 它产生 10 个输出文件 - 您可以通过在开始时更改 NFILES 来更改它
  2. 输出文件不会在运行之间相互覆盖,下一个空闲名称将使用以output-0.png 开头然后output-1.png 等等。
  3. 我已更正 alpha 合成以匹配您的文件。

脚本如下...

#!/bin/bash

# Number of output files - edit freely :-)
NFILES=10

# Build arrays of filenames in each layer, assume directories are "Layer0", "Layer1" etc
IFS=$'\n' L0files=($(find "Layer 0" -name "*.png"))
IFS=$'\n' L1files=($(find "Layer 1" -name "*.png"))
IFS=$'\n' L2files=($(find "Layer 2" -name "*.png"))
IFS=$'\n' L3files=($(find "Layer 3" -name "*.png"))

# Produce NFILES output files
for i in `seq 1 $NFILES`; do

   # Choose random index into each array of filenames
   index0=$( jot -r 1  0 $((${#L0files[@]} - 1)) )
   index1=$( jot -r 1  0 $((${#L1files[@]} - 1)) )
   index2=$( jot -r 1  0 $((${#L2files[@]} - 1)) )
   index3=$( jot -r 1  0 $((${#L3files[@]} - 1)) )

   # Pick up files as specified by the random index
   f0=${L0files[index0]}
   f1=${L1files[index1]}
   f2=${L2files[index2]}
   f3=${L3files[index3]}

   # Generate output filename, "output-nnn.png" 
   # ... where nnn starts at 0 and goes up till no clash
   i=0
   while :; do
      out="output-$i.png"
      [ ! -f "$out" ] && break
      ((i++))
   done

   echo $f0, $f1, $f2, $f3 "=> $out"
   convert "$f0" "$f1" -composite "$f2" -composite "$f3" -composite "$out"
done

从您的 Layer[0-3] 目录中的以下图像开始:

第 0 层

第 1 层

第 2 层

第 3 层

生成如下输出文件:

原答案

我会安装 ImageMagick 来执行此操作 - 如果您首先通过 here 安装 homebrew,它是免费且易于安装在 OSX 上的。然后在终端中输入以下内容。

brew install imagemagick

脚本将如下所示:

#!/bin/bash
# Build arrays of filenames in each layer, assume directories are "Layer0", "Layer1" etc
IFS=$'\n' L0files=($(find "Layer0" -name "*.png"))
IFS=$'\n' L1files=($(find "Layer1" -name "*.png"))
IFS=$'\n' L2files=($(find "Layer2" -name "*.png"))
IFS=$'\n' L3files=($(find "Layer3" -name "*.png"))

# Choose random index into each array of filenames
index0=$( jot -r 1  0 $((${#L0files[@]} - 1)) )
index1=$( jot -r 1  0 $((${#L1files[@]} - 1)) )
index2=$( jot -r 1  0 $((${#L2files[@]} - 1)) )
index3=$( jot -r 1  0 $((${#L3files[@]} - 1)) )

# Pick up files as specified by the random index
f0=${L0files[index0]}
f1=${L1files[index1]}
f2=${L2files[index2]}
f3=${L3files[index3]}

echo Overlaying $f0, $f1, $f2, $f3 to produce "result.png"
convert "$f0" "$f1" "$f2" "$f3" -compose over -composite result.png

所以,你可以将上面的内容保存为generate,然后到终端执行以下操作,使其可执行

chmod +x generate

然后你可以通过在Finder中双击它的图标来运行它,或者输入:

./generate

在终端中。然后它将生成 4 张图像的随机叠加,每个文件夹中一张,并将结果保存为 result.png

您需要根据图像在各个层的位置来编辑前 4 行 - 基本上我假设图像位于名为 Layer0-4 的目录中,但您的可能位于 /Users/FreddyFrog/pictures/backgrounds 或类似的目录中,其中你会编辑的情况

    IFS=$'\n' L0files=($(find "/Users/FreddyFrog/pictures/backgrounds" -name "*.png"))

当我在我的 Mac 上运行它几次时,我得到:

Overlaying Layer0/l0-5.png, Layer1/l1-0.png, Layer2/l2-3.png, Layer3/l3-3.png to produce result.png
Overlaying Layer0/l0-3.png, Layer1/l1-4.png, Layer2/l2-3.png, Layer3/l3-3.png to produce result.png

【讨论】:

  • 感谢您的详细回答@Mark,这似乎解决了主要任务。我在渲染透明度时遇到了问题,我一次只能看到 2 层,而且我的纯色背景似乎覆盖了最前面的图像。
    由于我需要多次运行脚本,我该怎么做避免结果被覆盖,我怎样才能让它播放也许每次我运行它时说 10 次?
  • 我有一段时间不在我的 Mac 上。你能张贴每一层的图片和你的预期结果吗?或者单击我的个人资料并通过电子邮件发送给他们以及结果的外观。我可以在回家时解决所有问题。
  • 再次感谢。我已经上传了 4 层的示例和示例结果图像 here
  • 我认为现在这可以解决您的所有要求 - 只要说明您的需求是否有任何问题或不清楚。
  • @ign:在 StackOverflow 上说“谢谢”的一般推荐方式是“投票”任何你遇到并阅读并认为它是好的答案或教会你一些新东西的答案.你只“接受”了马克的回答,但你还没有“投票”(就像我自己刚才所做的那样)。点击答案左上角的 ^ 形图标即可完成投票。
猜你喜欢
  • 2021-11-05
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
  • 2013-02-28
  • 1970-01-01
  • 1970-01-01
  • 2016-05-01
  • 2012-03-13
相关资源
最近更新 更多