#!/bin/bash

#a script to write a text label including 
#the date and time an image was taken, provided the latter
#can be found in the images Metadata.
#This script works on one or more valid image files
#depends on imagemagick, extract (both readily available from depositories)
#also: zenity is a simple gui http://library.gnome.org/users/zenity/stable/
#zenity creates simple dialogs that interact graphically with the user
#
#
#Examples:  works s:  
#eg:    labelimage *.jpg
#        labelimage a.jpg b.jpg c.giff
#Norman Bakker 9/2011

check_errs()
{
  #checks whether an error has occurred and exits if it has
  # http://steve-parker.org/sh/exitcodes.shtml
  # Function. Parameter 1 is the return code
  # Para. 2 is text to display on failure.
  if [ "${1}" -ne "0" ]; then
    echo "ERROR # ${1} : ${2}"
    exit ${1}
  fi
}

validfile() 
{
    #checks whether we are dealing with a valid image file using imagemagick identify command
    identify -quiet $1   #check we are dealing with a valid image file
    check_errs $? "$1 is not an image file";
    if [[ $? -ne "0" ]]; then exit 1;
    fi;  #if not halt execution
}

parsename()
{
#strip the extension from the file name (in $1): see parameter expansion :http://mywiki.wooledge.org/BashFAQ/073
#not used here
    name="${1%.*}"  
  	ext="${1##*.}"  #get the extension from the file name
}
 
readtimestamp()
{
#extract date metadata then delete all to '- '; delete all ':'; replace remaining ' ' with '-'; 
#example of normal output of extract -p date : date - 2011:08:01 13:49:23
#to delete last two characters (seconds) add :  -e 's/..$//g' to sed string below
# may need to install 'extract'   
    ts=`extract -p date "$1" | sed -e 's/^.*- //' -e 's/:/ /g' -e 's/ /-/g' `
}

addlabel() 
{
#add an outlined label to an image ($1) and attempt scaling based on height of photo 
#label is given as second argument $2
#output file is renamed to form "$name""-im.""$ext" after calling parsename'
#(for plain label change comments)
    actualheight=`identify -format '%h' "$1"`
    pointsz=$[actualheight/40]  #use a smaller denominator to get a larger label and vice versa
    fillcolor="gold"    #fillcolor="maroon"
    #plain label  : 
    #convert "$outputfilename" -gravity southeast -pointsize $pointsz -fill $fillcolor -annotate 0 "$lble"  "$outputfilename";fi  
    #outlined label 
    # http://www.imagemagick.org/Usage/annotating/#anno_on  
    #parsename  "$1" using name="${1%.*}";  ext="${1##*.}"  Not used here as a function
    #but see http://mywiki.wooledge.org/BashFAQ/073 for an explanation of the parameter expansion
    convert "$1" -gravity southeast -pointsize $pointsz -fill $fillcolor \
                -stroke '#000C' -strokewidth 4 -annotate 0 "$2" -stroke none -annotate 0 "$2" "${1%.*}""-im.""${1##*.}"  
}

getlabel()
{
#read in a label from stdinput and decide whether to add timestamp for image $1
    #read -p "Provide a label : " mylabel
    mylabel=`zenity --entry --text "Enter label for $1" --title "Label entry"`
}

displaybeforeafter() {
#view before and after of imageside by side
#to use uncomment last two lines in singlefile() 
    convert $1 $2  +append -quality 95 'ba.jpg'
    display -resize 1200 ba.jpg 
    rm ba.jpg
}

singlefile() 
{
# label a single image file
    validfile $1
    #get a label for each image if cl is 'n'
    #otherwise use the one already read in
    if [[ "$cl" = 'n' ]];then getlabel "$1";fi;
    readtimestamp $1  #comment this out if you don't want a time stamp
    addlabel "$1" "$mylabel"" ""$ts"
    #if zenity --question --text="Do you want to see the before/after?"
    #then  displaybeforeafter $1 "${1%.*}""-im.""${1##*.}";fi
}

    cl='n'

multiplefiles()
{
# label one or multiple image files
#process the image files one by one
    echo Processing $# files
    if [[ "$#" -gt 1 ]] 
    then
        #do we want a common label header for all images #{"$#" -gt 1} &&
        if `zenity --question --text "Use a common label header" --title "Common label?"`   
            then cl='y'; getlabel "$1"
        else cl='n';
        fi;
    fi;
    #process each image one by one
    shift $(($OPTIND - 1)); until [[ -z "$1" ]];   # continue until no files left
    do
       singlefile $1
    shift
    done
    echo Finished output is renamed in format "name"-im".ext"
    echo ALL DONE!
}


#process one or more files; output is ranamed but is in the same directory; original files unchanged.
multiplefiles $@



