rossz said:
I need to adjust an image to a minimum size, but without distoring it,
so I basically want to add space evenly around the existing image.
----------------------
a while back I wrote some tools to resize and build thumbnails for a
photo gallery site (
http://www.NormsGallery.com) and I thought I'd
post the sub that does most of the image sizing for you to look at.
Its probably not the most glamorous way to do it, and perhaps Martin
will suggest some improvements.
d
--------------
sub SizeAndThumb { my ( $FileNameIn ) = @_ ;
=head1 Purpose
This sub examines the current size of image passed in, and re-samples
so that it fits within the maximum allowable area defined by
$cMaxFullimgX , $cMaxFullimgY . If $cAnnotateText is defined, it will
also add the annotation.
Resampling is always done, even if the image is already the right
size
so that it get save with the right compression quality. Image might
have
been uploaded at higher quality with larger filesize.
Then, a thumbnail image is created with the name
$FileNameIn_$cMaxThumbimgX .
=head1 Input
$FileNameIn = relative path to a single image file to process
=head1 Output
- overwrites $FileNameIn, and creates a thumbnail image in the same
folders with a name based on $FileNameIn_$cMaxThumbimgX
- returns a 0 for success, or an error message string
=head1 Notes and Usage
# Note that subConfig.pl MUST be required in main:: because it uses
parameters:
#
( $cMaxFullimgX , $cMaxFullimgY ) = (600,400);
( $cMaxThumbimgX , $cMaxThumbimgY ) = (100,100);
$cImageQuality = 75 ; # value 10-90
$cAnnotateFont = '@Comic.ttf' ;
$cAnnotatePointsize = 11 ;
$cAnnotateText = '(c)2000
www.NormsGallery.com' ; # set undef to skip
annotation
$cLowSRCText = '(c)2000
www.NormsGallery.com' ; # set undef to image
label
$ErrorMsg = &SizeAndThumb( $FileNameIn ); # returns 0 for success,
# $ErrorMsg for failure
This sub does NOT die on error, but does return an error message, so
the calling script can decide to die or continue.
=head1 History
written 10/18/2000 - Dan Baker, dan_at_dtbakerprojects.com
revised 12/3/2000 - changed to use Scale() instead of Sample()
- recoded Annotate() section for light outline
=cut
# ------------------------------------------------------------------------------
# declarations
use lib "./lib/perl5/site_perl/5.005/i386-linux" ;
use Image::Magick;
# local var declarations
my $tempString = "";
my $ErrMsg = "";
my $DoSample = "true" ;
# ------------------------------------------------------------------------------
# -------------------------------- executable ---------------
# read $FileNameIn to new object
# -----
my $image = Image::Magick->new;
$ErrMsg = $image->Read( $FileNameIn ) ;
if ($ErrMsg ) {
return( "$ErrMsg : Image-Magick could not read $FileNameIn " );
} elsif ( $cDEBUG ) {
print DEBUG_LOG "read $FileNameIn into ImageMagick object. \n" ;
}
# re-size
# -----
$ErrMsg = $image->Scale( geometry=>"${cMaxFullimgX}x${cMaxFullimgY}"
);
if ($ErrMsg ) {
return( "$ErrMsg : Image-Magick could not re-size $FileNameIn " );
} elsif ( $cDEBUG ) {
print DEBUG_LOG "resized $FileNameIn to ${MaxFullimgX}x${MaxFullimgY}
\n" ;
}
# annotate if text is defined
# -----
my $DidAnnotate = 0;
if ( $cAnnotateText ) { # only annotate if a text string is defined
print DEBUG_LOG "\t attempting to annotate. \n" if $cDEBUG ;
# we cant trust gravity=>'South' or 'North
# so figure offset manually
# -----
# get actual scaled size
my ( $imgX , $imgY ) = $image->Get('columns', 'rows');
my ( $Xoffset , $Yoffset ) = (0 , 0) ;
my $AnnotateOutline = 'LightGrey' ;
my $AnnotatePen = 'Black' ;
# figure out $Xoffset
# -----
$Xoffset = int( $imgX/2 -
(length($cAnnotateText)*($cAnnotatePointsize/1.5))/2 ) ;
# set up for differences between v4.2.9 and 5.2.4
# -----
if ( $^O =~ m/mswin32/i ) { # calculations for v4.2.9 on win98
# use $cAnnotatePointsize from config file
$Yoffset = int($imgY*.90) ;
} else { # calculations for v5.2.4 on LINUX
$cAnnotatePointsize += 3 ; # has to be set bigger to match
$Yoffset = int($imgY*.93) ;
}
# insert 8 instances of annotation in outline positions and color,
# 1 pixel offset in all directions
$image->Annotate( text=>$cAnnotateText ,
font=> $cAnnotateFont ,
pointsize=> $cAnnotatePointsize ,
pen=> $AnnotateOutline ,
x=> $Xoffset -1 ,
y=> $Yoffset -1 ,
);
$image->Annotate( text=>$cAnnotateText ,
font=> $cAnnotateFont ,
pointsize=> $cAnnotatePointsize ,
pen=> $AnnotateOutline ,
x=> $Xoffset -1 ,
y=> $Yoffset ,
);
$image->Annotate( text=>$cAnnotateText ,
font=> $cAnnotateFont ,
pointsize=> $cAnnotatePointsize ,
pen=> $AnnotateOutline ,
x=> $Xoffset -1 ,
y=> $Yoffset +1 ,
);
$image->Annotate( text=>$cAnnotateText ,
font=> $cAnnotateFont ,
pointsize=> $cAnnotatePointsize ,
pen=> $AnnotateOutline ,
x=> $Xoffset ,
y=> $Yoffset +1 ,
);
$image->Annotate( text=>$cAnnotateText ,
font=> $cAnnotateFont ,
pointsize=> $cAnnotatePointsize ,
pen=> $AnnotateOutline ,
x=> $Xoffset +1 ,
y=> $Yoffset +1 ,
);
$image->Annotate( text=>$cAnnotateText ,
font=> $cAnnotateFont ,
pointsize=> $cAnnotatePointsize ,
pen=> $AnnotateOutline ,
x=> $Xoffset +1 ,
y=> $Yoffset +0 ,
);
$image->Annotate( text=>$cAnnotateText ,
font=> $cAnnotateFont ,
pointsize=> $cAnnotatePointsize ,
pen=> $AnnotateOutline ,
x=> $Xoffset +1 ,
y=> $Yoffset -1 ,
);
$image->Annotate( text=>$cAnnotateText ,
font=> $cAnnotateFont ,
pointsize=> $cAnnotatePointsize ,
pen=> $AnnotateOutline ,
x=> $Xoffset ,
y=> $Yoffset -1 ,
);
# insert annotation on top of outline
$ErrMsg =
$image->Annotate( text=>$cAnnotateText ,
font=> $cAnnotateFont ,
pointsize=> $cAnnotatePointsize ,
pen=> $AnnotatePen ,
x=> $Xoffset ,
y=> $Yoffset ,
);
if ( $ErrMsg ) {
$tempString = "\t $ErrMsg : Image-Magick failed to annotate
$FileNameIn \n" ;
print DEBUG_LOG $tempString if $cDEBUG ;
return( $tempString );
} else {
print DEBUG_LOG "\t ...annotated \n" if $cDEBUG ;
$DidAnnotate = 'true' ;
}
}
# save the sized image
# ------
if ( $DidAnnotate or $DoSample ) {
$ErrMsg = $image->Write( filename=>$FileNameIn ,
quality=>$cImageQuality );
if ( $ErrMsg ) {
return( "$ErrMsg : Image-Magick failed to overwrite ".
"$FileNameIn with resampled image" );
} elsif ( $cDEBUG ) {
print DEBUG_LOG "\t ...saved \n"
}
}
# re-sample for thumbnail
# -----
$ErrMsg = $image->Scale( geometry=>"${cMaxThumbimgX}x${cMaxThumbimgY}"
);
if ($ErrMsg ) {
return( "$ErrMsg : Image-Magick failed to resample $FileNameIn to ".
"thumbnail ${cMaxThumimgX}x${cMaxThumimgY} " ) ;
} elsif ( $cDEBUG ) { print DEBUG_LOG "\t thumbnailed ok... \n" }
# figure out name and write thumbnail image
# -----
my $FileNameThum = $FileNameIn ;
$FileNameThum =~ s/(.*)\.(.+)$/$1/ ; # grab base filename and
extension
$FileNameThum = "$1_$cMaxThumbimgX.$2" ; # insert the thumb X to
filename
$ErrMsg = $image->Write( filename=>$FileNameThum ,
quality=>$cImageQuality );
if ( $ErrMsg ) {
return( "$ErrMsg : Image-Magick failed to write $FileNameThum
thumbnail image" ) ;
} elsif ( $cDEBUG ) { print DEBUG_LOG "\t ...saved thumbnail to
$FileNameThum \n" }
undef $image; # release object memory
print DEBUG_LOG scalar(localtime).
"finished SizeAndThumb for $FileNameIn and $FileNameThum \n" if
$cDEBUG;
# ------------------------------------------------------------------------------
return (0) ; # return success, no error message
}
1 ; # done.....