通过分层 png 随机组合图像
Randomly compose images by layering pngs
我正在尝试使用 Imagemagick v7 通过随机组合大小相同的透明 png 层来批量创建图像。
我是一个新手所以我复制了我在这里找到的代码:
#!/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
我设法让它随机选择我的图层但是:
- 输出文件夹中未创建任何文件。
- 无论我为 NFILES 添加什么,它总是停在第一个(“output-o.png”)。
如果我还可以确保一旦某个层被随机选取和使用,它就不会被再次选取,那就太好了。
也许用临时删除文件?
好的,我发现了问题,我在 copying/pasting 代码时犯了一个简单的语法错误...所以现在我设法输出了我的图像,欢呼!
剩下要做的唯一一件事就是确保,一旦一个层被随机挑选和使用,它就不会被再次挑选。
如何实现?
非常感谢
ok,感谢Mark Setchell的大力帮助,终于想出了解决办法
#!/bin/bash
# Number of output files
NFILES=20
BASE="$HOME/foldername"
# Function to read a random line from file, deleting it if required
randomLine () {
filename=; delete=
# Check file is not empty
declare -i nlines
nlines=$(wc -l < "$filename")
if [ $nlines -eq 0 ] ; then
2>&1 echo "ERROR: $filename is empty"
exit 1
fi
# Read lines into array
IFS=$'\n' read -d '' -r -a lines < "$filename"
# Choose a random line number
((sel = RANDOM % nlines))
# Output result for caller in global variable
retval="${lines[sel]}"
# Delete the line if required
if [ $delete -eq 1 ] ; then
lines[sel]="JUNK"
printf "%s\n" "${lines[@]}" | grep -v "JUNK" > "$filename"
fi
}
# Main program
# Create output directory
mkdir -p "${BASE}/export"
# Build lists of filenames in each layer - write lists in /tmp
for ((layer=1; layer<=6; layer++)) ; do
find "${BASE}/parts/p${layer}" -name "*.png" > /tmp/L${layer}
done
# Produce NFILES output files
for ((n=0; n<$NFILES; n++)) ; do
# Pick up files randomly, deleting 2, 4 and 6, reusing others
randomLine "/tmp/L1" 0; f1="$retval"
randomLine "/tmp/L2" 1; f2="$retval"
randomLine "/tmp/L3" 0; f3="$retval"
randomLine "/tmp/L4" 1; f4="$retval"
randomLine "/tmp/L5" 0; f5="$retval"
randomLine "/tmp/L6" 1; f6="$retval"
# Generate output filename
for ((i=0;;i++)) ; do
out="${BASE}/output-$i.png"
[ ! -f "$out" ] && break
done
echo $f1, $f2, $f3, $f4, $f5, $f6 "=> $out"
convert "$f1" "$f2" -composite "$f3" -composite "$f4" -composite "$f5" -composite "$f6" -composite "$out"
done
我正在尝试使用 Imagemagick v7 通过随机组合大小相同的透明 png 层来批量创建图像。
我是一个新手所以我复制了我在这里找到的代码:
#!/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
我设法让它随机选择我的图层但是:
- 输出文件夹中未创建任何文件。
- 无论我为 NFILES 添加什么,它总是停在第一个(“output-o.png”)。
如果我还可以确保一旦某个层被随机选取和使用,它就不会被再次选取,那就太好了。 也许用临时删除文件?
好的,我发现了问题,我在 copying/pasting 代码时犯了一个简单的语法错误...所以现在我设法输出了我的图像,欢呼!
剩下要做的唯一一件事就是确保,一旦一个层被随机挑选和使用,它就不会被再次挑选。
如何实现?
非常感谢
ok,感谢Mark Setchell的大力帮助,终于想出了解决办法
#!/bin/bash
# Number of output files
NFILES=20
BASE="$HOME/foldername"
# Function to read a random line from file, deleting it if required
randomLine () {
filename=; delete=
# Check file is not empty
declare -i nlines
nlines=$(wc -l < "$filename")
if [ $nlines -eq 0 ] ; then
2>&1 echo "ERROR: $filename is empty"
exit 1
fi
# Read lines into array
IFS=$'\n' read -d '' -r -a lines < "$filename"
# Choose a random line number
((sel = RANDOM % nlines))
# Output result for caller in global variable
retval="${lines[sel]}"
# Delete the line if required
if [ $delete -eq 1 ] ; then
lines[sel]="JUNK"
printf "%s\n" "${lines[@]}" | grep -v "JUNK" > "$filename"
fi
}
# Main program
# Create output directory
mkdir -p "${BASE}/export"
# Build lists of filenames in each layer - write lists in /tmp
for ((layer=1; layer<=6; layer++)) ; do
find "${BASE}/parts/p${layer}" -name "*.png" > /tmp/L${layer}
done
# Produce NFILES output files
for ((n=0; n<$NFILES; n++)) ; do
# Pick up files randomly, deleting 2, 4 and 6, reusing others
randomLine "/tmp/L1" 0; f1="$retval"
randomLine "/tmp/L2" 1; f2="$retval"
randomLine "/tmp/L3" 0; f3="$retval"
randomLine "/tmp/L4" 1; f4="$retval"
randomLine "/tmp/L5" 0; f5="$retval"
randomLine "/tmp/L6" 1; f6="$retval"
# Generate output filename
for ((i=0;;i++)) ; do
out="${BASE}/output-$i.png"
[ ! -f "$out" ] && break
done
echo $f1, $f2, $f3, $f4, $f5, $f6 "=> $out"
convert "$f1" "$f2" -composite "$f3" -composite "$f4" -composite "$f5" -composite "$f6" -composite "$out"
done