Auto-cropping scanned images

Posted on September 30th, 2008

Yesterday i needed to scan a few photos. Some of them really old and thus: no color, low contrast.

Needless to say i didnt want to crop them all by hand, so i started looking around for things that could make it easier for me. Unfortunately the things that i did find didnt really do the job, they got confused by dark spots from dust, darker areas on the very borders of the scans (yeah, crappy scanner, i know) or they just cropped too much of some very low contrast images!

BTW: There is a way of doing this really nicely in CS2 apparently, even allowing multiple photos in one scan, but i dont hav that around! :-(

So... I came up with this little script:

#!/bin/bash

DEVICE=`scanimage -L | sed "s/^device \`//;s/'.*\$//"`

if [ -z "$FUZZ" ]; then
	FUZZ="15"
fi
if [ -z "$OVERSCAN" ]; then
	OVERSCAN=1
fi

RAW="raw_$1.tiff"
SMALL="small_$1.jpg"
SMALL_DOT="small_dot_$1.jpg"
TRIMMED="trimmed_$1.jpg"
TRIMMED_DOT="trimmed_dot_$1.jpg"
FINAL="foto_$1.jpg"

scanimage -d "$DEVICE" -p --format tiff --resolution $(( 300 * $OVERSCAN )) --mode Color | convert - -resize $(( 100 / $OVERSCAN ))% -crop 90x90+5+2% "$RAW"
RAW_WIDTH=`identify -format "%w" "$RAW"`
RAW_HEIGHT=`identify -format "%h" "$RAW"`

convert "$RAW" -resize "10%" "$SMALL"

SMALL_WIDTH=`identify -format "%w" "$SMALL"`
SMALL_HEIGHT=`identify -format "%h" "$SMALL"`

convert "$SMALL" -draw 'point 0,0' "$SMALL_DOT"

convert "$SMALL" -fuzz "$FUZZ%" -trim "$TRIMMED"
convert "$SMALL_DOT" -fuzz "$FUZZ%" -trim "$TRIMMED_DOT"

TRIMMED_WIDTH=`identify -format "%w" "$TRIMMED"`
TRIMMED_HEIGHT=`identify -format "%h" "$TRIMMED"`

TRIMMED_DOT_WIDTH=`identify -format "%w" "$TRIMMED_DOT"`
TRIMMED_DOT_HEIGHT=`identify -format "%h" "$TRIMMED_DOT"`

OFFSET_X=$(( 20 + $RAW_WIDTH * ($TRIMMED_DOT_WIDTH - $TRIMMED_WIDTH) / $SMALL_WIDTH ))
OFFSET_Y=$(( 20 + $RAW_HEIGHT * ($TRIMMED_DOT_HEIGHT - $TRIMMED_HEIGHT) / $SMALL_HEIGHT ))
WIDTH=$(( $RAW_WIDTH * $TRIMMED_WIDTH / $SMALL_WIDTH - 40 ))
HEIGHT=$(( $RAW_HEIGHT * $TRIMMED_HEIGHT / $SMALL_HEIGHT - 40 ))

echo "CROP: $WIDTH x $HEIGHT + $OFFSET_X + $OFFSET_Y"
convert "$RAW" -crop "${WIDTH}x${HEIGHT}+${OFFSET_X}+${OFFSET_Y}" "$FINAL"

rm "$RAW" "$SMALL" "$SMALL_DOT" "$TRIMMED" "$TRIMMED_DOT"

This will scan an image and try to crop the background, the background should be white for best results! :-)
You can overwrite the fuzzyness using the FUZZ env-variable, so if you happen to have a very low contrast image, try FUZZ=5 or similar!

So long!!
:-)

AddThis button



About Me

Photo of myself Aike J Sommer
web [at] aikesommer [dot] name
Feed: RSS Syndicate content
Company: AS Media