#! /usr/bin/perl -w use strict; use warnings; use diagnostics; use CGI; use CGI::Carp qw(fatalsToBrowser); # only for testing - remove for production!!!!! use GD; # variables: my $q = CGI->new(); my ($srcImage, $tgtImage); # source and target image object variables my ($srcext, $srcname); my $tgtfile; my ($maxw, $maxh) = (120, 120); # maximum width and height of new thumbnail my ($neww, $newh); # will be the actual width and height of new thumbnail my ($width, $height); my $output; my $dir = '/home/mysite/private/upload'; # base directory for uploads my $id = 1; # hardcode one example for now, to test my $file = 'Iceberg.jpg'; # hardcode one example for now, to test die "Bad file parameter!" if $file =~ m/^[^a-zA-Z0-9 ._-]$/i; $output .= $q->p( "Preparing to make thumbnail of $file..." ); my $srcfile = "$dir/$id/$file"; # ensure user has a thumbnail directory: unless ( -e "$dir/$id/thumb" && -d "$dir/$id/thumb" ) { $output .= $q->p( "Creating /thumb directory for thumbnails..." ); mkdir "$dir/$id/thumb" or die "Couldn't make thumbnail directory $!"; } # some filename parsing: $file =~ m/([^.]+)\.?(\w*)$/; ($srcname, $srcext) = ($1, $2); # file extension is last part of name # open a filehandle for the source image file: open (SRC, '<', $srcfile) or die "Sorry, couldn't open $srcfile: $!"; binmode SRC; # create a new image object based on the source file: if ( $srcext =~ m/jpe?g/i ) { $srcImage = newFromJpeg GD::Image(\*SRC) or die "Problem reading $srcfile: $!"; } elsif ( $srcext =~ m/gif/i ) { $srcImage = new GD::Image(\*SRC) or die "Problem reading $srcfile: $!"; } else { $output .= $q->p( "Can only convert jpg and gif format" ); display($output); exit; } close SRC; # determine width and height of source image: ($width,$height) = $srcImage->getBounds(); if ($width <= $maxw && $height <= $maxh) { # no work to be done! display( $q->p("File is already thumbnail-sized!!!") ); exit; } # determine limiting scale factor: my $wf = $width / $maxw; my $hf = $height / $maxh; my $scale = $wf > $hf ? $wf : $hf; # determine our new target image's scaled width and height: $neww = round($width / $scale); $newh = round($height / $scale); $output .= $q->p( "w factor = $wf, h factor = $hf, we'll scale by a factor of $scale" ); $output .= $q->p( "new image width x height will be $neww x $newh" ); # create new target image: $tgtImage = new GD::Image($neww, $newh); # copy the source image to the new image in scale: eval { $tgtImage->copyResized($srcImage, # source image - a GD::Image object 0, # target x co-ordinate 0, # target y co-ordinate 0, # source x co-ordinate 0, # source y co-ordinate $neww, # target width $newh, # target height $width, # source width $height # source height )}; die $@ if $@; #was: or die "Attempt to copy source image $file failed!"; # create a jpeg datastream representation of the new thumbnail image: my $jpegdata = $tgtImage->jpeg() or die "Couldn't create jpeg thumbnail from source!"; $output .= $q->p( "jpeg data stream created successfully" ); # write data to new file: $tgtfile = "$dir/$id/thumb/$srcname.jpg";# name of new thumbnail-sized image open (OUT, '>', $tgtfile) or die "Sorry, couldn't open target file for writing: $!"; binmode OUT; print OUT $jpegdata; close OUT; $output .= $q->p( "Seem to be successful in creating a thumbnail version of $file!" ); display($output); exit; sub display { # in production there is a much better way of doing this my $stuff = shift; print $q->header(), $q->html($stuff); return; } sub round { my($number) = shift; return int($number + .5); }