#!/bin/bash # # Developed by Fred Weinhaus 7/16/2010 .......... revised 6/30/2011 # # USAGE: bevelborder [-s size] [-m method] [-p percent] [-c contrast] [-b bcolor] [-a amount] [-t type] infile outfile # USAGE: bevelborder [-h or -help] # # OPTIONS: # # -s size size of border in pixels; same in both dimensions; # default equals 10% of min(imagewidth, imageheight) # -m method bevel method; choices are: outer, inner or split; # default=outer # -p percent split percent between outer and inner bevel; # 100 is outer bevel only; 0 is inner bevel only; # default=50 applies only to method=split # -c contrast contrast percent for bevel; 0<=integer<=100; # default=50 # -b bcolor border coloring; any IM opaque color is allowed; # default is no coloring # -a amount amount of border coloring; 0<=integer<=100; # default=25 # -t type type of compose; hardlight, linearlight or # vividlight; default=hardlight # ### # # NAME: BEVELBORDER # # PURPOSE: To applies a bevel effect to the border of an image. # # DESCRIPTION: BEVELBORDER applies a bevel effect to the border of an image. # The bevel can be an outer bevel (raised effect), an inner bevel (depressed # effect) or a split (mix) of the two. The border may also be colorized. # # # ARGUMENTS: # # -s size ... SIZE is the dimensions of the border region in pixels. The same # value is used in both dimensions. Values are integers greater than 0. The # default is 10% of the min(width,height) of the image. # # -m method ... METHOD is the bevel method. Choices are: outer, which makes a # raised effect; inner, which makes a depressed effect; and split, which is # part raised and part depressed. The amount of each is controlled by the # percent argument. The default is outer. # # -p percent ... PERCENT is the percent split between outer and inner bevels. # Values are integers such that 0<=percent<=100. A value of 100 is full outer # bevel. A value of 0 is full inner bevel. The default is 50 and only applies # when the method=split. # # -c contrast ... CONTRAST percent for innerbevel or outerbevel. Values are # integers between 0 and 100. The default=50. # # -b bcolor ... BCOLOR is the bevel colorization color. Any valid opaque IM # color is allowed. The default is no additional colorization. # # -a amount ... AMOUNT of colorization. Values are integers between 0 and 100. # The default=25. # # -t type ... TYPE of compose. Choices are: hardlight, linearlight and # vividlight. The default=hardlight # # REQUIREMENTS: IM 6.5.9.0 or higher due to the use of -brightness-contrast. # # CAVEAT: No guarantee that this script will work on all platforms, # nor that trapping of inconsistent parameters is complete and # foolproof. Use At Your Own Risk. # ###### # # set default values size="" # bevel border amount in pixels method="outer" # outer, inner, split percent=50 # split percent; 0 to 100; 100 is outer; 0 is inner contrast=50 # bevel contrast percent bcolor="" # bevel color amount=25 # amount of coloring; 0<=integer<=100 type="hardlight" # bevel compose method # set directory for temporary files dir="." # suggestions are dir="." or dir="/tmp" # set up functions to report Usage and Usage with Description PROGNAME=`type $0 | awk '{print $3}'` # search for executable on path PROGDIR=`dirname $PROGNAME` # extract directory of program PROGNAME=`basename $PROGNAME` # base name of program usage1() { echo >&2 "" echo >&2 "$PROGNAME:" "$@" sed >&2 -n '/^###/q; /^#/!q; s/^#//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME" } usage2() { echo >&2 "" echo >&2 "$PROGNAME:" "$@" sed >&2 -n '/^######/q; /^#/!q; s/^#*//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME" } # function to report error messages errMsg() { echo "" echo $1 echo "" usage1 exit 1 } # function to test for minus at start of value of second part of option 1 or 2 checkMinus() { test=`echo "$1" | grep -c '^-.*$'` # returns 1 if match; 0 otherwise [ $test -eq 1 ] && errMsg "$errorMsg" } # test for correct number of arguments and get values if [ $# -eq 0 ] then # help information echo "" usage2 exit 0 elif [ $# -gt 16 ] then errMsg "--- TOO MANY ARGUMENTS WERE PROVIDED ---" else while [ $# -gt 0 ] do # get parameter values case "$1" in -h|-help) # help information echo "" usage2 exit 0 ;; -s) # get size shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID SIZE SPECIFICATION ---" checkMinus "$1" size=`expr "$1" : '\([0-9]*\)'` [ "$size" = "" ] && errMsg "--- SIZE=$size MUST BE A NON-NEGATIVE INTEGER VALUE (with no sign) ---" testA=`echo "$size <= 0" | bc` [ $testA -eq 1 ] && errMsg "--- SIZE=$size MUST BE A POSITIVE INTEGER ---" ;; -m) # get method shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID METHOD SPECIFICATION ---" checkMinus "$1" # test type values method=`echo "$1" | tr "[:upper:]" "[:lower:]"` case "$method" in outer|inner|split) ;; # do nothing - valid type *) errMsg "--- METHOD=$method IS NOT A VALID VALUE ---" ;; esac ;; -p) # get percent shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID PERCENT SPECIFICATION ---" checkMinus "$1" percent=`expr "$1" : '\([0-9]*\)'` [ "$percent" = "" ] && errMsg "--- PERCENT=$percent MUST BE A NON-NEGATIVE INTEGER ---" testA=`echo "$percent < 0" | bc` testB=`echo "$percent > 100" | bc` [ $testA -eq 1 -o $testB -eq 1 ] && errMsg "--- PERCENT=$percent MUST BE AN INTEGER BETWEEN 0 AND 100 ---" ;; -c) # get contrast shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID CONTRAST SPECIFICATION ---" checkMinus "$1" contrast=`expr "$1" : '\([0-9]*\)'` [ "$contrast" = "" ] && errMsg "--- CONTRAST=$contrast MUST BE A NON-NEGATIVE INTEGER ---" testA=`echo "$contrast < 0" | bc` testB=`echo "$contrast > 100" | bc` [ $testA -eq 1 -o $testB -eq 1 ] && errMsg "--- CONTRAST=$contrast MUST BE AN INTEGER BETWEEN 0 AND 100 ---" ;; -b) # get bcolor shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID BCOLOR SPECIFICATION ---" checkMinus "$1" bcolor="$1" ;; -a) # get amount shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID AMOUNT SPECIFICATION ---" checkMinus "$1" amount=`expr "$1" : '\([0-9]*\)'` [ "$amount" = "" ] && errMsg "--- AMOUNT=$amount MUST BE A NON-NEGATIVE INTEGER ---" testA=`echo "$amount < 0" | bc` testB=`echo "$amount > 100" | bc` [ $testA -eq 1 -o $testB -eq 1 ] && errMsg "--- AMOUNT=$amount MUST BE AN INTEGER BETWEEN 0 AND 100 ---" ;; -t) # get type shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID TYPE SPECIFICATION ---" checkMinus "$1" # test type values type=`echo "$1" | tr "[:upper:]" "[:lower:]"` case "$type" in hardlight|linearlight|vividlight) ;; # do nothing - valid type *) errMsg "--- METHOD=$method IS NOT A VALID VALUE ---" ;; esac ;; -) # STDIN and end of arguments break ;; -*) # any other - argument errMsg "--- UNKNOWN OPTION ---" ;; *) # end of arguments break ;; esac shift # next option done # # get infile and outfile infile=$1 outfile=$2 fi # test that infile provided [ "$infile" = "" ] && errMsg "NO INPUT FILE SPECIFIED" # test that outfile provided [ "$outfile" = "" ] && errMsg "NO OUTPUT FILE SPECIFIED" tmpA="$dir/bevelborder_$$.mpc" tmpB="$dir/bevelborder_$$.cache" trap "rm -f $tmpA $tmpB; exit 0" 0 trap "rm -f $tmpA $tmpB; exit 1" 1 2 3 15 # read the input image into the TMP cached image. convert -quiet -regard-warnings "$infile" +repage "$tmpA" || errMsg "--- FILE $infile NOT READABLE OR HAS ZERO SIZE ---" # set default size if [ "$size" = "" ]; then size=`convert $tmpA -ping -format "%[fx:floor(0.1*min(w,h))]" info:` wsize=$size hsize=$size fi # get input image size ww=`convert $infile -ping -format "%w" info:` hh=`convert $infile -ping -format "%h" info:` wd=`convert xc: -format "%[fx:$ww-2*$size]" info:` ht=`convert xc: -format "%[fx:$hh-2*$size]" info:` # adjust contrast and transparency to fractions contr1=`convert xc: -format "%[fx:$contrast-100]" info:` # setup bevel parameters if [ "$method" = "outer" ]; then wsize2=$size hsize2=0 elif [ "$method" = "inner" ]; then hsize2=$size wsize2=0 elif [ "$method" = "split" ]; then wsize2=`convert xc: -format "%[fx:floor($percent*$size/100)]" info:` hsize2=$(($size-$wsize2)) fi echo "ww=$ww; hh=$hh; wd=$wd; ht=$ht; wsize2=$wsize2; hsize2=$hsize2" if [ "$bcolor" = "" ]; then colorize="" else colorize="-fill $bcolor -colorize $amount%" fi # process image convert $tmpA -size ${wd}x${ht} xc:"gray(50%)" \ \( -clone 1 -frame ${size}x${size}+${wsize2}+${hsize2} \ -auto-level -black-threshold 25% -white-threshold 75% $colorize \ -brightness-contrast 0,${contr1}% \ -clone 1 -gravity center -composite \) \ -delete 1 -compose $type -composite \ $outfile exit 0