#!/bin/bash # # divide_vert [-i] image multi_image # # Divide an image horizontally into rows of images consisting of alternating # images of variable colors (interesting parts) and images of a single solid # color (seperating gaps) that when appended together vertically will # re-produce the original image. # # Options... # -i Don't output (delete) the uninteresting 'gaps' between the rows. # # Examples... # # Expand the row spacing of some text by 4 pixels (must be a multiple of two) # # convert -size 50x caption:'This is a word wrapped line of text' miff:- |\ # divide_vert - miff:- | convert - -splice 0x2 -append gap_expansion.png # # This will remove all gaps between lines of text... # # convert -size 50x caption:'This is a word wrapped line of text' miff:- |\ # divide_vert -i - miff:- | convert - -append gaps-removed.png # # Replace all gaps by a fixed amount (5 pixels), # though this is not a good idea for normal text images. # # convert -size 50x caption:'This is a word wrapped line of text' miff:- |\ # divide_vert -i - miff:- |\ # convert - -splice 0x5 -append \ # -gravity south -splice 0x5 gaps_replaced.png # # If you want to split on gaps of a specific color you can use -splice or # -border to add a single column of that color along the left edge. # # FUTURE: # * Expand to allow fuzzy matching of the colors in each row and gap. # This is needed for scanned and JPEG images. # * Allow dividing the image into 'columns' instead of 'rows'. # * Specify a minimum 'gap' size, to allow 'paragraph/word' seperation # * Optionally divide the 'gap' equally bettween each 'interesting' row That # is every image contains 'interesting' parts, surrounded by some 'blank' # of 'gap' spacing. # * Save images with 'virtual (page) offsets' to preserve their location. # The result will be a collection of 'layer' images rather than 'simple' # rows. such 'layer' images will then allow you to separate an image # first vertically by 'row', then horizontally by 'column' producing # a exploded layed image of either individual characters or words. # It will also let you do automated "GIF animation splitting". # ### # # Anthony Thyssen 25 June 2007 A.Thyssen_AT_griffith.edu.au # 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 Usage() { # output the script comments as docs echo >&2 "$PROGNAME:" "$@" sed >&2 -n '/^###/q; /^#/!q; s/^#//; s/^ //; 3s/^/Usage: /; 2,$ p' \ "$PROGDIR/$PROGNAME" exit 10; } while [ $# -gt 0 ]; do case "$1" in --help|--doc*) Usage ;; -i) IGNORE_GAPS=true ;; # do not output blank gap images. --) shift; break ;; # end of user options -) break ;; # STDIN end of user options -*) Usage "Unknown option \"$1\"" ;; *) break ;; # end of user options esac shift # next option done input="$1" # Read from this IM input file format, may be a pipe output="$2" # Write to this IM input file format, may be a pipe # Handle the many temporary files needed. tmpdir=/tmp/$PROGNAME.$$ mkdir $tmpdir if [ $? -ne 0 ]; then echo >&2 "$PROGNAME: Failed to create directory \"$tmpdir\" -- ABORTING" exit 1 fi trap "rm -rf $tmpdir; exit 0" 0 trap "rm -rf $tmpdir; exit 1" 1 2 3 15 # Read input image, once only as it may be pipelines, and save a MPC copy of it. # Return the height of that image. height=`convert "$input" -format '%[fx:u.h-1]' -identify $tmpdir/original.mpc` count=0 # the number of divisions found in the file # Divide image into individual rows and # Get the number of colors, and first color from each row! convert $tmpdir/original.mpc -crop 0x1 +repage \ -format '%k %[pixel:s]' info:$tmpdir/image_data exec <$tmpdir/image_data # read from this data as STDIN read top_cnum top_color # get the color count, and first pixel color top=0 # the top row of current area being divided # Divide the image basied on the number of colors (or change in gap color) for x in `seq 1 $height`; do read cnum color if [ $top_cnum -eq 1 -a \( $cnum -ne 1 -o "$top_color" != "$color" \) ] || [ $top_cnum -ne 1 -a $cnum -eq 1 ]; then # We found the end of a variable image or single color 'blank' gap if [ $top_cnum -ne 1 -o ! "$IGNORE_GAPS" ]; then # Save this division from the original image h=`expr $x - $top` # height of region file=`printf "$tmpdir/divisions_%06d.mpc" $count` # save the division convert $tmpdir/original.mpc -crop 0x$h+0+$top +repage $file fi # note the information for the next area to be divided top=$x top_cnum=$cnum top_color="$color" count=`expr $count + 1` # we found this many divisions. fi done if [ $count -eq 0 ]; then # No divisions were found, so just output image (via convert again) if [ $top_cnum -ne 1 -o ! "$IGNORE_GAPS" ]; then convert $tmpdir/original.mpc "$output" else # image is blank, BUT we were asked to not output blank images! # This is imposible, so ouput the 'null' error image convert null: "$output" fi else # Extract the final split (if wanted) if [ $top_cnum -ne 1 -o ! "$IGNORE_GAPS" ]; then # save the last division that is present in the original image h=`expr $height + 1 - $top` # height of region file=`printf "$tmpdir/divisions_%06d.mpc" $count` convert $tmpdir/original.mpc -crop 0x$h+0+$top +repage $file fi #count=`expr $count + 1` #echo >&2 "split_horiz: Found $count divisions" # output the parts that were saved, if any! if ls -d $tmpdir/divisions_*.mpc >/dev/null 2>/dev/null; then # Output all the divisions as a posible multi-image file convert $tmpdir/divisions_*.mpc "$output" else # No divisions were found! presumably we are ignoring gaps! # This should be imposible, so ouput the 'null' error image convert null: "$output" fi fi