Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
#!/bin/bash # This is a(n outdated) COPY of Fred Winehaus's "textcleaner" script. # For the upstream version, see: # http://www.fmwconcepts.com/imagemagick/textcleaner/index.php # # This copy is hosted at: # http://angg.twu.net/bin/textcleaner.html # http://angg.twu.net/bin/textcleaner # (find-angg "bin/textcleaner") # See: (find-angg "bin/whiteboard") # Developed by Fred Weinhaus 6/9/2009 .......... revised 7/12/2021 # # ------------------------------------------------------------------------------ # # Licensing: # # Copyright © Fred Weinhaus # # My scripts are available free of charge for non-commercial use, ONLY. # # For use of my scripts in commercial (for-profit) environments or # non-free applications, please contact me (Fred Weinhaus) for # licensing arrangements. My email address is fmw at alink dot net. # # If you: 1) redistribute, 2) incorporate any of these scripts into other # free applications or 3) reprogram them in another scripting language, # then you must contact me for permission, especially if the result might # be used in a commercial or for-profit environment. # # My scripts are also subject, in a subordinate manner, to the ImageMagick # license, which can be found at: http://www.imagemagick.org/script/license.php # # ------------------------------------------------------------------------------ # #### # # USAGE: textcleaner [-r rotate] [-l layout] [-c cropoff] [-g] [-e enhance ] # [-f filtersize] [-o offset] [-u] [-P] [-t threshold] [-s sharpamt] # [-s saturation] [-a adaptblur] [-T] [-p padamt] [-b bgcolor] [-F fuzzval] # [-i invert] [-C compression] infile outfile # USAGE: textcleaner [-help] # # OPTIONS: # # -r rotate rotate image 90 degrees in direction specified if # aspect ratio does not match layout; options are cw # (or clockwise), ccw (or counterclockwise) and n # (or none); default=none or no rotation # -l layout desired layout; options are p (or portrait) or # l (or landscape); default=portrait # -c cropoff image cropping offsets after potential rotate 90; # choices: one, two or four non-negative integer comma # separated values; one value will crop all around; # two values will crop at left/right,top/bottom; # four values will crop left,top,right,bottom # -g convert document to grayscale before enhancing # -e enhance enhance image brightness before cleaning; # choices are: none, stretch or normalize; # default=stretch # -f filtersize size of filter used to clean background; # integer>0; default=15 # -o offset offset of filter in percent used to reduce noise; # integer>=0; default=5 # -u unrotate image; cannot unrotate more than # about 5 degrees # -P preserve input size after unrotate # -t threshold text smoothing threshold; 0<=threshold<=100; # nominal value is about 50; default is no smoothing # -s sharpamt sharpening amount in pixels; float>=0; # nominal about 1; default=0 # -S saturation color saturation expressed as percent; integer>=0; # only applicable if -g not set; a value of 100 is # no change; default=200 (double saturation) # -a adaptblur alternate text smoothing using adaptive blur; # floats>=0; default=0 (no smoothing) # -T trim background around outer part of image # -p padamt border pad amount around outer part of image; # integer>=0; default=0 # -b bgcolor desired color for background or "image"; default=white # -F fuzzval fuzz value for determining bgcolor when bgcolor=image; # integer>=0; default=10 # -i invert invert colors; choices are: 1 or 2 for one-way or two-ways # (input or input and output); default is no inversion # -C compression TIFF output compression mode; choices are: none (n), # lzw(l), zip(z), fax(f), and group4(g); default=none # ### # # NAME: TEXTCLEANER # # PURPOSE: To process a scanned document of text to clean the text background. # # DESCRIPTION: TEXTCLEANER processses a scanned document of text to clean # the text background and enhance the text. The order of processing is: # 1) optional 90 degree rotate if aspect does not match layout # 2) optional crop, # 3) optional convert to grayscale, # 4) optional enhance, # 5) filter to clean background and optionally smooth/antialias, # 6) optional unrotate (limited to about 5 degrees or less), # 7) optional text smoothing, # 8) optional sharpening, # 9) optional saturation change (if -g is not specified), # 10) optional alternate text smoothing via adaptive blur # 11) optional auto trim of border (effective only if background well-cleaned), # 12) optional pad of border # # OPTIONS: # # -r rotate ... ROTATE image either clockwise or counterclockwise by 90 degrees, # if image aspect ratio does not match the layout mode. Choices are: cc (or # clockwise), ccw (or counterclockwise) and n (or none). The default is no rotation. # # -l layout ... LAYOUT for determining if rotation is to be applied. The choices # are p (or portrait) or l (or landscape). The image will be rotated if rotate is # specified and the aspect ratio of the image does not match the layout chosen. # The default is portrait. # # -c cropoffsets ... CROPOFFSETS are the image cropping offsets after potential # rotate 90. Choices: one, two or four non-negative integer comma separated # values. One value will crop all around. Two values will crop at # left/right,top/bottom. Four values will crop left,top,right,bottom. # # -g ... Convert the document to grayscale. # # -e enhance ... ENHANCE brightness of image. The choices are: none, stretch, # or normalize. The default=stretch. # # -f filtersize ... FILTERSIZE is the size of the filter used to clean up the # background. Values are integers>0. The filtersize needs to be larger than # the thickness of the writing, but the smaller the better beyond this. Making it # larger will increase the processing time and may lose text. The default is 15. # # -o offset ... OFFSET is the offset threshold in percent used by the filter # to eliminate noise. Values are integers>=0. Values too small will leave much # noise and artifacts in the result. Values too large will remove too much # text leaving gaps. The default is 5. # # -u ... UNROTATE the image. This is limited to about 5 degrees or less. # # -P ... PRESERVE input size after unrotate # # -t threshold ... THRESHOLD is the text smoothing threshold. Values are integers # between 0 and 100. Smaller values smooth/thicken the text more. Larger values # thin, but can result in gaps in the text. Nominal value is in the middle at # about 50. The default is to disable smoothing. # # -s sharpamt ... SHARPAMT is the amount of pixel sharpening to be applied to # the resulting text. Values are floats>=0. If used, it should be small # (suggested about 1). The default=0 (no sharpening). # # -S saturation ... SATURATION is the desired color saturation of the text # expressed as a percentage. Values are integers>=0. A value of 100 is no change. # Larger values will make the text colors more saturated. The default=200 # indicates double saturation. Not applicable when -g option specified. # # -a adaptblur ... ADAPTBLUR applies an alternate text smoothing using # an adaptive blur. The values are floats>=0. The default=0 indicates no # blurring. # # -T ... TRIM the border around the image. # # -p padamt ... PADAMT is the border pad amount in pixels. The default=0. # # -b bgcolor ... BGCOLOR is the desired background color after it has been # cleaned up. Any valid IM color may be use. If bgcolor=image, then the color will # be computed from the top left corner pixel and a fuzzval. The final color will be # computed subsequently as an average over the whole image. The default is white. # # -F fuzzval ... FUZZVAL is the fuzz value for determining bgcolor when bgcolor=image. # Values are integers>=0. The default=10. # # -i invert ... INVERT colors for example to convert white text on black background to # black text on white background. The choices are: 1 or 2 for one-way or two-ways # (input or input and output). The default is no inversion. # # -C compression ... COMPRESSION mode for TIFF output. The choices are: none (n), # lzw(l), zip(z), fax(f), and group4(g). The default=none. # # 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 rotate="none" # rotate 90 clockwise (cw) or counterclockwise (ccw) layout="portrait" # rotate 90 to match layout; portrait or landscape cropoff="" # crop amounts; comma separate list of 1, 2 or 4 integers numcrops=0 # number of crops flag gray="no" # convert to grayscale flag enhance="stretch" # none, stretch, normalize filtersize=15 # local area filter size offset=5 # local area offset to remove "noise"; too small-get noise, too large-lose text threshold="" # smoothing threshold sharpamt=0 # sharpen sigma saturation=200 # color saturation percent; 100 is no change adaptblur=0 # adaptive blur unrotate="no" # unrotate flag preserve="no" # preserve input size after unrotate flag trim="no" # trim flag padamt=0 # pad amount bgcolor="white" # color for output whiteboard background fuzzval=10 # fuzz value for determining bgcolor from image invert="" # invert colors: 1 or 2 compression="none" # TIFF compression modes # 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 -e '1,/^####/d; /^###/g; /^#/!q; s/^#//; s/^ //; 4,$p' "$PROGDIR/$PROGNAME" } usage2() { echo >&2 "" echo >&2 "$PROGNAME:" "$@" sed >&2 -e '1,/^####/d; /^######/g; /^#/!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 32 ] 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 ;; -r) # rotate shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID ROTATE SPECIFICATION ---" checkMinus "$1" rotate=`echo "$1" | tr "[:upper:]" "[:lower:]"` case "$rotate" in none|n) rotate="none" ;; clockwise|cw) rotate="cw" ;; counterclockwise|ccw) rotate="ccw" ;; *) errMsg "--- ROTATE=$rotate IS NOT A VALID CHOICE ---" ;; esac ;; -l) # layout shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID LAYOUT SPECIFICATION ---" checkMinus "$1" layout=`echo "$1" | tr "[:upper:]" "[:lower:]"` case "$layout" in portrait|p) layout="portrait" ;; landscape|l) layout="landscape" ;; *) errMsg "--- LAYOUT=$layout IS NOT A VALID CHOICE ---" ;; esac ;; -c) # get cropoffsets shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID CROPOFFSETS SPECIFICATION ---" checkMinus "$1" cropoff="$1" cropoff="${cropoff}," cropoff=`expr "$cropoff" : '\([,0-9]*\)'` numcrops=`echo "$cropoff" | tr "," " " | wc -w` [ "$cropoff" = "" ] && errMsg "--- ONE OR TWO OR FOUR OFFSETS MUST BE PROVIDED ---" [ $numcrops -ne 1 -a $numcrops -ne 2 -a $numcrops -ne 4 ] && errMsg "--- ONE OR TWO OR FOUR OFFSETS MUST BE PROVIDED ---" crop1=`echo "$cropoff" | cut -d, -f1` crop2=`echo "$cropoff" | cut -d, -f2` crop3=`echo "$cropoff" | cut -d, -f3` crop4=`echo "$cropoff" | cut -d, -f4` ;; -g) # set grayscale gray="yes" ;; -e) # get enhance shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID ENHANCE SPECIFICATION ---" checkMinus "$1" enhance="$1" case "$1" in none) ;; stretch) ;; normalize) ;; *) errMsg "--- ENHANCE=$enhance IS NOT A VALID CHOICE ---" ;; esac ;; -f) # get filtersize shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID FILTERSIZE SPECIFICATION ---" checkMinus "$1" filtersize=`expr "$1" : '\([0-9]*\)'` [ "$filtersize" = "" ] && errMsg "--- FILTERSIZE=$filtersize MUST BE A NON-NEGATIVE INTEGER ---" filtersizetest=`echo "$filtersize < 1" | bc` [ $filtersizetest -eq 1 ] && errMsg "--- FILTERSIZE=$filtersize MUST BE AN INTEGER GREATER THAN 0 ---" ;; -o) # get offset shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID OFFSET SPECIFICATION ---" checkMinus "$1" offset=`expr "$1" : '\([0-9]*\)'` [ "$offset" = "" ] && errMsg "--- OFFSET=$offset MUST BE A NON-NEGATIVE INTEGER ---" ;; -t) # get threshold shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID THRESHOLD SPECIFICATION ---" checkMinus "$1" threshold=`expr "$1" : '\([0-9]*\)'` [ "$threshold" = "" ] && errMsg "--- THRESHOLD=$threshold MUST BE A NON-NEGATIVE INTEGER ---" thresholdtestA=`echo "$threshold < 0" | bc` thresholdtestB=`echo "$threshold > 100" | bc` [ $thresholdtestA -eq 1 -o $thresholdtestB -eq 1 ] && errMsg "--- THRESHOLD=$threshold MUST BE AN INTEGER GREATER BETWEEN 0 AND 100 ---" ;; -s) # get sharpamt shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID SHARPAMT SPECIFICATION ---" checkMinus "$1" sharpamt=`expr "$1" : '\([.0-9]*\)'` [ "$sharpamt" = "" ] && errMsg "--- SHARPAMT=$sharpamt MUST BE A NON-NEGATIVE FLOAT ---" ;; -S) # get saturation shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID SATURATION SPECIFICATION ---" checkMinus "$1" saturation=`expr "$1" : '\([0-9]*\)'` [ "$saturation" = "" ] && errMsg "--- SATURATION=$saturation MUST BE A NON-NEGATIVE INTEGER ---" ;; -a) # get adaptblur shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID ADAPTBLUR SPECIFICATION ---" checkMinus "$1" adaptblur=`expr "$1" : '\([.0-9]*\)'` [ "$adaptblur" = "" ] && errMsg "--- ADAPTBLUR=$adaptblur MUST BE A NON-NEGATIVE FLOAT ---" ;; -u) # set unrotate unrotate="yes" ;; -P) # set preserve unrotate preserve="yes" ;; -T) # set trim trim="yes" ;; -p) # get padamt shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID PADAMT SPECIFICATION ---" checkMinus "$1" padamt=`expr "$1" : '\([0-9]*\)'` [ "$padamt" = "" ] && errMsg "--- PADAMT=$padamt MUST BE A NON-NEGATIVE INTEGER ---" ;; -b) # get bgcolor shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID BACKGROUND COLOR SPECIFICATION ---" checkMinus "$1" bgcolor="$1" ;; -F) # get fuzzval shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID FUZZVAL SPECIFICATION ---" checkMinus "$1" fuzzval=`expr "$1" : '\([0-9]*\)'` [ "$fuzzval" = "" ] && errMsg "--- FUZZVAL=$fuzzval MUST BE A NON-NEGATIVE INTEGER ---" ;; -i) # get invert shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID INVERT SPECIFICATION ---" checkMinus "$1" invert=`expr "$1" : '\([0-9]*\)'` [ "$invert" = "" ] && errMsg "--- INVERT=$invert MUST BE A NON-NEGATIVE INTEGER ---" testA=`echo "$invert < 1" | bc` testB=`echo "$invert > 2" | bc` [ $testA -eq 1 -o $testB -eq 1 ] && errMsg "--- INVERT=$invert MUST BE AN INTEGER VALUE OF 1 OR 2 ---" ;; -C) # compression shift # to get the next parameter # test if parameter starts with minus sign errorMsg="--- INVALID COMPRESSION SPECIFICATION ---" checkMinus "$1" compression=`echo "$1" | tr "[:upper:]" "[:lower:]"` case "$compression" in none|n) compression="none" ;; lzw|l) compression="lzw" ;; zip|z) compression="zip" ;; fax|f) compression="fax" ;; group4|g) compression="group4" ;; *) errMsg "--- COMPRESSION=$compression IS NOT A VALID CHOICE ---" ;; 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" tmpA1="$dir/textcleaner_1_$$.mpc" tmpA2="$dir/textcleaner_1_$$.cache" trap "rm -f $tmpA1 $tmpA2; exit 0;" 0 trap "rm -f $tmpA1 $tmpA2; exit 1" 1 2 3 15 #trap "rm -f $tmpA1 $tmpA2; exit 1" ERR # get im version im_version=`convert -list configure | \ sed '/^LIB_VERSION_NUMBER */!d; s//,/; s/,/,0/g; s/,0*\([0-9][0-9]\)/\1/g' | head -n 1` # test for hdri enabled # NOTE: must put grep before trap using ERR in case it does not find a match if [ "$im_version" -ge "07000000" ]; then hdri_on=`convert -version | grep "HDRI"` else hdri_on=`convert -list configure | grep "enable-hdri"` fi # colorspace RGB and sRGB swapped between 6.7.5.5 and 6.7.6.7 # though probably not resolved until the latter # then -colorspace gray changed to linear between 6.7.6.7 and 6.7.8.2 # then -separate converted to linear gray channels between 6.7.6.7 and 6.7.8.2, # though probably not resolved until the latter # so -colorspace HSL/HSB -separate and -colorspace gray became linear # but we need to use -set colorspace RGB before using them at appropriate times # so that results stay as in original script # The following was determined from various version tests using textcleaner # with IM 6.7.4.10, 6.7.6.10, 6.7.9.0 if [ "$im_version" -lt "06070607" -o "$im_version" -gt "06070707" ]; then setcspace="-set colorspace RGB" else setcspace="" fi # no need for setcspace for grayscale or channels after 6.8.5.4 if [ "$im_version" -gt "06080504" ]; then setcspace="" fi if [ "$invert" != "" ]; then inversion1="-negate" else inversion1="" fi # read the input image into the TMP cached image. convert -quiet "$infile" +repage $inversion1 "$tmpA1" || errMsg "--- FILE $infile NOT READABLE OR HAS ZERO SIZE ---" # get image size ww=`convert $tmpA1 -ping -format "%w" info:` hh=`convert $tmpA1 -ping -format "%h" info:` # get image h/w aspect ratio and determine if portrait=1 (h/w>1) or landscape=0 (h/w<1) aspect=`convert xc: -format "%[fx:($hh/$ww)>=1?1:0]" info:` #echo "ww=$ww; hh=$hh; aspect=$aspect" # set up rotation if [ "$layout" = "portrait" -a $aspect -eq 0 -a "$rotate" = "cw" ]; then rotation="-rotate 90" elif [ "$layout" = "portrait" -a $aspect -eq 0 -a "$rotate" = "ccw" ]; then rotation="-rotate -90" elif [ "$layout" = "landscape" -a $aspect -eq 1 -a "$rotate" = "cw" ]; then rotation="-rotate 90" elif [ "$layout" = "landscape" -a $aspect -eq 1 -a "$rotate" = "ccw" ]; then rotation="-rotate -90" else rotation="" fi # set up cropping if [ "$cropoff" != "" -a $numcrops -eq 1 ]; then wwc=`convert xc: -format "%[fx:$ww-2*$crop1]" info:` hhc=`convert xc: -format "%[fx:$hh-2*$crop1]" info:` cropping="-crop ${wwc}x${hhc}+$crop1+$crop1 +repage" elif [ "$cropoff" != "" -a $numcrops -eq 2 ]; then wwc=`convert xc: -format "%[fx:$ww-2*$crop1]" info:` hhc=`convert xc: -format "%[fx:$hh-2*$crop2]" info:` cropping="-crop ${wwc}x${hhc}+$crop1+$crop2 +repage" elif [ "$cropoff" != "" -a $numcrops -eq 4 ]; then wwc=`convert xc: -format "%[fx:$ww-($crop1+$crop3)]" info:` hhc=`convert xc: -format "%[fx:$hh-($crop2+$crop4)]" info:` cropping="-crop ${wwc}x${hhc}+$crop1+$crop2 +repage" else cropping="" fi #echo "cropoff=$cropoff; numcrops=$numcrops; cropping=$cropping" # test if grayscale grayscale=`convert $tmpA1 -format "%[colorspace]" info:` typegray=`convert $tmpA1 -format '%r' info: | grep 'Gray'` if [ "$gray" = "yes" -o "$grayscale" = "Gray" -o "$typegray" != "" ]; then makegray="$setcspace -colorspace gray -type grayscale" else makegray="" fi #echo "makegray=$makegray" # set up enhance if [ "$enhance" = "stretch" ]; then enhancing="$setcspace -contrast-stretch 0" elif [ "$enhance" = "normalize" ]; then enhancing="$setcspace -normalize" else enhancing="" fi #echo "enhancing=$enhancing" # setup blurring if [ "$threshold" = "" ]; then blurring="" else # note: any 0<bluramt<=1, will be the same as using bluramt=1, since radius must be used as an integer # bluramt=`convert xc: -format "%[fx:$threshold/100]" info:` # blurring="-blur ${bluramt}x65535 -level ${threshold}x100%" blurring="-blur 1x65535 -level ${threshold}x100%" fi #echo "blurring=$blurring" # get background color bgcolor=`echo "$bgcolor" | tr "[:upper:]" "[:lower:]"` if [ "$bgcolor" = "image" ]; then bgcolor=`convert $tmpA1 -format "%[pixel:u.p{0,0}]" info:` fuzzval=$((100-fuzzval)) bgcolor=`convert $tmpA1 -fuzz $fuzzval% +transparent "$bgcolor" -scale 1x1! -alpha off -format "%[pixel:u.p{0,0}]" info:` fi #echo "$bgcolor" # set up unrotate if [ "$unrotate" = "yes" -a "$preserve" = "yes" ]; then unrotating="-background $bgcolor -deskew 40% -gravity center -background $bgcolor -compose over -extent ${ww}x${hh}+0+0 +repage" elif [ "$unrotate" = "yes" -a "$preserve" = "no" ]; then unrotating="-background $bgcolor -deskew 40%" else unrotating="" fi #echo "unrotating=$unrotating" # setup sharpening if [ "$sharpamt" = "0" -o "$sharpamt" = "0.0" ]; then sharpening="" else sharpening="-sharpen 0x${sharpamt}" fi #echo "sharpening=$sharpening" # setup modulation [ "$gray" = "yes" -o "$grayscale" = "Gray" -o "$typegray" != "" ] && saturation=100 if [ $saturation -eq 100 ]; then modulation="" else modulation="-modulate 100,$saturation,100" fi #echo "modulation=$modulation" # set up adaptiveblurring if [ "$adaptblur" = "0" ]; then adaptiveblurring="" else adaptiveblurring="-adaptive-blur $adaptblur" fi # set up trim if [ "$trim" = "yes" -a "$hdri_on" != "" ]; then # hdri is enabled # need to round near white to pure white for trim to work trimming="-white-threshold 99.9% -trim +repage " elif [ "$trim" = "yes" -a "$hdri_on" = "" ]; then # hdri is not enabled trimming="-trim +repage " else trimming="" fi #echo "trimming=$trimming" # set up pad if [ $padamt -gt 0 ]; then # note must reset -compose from -compose copy_opacity as -border uses -compose padding="-compose over -bordercolor $bgcolor -border $padamt" else padding="" fi #echo "padding=$padding" if [ "$invert" = 2 ]; then inversion2="-negate" else inversion2="" fi # test compression for TIFF output ofile="${outfile##*/}" suffix="${ofile##*.}" suffix2=`echo "$suffix" | tr "[:upper:]" "[:lower:]"` if [ "$suffix2" = "tiff" -o "$suffix2" = "tif" ]; then compressing="-compress $compression" else compressing="" fi # process image convert -respect-parenthesis \( $tmpA1 $rotation $cropping $makegray $enhancing \) \ \( -clone 0 $setcspace -colorspace gray -negate -lat ${filtersize}x${filtersize}+${offset}% -contrast-stretch 0 $blurring \) \ -alpha off -compose copy_opacity -composite -fill "$bgcolor" -opaque none -alpha off \ $unrotating $sharpening $modulation $adaptiveblurring $trimming $padding $inversion2 $compressing \ "$outfile" exit 0