Finance-MICR-GOCR-Check

 view release on metacpan or  search on metacpan

lib/Finance/MICR/GOCR/Check.pm  view on Meta::CPAN

package Finance::MICR::GOCR::Check;
use strict;
use warnings;
use Finance::MICR::LineParser;
use Finance::MICR::GOCR;
use File::PathInfo;
use Image::Magick;

our $VERSION = sprintf "%d.%02d", q$Revision: 1.3 $ =~ /(\d+)/g;

$Finance::MICR::GOCR::Check::DEBUG=0;
sub DEBUG : lvalue { $Finance::MICR::GOCR::Check::DEBUG }






=pod

=head1 NAME

Finance::MICR::GOCR::Check - scan a check scan image file for a valid micr line

=head1 SYNOPSIS

	use Finance::MICR::Check;

	my $c = new Finance::MICR::GOCR::Check({ abs_check => '/path/to/check_CHECK.png });

   $c->found_valid;

=head1 DESCRIPTION

This object oriented module scans a check for a valid micr line.

The present status is pre release.

=head2 PREPPING

It can prep a check if it's turned 90 degrees right (batch scan in Canon scanners produce that).

=head2 SCAN ITERATIONS

The way the module works, after copying the target file to a temp directory, it creates smaller image 
excerpts from the bottom up and feeds it to Finance::MICR::GOCR , tests for validity with Finance::MICR::LineParser.

When a valid match is found it stops. See L<SCAN ITERATION METHODS>.


=head1 METHODS

The main methods you will likely be using are new() and parser().
The other methods are called internally, or can be called to tweak the process.

=cut

sub new {
	my ($class, $self) = (shift, shift);
	$self ||={};

	$self->{on_us_symbol} ||=  'CCc';
	$self->{transit_symbol} ||=  'Aa';
	$self->{dash_symbol} ||=  'DDd';
	$self->{ammount_symbol} ||=  'XxX';
	$self->{MICR_height} ||= 78;
	$self->{MICR_append} ||= '_MICR.png';

lib/Finance/MICR/GOCR/Check.pm  view on Meta::CPAN

	my $arg = shift; #ref $arg eq 'HASH' or croak('_creat_micr() arg must be hash');
	print STDERR "creating a micr extraction from the image..\n" if DEBUG;
	
	$arg ||= {};
	$arg->{abs_check}		||= $self->f->abs_path;
   $arg->{MICR_height}	||= $self->{MICR_height};
	$arg->{CHECK_height} ||= $self->{CHECK_height};
	$arg->{id} ||= time;
	
	
	$arg->{abs_micr}		||= '/tmp/.'.$$arg{id}.'_'.$$arg{MICR_height}.'_'.time .$self->{MICR_append};

	$arg->{abs_check} or croak('missing abs_check arg, this is the check file to read');
	$arg->{abs_micr} or croak('missing abs_micr arg  this is where you want to output the file');
	$arg->{MICR_height} or croak('missing MICR_height');
	$arg->{CHECK_height} or croak('missing CHECK_height');
	

	my $i = $self->im;

	
	my($cropy,$cropx)=(0,0);
	
	my($h,$w) = $i->Get('height','width');	

	print STDERR "h $h, w $w\n" if DEBUG;


	# crop sides.. how much?
	if ($self->crop_sides){
		print STDERR "cropping sides\n" if DEBUG;
		my $minus = int ($w * $self->crop_sides);# minus 15% width is default (0.15)
		$cropy = int( $minus/2 );
		$w = ($w - $minus); 
	}


	my $target_h =	int ( ($arg->{MICR_height} * $h) / $arg->{CHECK_height} );	$target_h or confess('cant determine target height');
	print STDERR "target h $target_h\n" if DEBUG;
   
	$cropy = ($h-$target_h);
	
	print STDERR "crop y $cropy\n" if DEBUG;
	
	
	my $x = $i->Crop( width => $w, height => 72, x => $cropx,y => $cropy);
	
	warn "$x" if "$x";

	$x =$i->Write($arg->{abs_micr});
	warn "$x" if "$x";

   print STDERR "saved $$arg{abs_micr}\n" if DEBUG;
	return $arg->{abs_micr};
}

sub im { # object containing image magick object already reading the check image
	my $self = shift;
	
	unless( defined $self->{im} ){
		my $i = new Image::Magick;
		$i->Read($self->f->abs_path);
		$self->{im} = $i;
	}
	return $self->{im}->Clone;
}

=head2 im()

returns clone of image magick object that already read check image

=cut






=head1 REPORTING

=cut

sub save_report {
   my $self = shift;
	require YAML;
	YAML::DumpFile( $self->abs_report, $self->_status);	   
   printf STDERR "abs report saved %s\n", $self->abs_report if DEBUG;
   return $self->abs_report;
}

sub _status {
	my $self= shift;
   my $status = {
			is_prepped => $self->is_prepped,
			abs_path => ($self->f->abs_path || undef), 
			_micr => ($self->_micr || undef), 
			LineParser_status => ($self->parser->status || undef),
         is_valid => $self->parser->valid ,   
	};	   
   return $status;
}

sub get_report {
	my $self = shift;
	my $report = File::Slurp::read_file($self->f->abs_loc.'/'.$self->report_filename);
	return $report;
}

sub abs_report {
	my $self = shift;
	my $where = $self->f->abs_loc .'/'.$self->report_filename;
	return $where;
}

sub report_filename {
	my $self = shift;
	my $filename = $self->f->filename.'.report';	
	return $filename;
}

=head2 save_report()



( run in 1.522 second using v1.01-cache-2.11-cpan-97f6503c9c8 )