简体   繁体   中英

montage does not label images with list of strings represented in text file

I have a directory ( ./img/ ) with a large number of images in it. I want to montage them with specific label for each file. I have a text file ( label.txt ) which has list of labels:

label1
label2
label3
label4
...

I use this command:

montage -label @label.txt -size 512x512 "./img/*.*[120x90]" -geometry +5+5 photo.png

But in result, all images are labeled by all lines of label.txt ! How I can separate them, so each image will be labeled by relevant line of label.txt ?

ImageMagick works by parsing the command line and executing the parameters left to right.

Let's say that I have the following images:

eh-banner-201606.png
eh-banner-201607.png
eh-banner-201608.png
eh-banner-201609.png

(these are some banners for a webstie, the quickest images I have at hand)

Now, if I want to construct a montage with distinct label I must do:

montage -font /usr/share/fonts/TTF/DejaVuSerif.ttf -size 512x512 \
        -label 'first image' eh-banner-201606.png \
        -label 'second image' eh-banner-201607.png \
        -label 'third image' eh-banner-201608.png \
        -label 'fourth image' eh-banner-201609.png \
        -geometry +5+5 out.png

(the -font parameter is not strictly needed but I included it for pedantry)

This works as well with @labelfile :

montage -font /usr/share/fonts/TTF/DejaVuSerif.ttf -size 512x512 \
        -label '@first.txt' eh-banner-201606.png \
        -label '@second.txt' eh-banner-201607.png \
        -label '@third.txt' eh-banner-201608.png \
        -label '@fourth.txt' eh-banner-201609.png \
        -geometry +5+5 out.png

Where each file will contain a single line (or several lines) that will be the caption for the next image on the command line.

Therefore you need a script to perform what you are after, for example:

#!/bin/bash

LABELS=${1:-./labels.txt}
IMAGES=""

readarray labels < "$LABELS"
i=0
for img in "$@"; do
    IMAGES+=" -label '${labels[i]}' $img"
    ((i++))
done

echo montage -size 512x512 $IMAGES -geometry +5+5 out.png
montage -size 512x512 $IMAGES -geometry +5+5 out.png

You the can do (assuming the script name to be script.sh ):

./script.sh label.txt ./img/*.*120x90

Caveat : The image files cannot have spaces or special shell characters (that would require a third level of quoting, which is incredibly error prone). Note that [ and ] are special shell characters depending on the context. If you need more complex handling it may be wiser to use Perl or Python.

I changed sample code represented by @grochmal and it works:

#!/bin/bash

LABELS=${1:-./labels.txt}
IMAGES=""

readarray labels < "$LABELS"

i=0
echo @ is $@

#copy input argument array in InArg array:
for img in "$@"; do
InArg[$i]=$img
    ((i++))
done

#get dimensions of InArg array:
arraylength=${#InArg[@]}

#extract Input Image array from InArg array:
for (( i=1; i<${arraylength}; i++ ));
do
ImageArray[$i]=${InArg[$i]}
done

#create IMAGES from some elements of InArg array:
for (( i=1; i<${arraylength}; i++ ));
do
IMAGES+=" -label ${labels[i-1]} ${ImageArray[$i]}"
done
echo  "IMAGES is $IMAGES"

echo montage -size 512x512 $IMAGES -font FreeMono-Bold-Oblique -pointsize 30 -geometry '120x90+5+5>' -tile 5x  -frame 5  -shadow out.html
montage -size 512x512 $IMAGES -font FreeMono-Bold-Oblique -pointsize 30 -geometry '120x90+5+5>' -tile 5x  -frame 5  -shadow out.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM