#!/usr/bin/perl -w # # Image to Text v1.0 # by f roque # #converts a b&w png or jpeg image to text from a specified file. $|=1; use GD; use strict; use Getopt::Std; my %opt; #check to make sure we have been called correctly PrintUsage() && exit unless getopts('vrph:w:H:W:i:t:l:d:', \%opt); #set default variables my $threshold = defined($opt{'d'}) ? $opt{'d'} : 128; my $verbose = defined($opt{'v'}) ? 1 : 0; my $reverse = defined($opt{'r'}) ? 1 : 0; my $preserve = defined($opt{'p'}) ? 1 : 0; my $w = defined($opt{'w'}) ? $opt{'w'} : 1; my $h = defined($opt{'h'}) ? $opt{'h'} : 1; my $W = defined($opt{'W'}) ? $opt{'W'} : 0; my $H = defined($opt{'H'}) ? $opt{'H'} : 0; my $imgfile = defined($opt{'i'}) ? $opt{'i'} : PrintUsage() && exit; my $txtfile = defined($opt{'t'}) ? $opt{'t'} : $0; #read in and parse the text to use print STDERR "Reading in text..." if $verbose; open(TEXT, $txtfile) or die "Error opening $txtfile: $!"; my @text = ; close(TEXT); my $text = join('', @text); $text =~ s/\s//gs; @text = split(//, $text); undef($text); print STDERR "...done\n" if $verbose; #read in and resize the image to use print STDERR "Reading in image..." if $verbose; my $image; if ($imgfile =~ /png$/i) { $image = GD::Image->newFromPng($imgfile); } elsif ($imgfile =~ /jpg$/i) { $image = GD::Image->newFromJpeg($imgfile); } else { die "Error: unknown file type!"; } my ($x, $y) = $image->getBounds(); #resize the image if ($w != 1 or $h != 1 or $W or $H) { print STDERR "...resizing..." if $verbose; if ($preserve && ($W or $H)) { if ($W && !$H) { $H = ($y/$x)*$W; } if ($H && !$W) { $W = ($x/$y)*$H; } } my $x2 = $W ? $W : $x; my $y2 = $H ? $H : $y; my $oimage = $image; $y2 = int($y2*$h); $y2 = 1 unless $y2 > 0; $x2 = int($x2*$w); $x2 = 1 unless $x2 > 0; $image = GD::Image->new($x, $y2); $image->copyResized($oimage,0,0,0,0,$x2,$y2,$x,$y); $y = $y2; $x = $x2; } print STDERR "...done\n" if $verbose; #run through image printing either a character from text or a blank print STDERR "Printing out text image..." if $verbose; my $p = 0; for my $n (0..$y-1) { for my $m (0..$x-1) { my ($r, $g, $b) = $image->rgb($image->getPixel($m, $n)); if (($r+$g+$b)/3 >= $threshold) { print $reverse ? $text[$p++] : ' '; } else { print $reverse ? ' ' : $text[$p++]; } $p = 0 if $p > $#text; } print "\n"; } print STDERR "...done\n" if $verbose; exit; sub PrintUsage { print STDERR "usage: $0 [options]\n"; print STDERR "\t-r reverse colours\n"; print STDERR "\t-p preserve ratio (used with -H and -W)\n"; print STDERR "\t-d threshold rgb value to consider white/black\n\n"; print STDERR "\t-h height resize height by this amount\n"; print STDERR "\t-w width resize width by this amount\n"; print STDERR "\t-H pixels resize height to this many pixels\n"; print STDERR "\t-W pixels resize width to this many pixels\n\n"; print STDERR "\t-i imagefile png image file\n"; print STDERR "\t-t textfile text file\n\n"; print STDERR "\t-v verbose output\n\n"; } =head1 NAME image2text - image to text converter =head1 SYNOPSIS image2text [options] -r reverse colours -p preserve ratio (used with -H and -W) -d threshold rgb value to consider white/black -h height resize height by this amount -w width resize width by this amount -H pixels resize height to this many pixels -W pixels resize width to this many pixels -i imagefile png image file -t textfile text file -v verbose output =head1 DESCRIPTION B converts a png or jpeg image into a text file similar to the image. If the image is not already black and white, it attempts to convert the image to black and white. It can also resize the image. =head1 EXAMPLES convert image.png to text in text.txt file image2text -i image.png -t text.txt convert image.png to text in text.txt file after resizing height by 80% image2text -i image.png -t text.txt -h.8 convert image.png to text in text.txt file after resizing height by 40% and resizing width by 40% (this will produce image similar to previous sample but have as big) image2text -i image.png -t text.txt -h.4 -w.5 convert image.png to text in text.txt file after resizing height to 89 pixels and preserving ratio of width to height, then resizing height to 80% of 89, and converting the image to b&w based on a threshold of 50 image2text -i image.png -t text.txt -H89 -p -h.8 -d50 a character of text is higher than it is wide, unlike a pixel which has the same height as width, so you will want to scale the height of the image in relation to the width. i've found that a ratio of .8:1 works well, hence the "-h.8" and "-w.5 -h.4" used above. =head1 AUTHOR frisco@blackant.net