将图像列表与名称进行核对

将图像列表与名称进行核对

如何创建以下格式的图像排序规则:

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"

相关内容