#!/usr/bin/perl -w
use strict;
use Getopt::Long;
# Converts the image given in the first argument into
# the format of the second argument. Decides how to do it
# based on the filenames of the source and destination
#
my $usage =
"Usage: image_convert.pl [--scale scale_filename] [--res resolution] source_file destination_file\n ";
# A global hash to hold command-line arguments.
my $cliArgs = {};
my $DEFAULT_SCALE = 0.75;
my $DEFAULT_MAXX = 5;
my $DEFAULT_MAXY = 8;
my $DEFAULT_RESOLUTION = 72;
sub max { return $_[0] > $_[1] ? $_[0] : $_[1]; }
sub min { return $_[0] < $_[1] ? $_[0] : $_[1]; }
sub getIMGdetails {
# Takes the image filename as the only argument, returns the image
# size in inches.
# If the identify program is available:
# Determine the current geometry and resolution of the image.
# Return the image size in inches.
# Otherwize return 0,0.
my ($img) = shift;
# # If the identify program is not available, bail.
(`which identify 2>\&1` =~ /^which:/) and
die "identify program (part of Imagemagick) not available -- aborting\n";
my $attrib = {};
# Determine the size of the existing image.
my $response = `identify -verbose $img`;
if ($response =~ /^identify: no decode delegate/ or
!$response) {
return 0;
}
($attrib->{format}) =
$response =~ /^\s*Format:\s+(\S*)\s+/m;
($attrib->{hdots},$attrib->{vdots}) =
$response =~ /^\s*Geometry:\s*([\d\.]*)x([\d\.]*)/m;
($attrib->{hres},$attrib->{vres}) =
$response =~ /^\s*Resolution:\s*([\d\.]*)x([\d\.]*)/m;
$attrib->{hsize} = $attrib->{hdots} / $attrib->{hres};
$attrib->{vsize} = $attrib->{vdots} / $attrib->{vres};
return $attrib;
}
sub doConversion {
my ($cli,$scales) = @_;
my ($attrib,$ourScale,$newsizex,$newsizey);
# Get the input file details.
$attrib = getIMGdetails($cli->{infile});
if (ref($attrib) ne 'HASH') {
# Identify failed.
die "Failed to Identify Input Image File $cli->{infile}. Aborting\n";
}
# If the scale factor is defined in the file of scale factors,
# use that. Otherwise use the default scale provided on the command line,
# If none was provided, use 0.75.
if (defined($scales->{$cli->{infile}})) {
$ourScale = $scales->{$cli->{infile}};
} else {
if (defined $cli->{defaultscale}) {
$ourScale = $cli->{defaultscale};
} else { $ourScale = $DEFAULT_SCALE; }
# If after scaling the image is still too big, scale it to the max
# size. Otherwise, scale it according to the scale factor.
if ($attrib->{hsize} * $ourScale > $cli->{maxx} or
$attrib->{vsize} * $ourScale > $cli->{maxy}) {
$ourScale /= max($attrib->{hsize} * $ourScale / $cli->{maxx},
$attrib->{vsize} * $ourScale / $cli->{maxy});
}
}
$newsizex = $attrib->{hsize} * $ourScale;
$newsizey = $attrib->{vsize} * $ourScale;
# Get strings ready for the convert command.
my $cdots = sprintf "%dx%d",$newsizex * $cli->{resolution},
$newsizey * $cli->{resolution};
my $cres = sprintf "%dx%d",$cli->{resolution},$cli->{resolution};
# Do the conversion...
printf "Scaling by %.5f : %s -> %s\n",$ourScale,$cli->{infile},$cli->{outfile};
print STDERR `convert $cli->{infile} -resize $cdots -density $cres $cli->{outfile}`;
# if ($cli->{infile} =~ /.*\.png$/ and $cli->{outfile} =~ /.*\.pdf$/) {
# printf "Scaling %s to %s with scale %.3f\n",$cli->{infile},$cli->{outfile},$ourScale;
# print STDERR `pngtopnm $cli->{infile} | pnmtops -scale=$ourScale -noturn -nosetpage | epstopdf --filter > $cli->{outfile}`;
# pngtopnm $${i}.png | pnmtops -scale=0.85 --noturn -nosetpage | epstopdf --filter >$${i}.pdf ;
# } elsif ($cli->{infile} =~ /.*\.png$/ and $cli->{outfile} =~ /.*\.eps$/) {
# printf "Scaling %s to %s with scale %.3f\n",$cli->{infile},$cli->{outfile},$ourScale;
# print STDERR `pngtopnm $cli->{infile} | pnmtops -scale=$ourScale -noturn -nosetpage > $cli->{outfile}`;
# pngtopnm $${i}.png | pnmtops -scale=0.65 --noturn -nosetpage >$${i}.eps;
# } elsif ($cli->{infile} =~ /.*\.jpg$/ and $cli->{outfile} =~ /.*\.png$/) {
# printf "Converting %s to %s\n",$cli->{infile},$cli->{outfile};
# print STDERR `jpegtopnm $cli->{infile} | pnmtopng > $cli->{outfile}`;
# jpegtopnm $${i}.jpg | pnmtopng >$${i}.png ;
# } elsif ($cli->{infile} =~ /.*\.gif$/ and $cli->{outfile} =~ /.*\.png$/) {
# printf "Converting %s to %s\n",$cli->{infile},$cli->{outfile};
# print STDERR `giftopnm $cli->{infile} | pnmtopng > $cli->{outfile}`;
# giftopnm $${i}.gif | pnmtopng >$${i}.png ;
# } else {
# die "Unsupported Conversion: $cli->{infile} to $cli->{outfile}\n";
# }
# Save the image scale for putting into the file of scales.
$scales->{$cli->{infile}} = $ourScale;
}
sub loadImgScales {
# Loads the image scales from the specified file into the
# global hash %imgScales
my $scaleFile = shift;
my ($imagename,$scale,$cnt);
my %imgScales;
if (!open (IF,"<$scaleFile")) {
warn "File of Image Scales not Found. Will create one when needed.\n";
} else {
$cnt = 0;
while (<IF>) {
$cnt++;
chomp;
my ($imagename,$scale) = split /\s+/;
if (!defined $imagename or !defined $scale or
$scale !~ /^[\-\+\d\.]+$/ or $scale < 0.01 or $scale > 100) {
print STDERR "Invalid Image Scale Entry at line $cnt in $scaleFile\n";
} else {
$imgScales{$imagename} = $scale;
}
}
close IF;
}
return { %imgScales };
}
sub writeImgScales {
my ($fileName,$scales) = @_;
open OF,">$fileName" or die "Cannot open scale file $fileName for output\n";
foreach (sort(keys(%{$scales}))) { printf OF "%s %.5f\n",$_,$scales->{$_}; }
close OF;
}
sub getCliArgs {
# Sets up the parameters and gets the command-line
# options. $args is a pointer to a hash.
my $args = shift;
my ($infile,$outfile,@filenames);
# Establish defaults:
$args->{defaultscale} = $DEFAULT_SCALE;
$args->{maxx} = $DEFAULT_MAXX;
$args->{maxy} = $DEFAULT_MAXY;
$args->{resolution} = $DEFAULT_RESOLUTION;
GetOptions( "scalefile=s" => \$args->{scalefile},
"defaultscale=f" => \$args->{defaultscale},
"resolution=i" => \$args->{resolution},
"maxx=f" => \$args->{maxx},
"maxy=f" => \$args->{maxy},
) or die $usage;
# There should be just the input and output filenames and
# nothing more in @filenames
$args->{infile} = shift @ARGV;
$args->{outfile} = shift @ARGV;
if (!defined $args->{outfile}) { die $usage; }
}
###############################################
############## MAIN ###########################
###############################################
my ($scales);
# Get the command-line arguments into the global hash.
getCliArgs($cliArgs);
#foreach (sort(keys(%$cliArgs))) {
# print "$_ $cliArgs->{$_}\n";
#}
if (! -e $cliArgs->{infile}) {die "Input File not Found: $cliArgs->{infile}\n";}
# Load in the image conversion scales from the file of scale factors.
if (defined $cliArgs->{scalefile}) {
if (-e $cliArgs->{scalefile}) {
$scales = loadImgScales($cliArgs->{scalefile});
} else {
warn "File of Image Scales not Found. Will create one when needed.\n";
}
}
# Process the file.
doConversion($cliArgs,$scales);
# Write the file of scale factors.
writeImgScales($cliArgs->{scalefile},$scales);
syntax highlighted by Code2HTML, v. 0.9.1