: ########################################################################## # Title : mkindexpic - create combined index of several image files # Author : Heiner Steven # Date : 2004-01-09 # Category : Graphics # Requires : identify, montage # SCCS-Id. : @(#) mkindexpic 1.6 15/04/11 ########################################################################## # Description # # Notes # o The programs "montage" and "identify" are part of the ImageMagick # package that is available for most Unix and Windows systems: # http://www.imagemagick.org/ ########################################################################## PN=`basename "$0"` # Program name VER='1.6' INDEXNAME=index.jpg usage () { echo >&2 "$PN - create combined index picture from image files, $VER usage: $PN [-o outputfile] [-l label] image [image ...] -o: file name of the resulting combined image (default is $INDEXNAME) -l: label text (may contain ImageMagick(1) format characters) Example: Create a index file \"$INDEXNAME\" combining all *.jpg images in the current directory. The images will be labelled with the image name, followed by the image size (e.g. \"test.jpg: 160x120\"): $PN -l \"%f: %wx%h\" *.jpg" exit 1 } msg () { for MsgLine do echo "$PN: $MsgLine" >&2 done } fatal () { msg "$@"; exit 1; } IndexFile= while getopts :hl:o: opt do case "$opt" in l) labelformat=$OPTARG;; o) IndexFile=$OPTARG;; h) usage;; ?) usage;; esac done shift `expr $OPTIND - 1` [ $# -lt 1 ] && usage newimage=${IndexFile:-index.jpg} # Use rough prescaling, allowing "montage" not to have to read all pictures # into memory. #montageargs="-size 512x512" # This option changed with version 6.5.6-0 montageargs="-define jpeg:size=512x512" imagecnt=0 for image do [ -r "$image" ] || continue [ -s "$image" ] || continue [ X"$image" = X"$newimage" ] && continue # no index with index image #[ "$image" -ef "$newimage" ] && continue # BASH and ksh only if [ -n "$labelformat" ] then label=`identify -format "$labelformat" "$image"` elif [ -n "${labelformat+SET}" ] then label="" # Variable set, but empty else label=$image fi # This is my attempt to correctly handle file names with embedded # apostrophe characters imagequoted=`sed "s/'/'\\\\\\''/g" <<-EOT $image EOT ` labelquoted=`sed "s/'/'\\\\\\''/g" <<-EOT $label EOT ` montageargs="${montageargs:+$montageargs }-label '$labelquoted' '$imagequoted'" imagecnt=`expr $imagecnt + 1` done [ $imagecnt -lt 1 ] && fatal "no valid images found" #echo >&2 "DEBUG: imagecnt=<$imagecnt>" #echo >&2 "DEBUG: montageargs=<$montageargs>" eval `awk ' BEGIN { n = '$imagecnt' ratio = 1 sq = sqrt(n) cols = int(sq + 0.5) rows = int(n / cols + 0.5) if ( rows * cols < n ) { # Images do still not fit into cols x rows. We will add # either a new column or a new row, depending on which # of both will be filled better. Example: # 8 albums -> sqrt(8) = 2 -> cols=3, rows=2 # We could now create 4 columns with two rows, or # 3 columns with 3 rows. # When "X" is an image, and "O" is an empty field, # XXXX is preferred to XXX # XXXX XXX # XXO # because the former layout does not leave an empty # space like the latter does. #print "n=" n, "rows*cols=" rows*cols | "cat >&2" if ( (n % (cols+1)) <= (n % (rows+1)) ) { ++cols } else { ++rows } } print "cols=" cols print "rows=" rows } ' /dev/null` msg "creating ${cols}x$rows index file \"$newimage\" combining $imagecnt images" #set -x eval "montage -tile ${cols}x$rows $montageargs \"$newimage\"" #set +x