如何创建以下格式的图像排序规则:
image_name_1 [IMAGE#1]
image_name_2 [IMAGE#2]
image_name_3 [IMAGE#3]
...
使用 Imagemagick 我可以这样说:
montage -label '%f' -mode concatenate -tile 1x foo*.png out.png
但这增加了文件名在图像下方+它不考虑名称宽度。
在哪里打印的文件名(如传统的笛卡尔 y 轴)并不重要,只要它位于文件的左侧即可正确的图像。
哪个工具并不重要,只要它适用于 32 位 Linux 即可。
答案1
我不是 ImageMagick 专家,因此可能有更好的方法来执行此操作,但您可以分两步执行此操作,首先将每个图像左侧的文本添加到中间文件中,然后进行蒙太奇。
for file in foo*.png
do convert "$file" -splice 100x0 -gravity west -annotate +10+0 '%f' /tmp/"$(basename "$file")"
done
montage -mode concatenate -tile 1x /tmp/*.png out.png
您需要将拼接值调整100
为足够宽以适合最宽的文件名标签。
使用单个命令的一个有趣的替代方案是
convert \
$(for file in foo*.png
do echo '(' label:"$(basename "$file")" -gravity center "$file" +append ')'
done) -gravity west -append out.png
您可以在其中+append
将标签和图像水平连接在一起,然后-append
垂直连接结果。它并不完全是您所需要的,但可能是进一步实验的起点。
答案2
如果有人想进一步破解这个问题,这里有一些虽然混乱但可能会引起兴趣的提示或帮助。
该过程请求文件名的最大高度和宽度,以生成适合的标签。缺少的一个功能是文本的垂直居中(说实话,看起来更好。)
要获取文本的宽度 + 高度(作为整数),一种方法是:
convert -debug annotate xc: -font Arial -pointsize 24 \
-annotate 0 'Test' null: 2>&1 | \
awk -vRS='[;.]' -F': ' '/width|height/{print $2}'
但是,当文件数量适中时,对循环中的每个文件名执行此操作会大大增加时间/资源。
因此,在下面的脚本中,我生成了两个具有所有文件名的临时文件。一个获得最大高度,另一个获得最大宽度。
如果文件名有换行符,该过程将中断。
#!/bin/bash
# Default Options
font=Arial
font_size=12
pad=20
usage()
{
cat <<EOF_USAGE
Usage: $0 [OPTION] <images>
-f | --font <font>
-z | --font_size <N>
-h | --help [f|font]
EOF_USAGE
exit 1
}
# Check for user-options
while [[ "$1" ]]
do
case "$1" in
--font|-f)font=$2; shift;;
--help|-h)
if [[ "$2" = "f" || "$2" = "font" ]]
then
convert -list font
printf "\nCMD: convert -list font\n"
fi
usage
exit 1
;;
--font_size|-z)font_size=$2; shift;;
--pad|-p)pad=$2; shift;;
--)shift; break;;
*)break;;
esac
shift
done
# Shallow Next option check (is it a file at all?)
! [[ -f "$1" ]] && printf "Not a file: %s\n" "$1" && exit 2
printf "Processing %d files ...\n" "$#"
txt_w=0
txt_h=0
tmp_dir=$(mktemp -d)
printf "tmp dir : %s\n" "$tmp_dir"
images=("$@")
printf "Calculating max width / height ..."
# Find max width from file names using font + font-size
txt_w=$(convert \
-debug annotate xc: \
-font "$font" \
-pointsize "$font_size" \
-annotate 0 "\"$(printf "%s\n" "${images[@]}")\"" null: 2>&1 | \
sed -n 's/.*Metrics:.* width: \([^.;]*\)[;.].*/\1/p' | sort -n | tail -n1)
# Find max height from file names using font + font-size
txt_h=$(convert \
-debug annotate xc: \
-font "$font" \
-pointsize "$font_size" \
-annotate 0 "\"$(printf "%s" "${images[@]}")\"" null: 2>&1 | \
sed -n 's/.*Metrics:.* height: \([^.;]*\)[;.].*/\1/p')
printf "\r\033[KWidth : %d\n" "$txt_w"
printf "Height : %d\n" "$txt_h"
# Add padding pixels
(( txt_w+=pad*2 ))
# Create the labeled images
for img in "${images[@]}"
do
printf "\r\033[KCreating label for \`%s'" "$img"
convert "$img" \
-splice ${txt_w}x$txt_h \
-gravity west \
-font "$font" \
-pointsize $font_size \
-annotate +$pad+0 '%f' \
"$tmp_dir"/"$(basename "$img")"
done
printf "\r\033[KMontage ...\n"
# Combine / Collate / Montage
montage -mode concatenate -tile 1x $(printf "$tmp_dir/%s " "${images[@]}") out.png
printf "Done!\n"
# Clean up
rm -r "$tmp_dir"