CGI-Uploader
view release on metacpan or search on metacpan
lib/CGI/Uploader/Transform/ImageMagick.pm view on Meta::CPAN
This function creates a copy of given image file and resizes the copy to the
provided width and height.
C<gen_thumb> can be called as object or class method. As a class method,
there there is no need to call C<new()> before calling this method.
L<Graphics::Magick> is used as the first choice image service module.
L<Image::Magick> is tried next.
Input:
filename - filename of source image
w - max width of thumbnail
h - max height of thumbnail
One or both of C<w> or C<h> is required.
Output:
- filename of generated tmp file for the thumbnail
- the initialized image generation object. (You generally shouldn't need this)
=cut
sub gen_thumb {
# If the first arg is an object, we have really work to do right now
my $first_arg = $_[0];
use Scalar::Util (qw/blessed/);
if ((blessed $first_arg) or (eval {$first_arg->can('gen_thumb')})) {
return _really_gen_thumb(@_);
}
# Otherwise, just generate a closure pass back a code ref for later use
else {
# require a single hashref as input
my ($args_href) = validate_pos(@_, { type => HASHREF });
return sub {
my $self = shift;
my $filename = shift;
_really_gen_thumb($self, {
filename => $filename,
%$args_href,
});
}
}
}
sub _really_gen_thumb {
my $self = shift || die "gen_thumb needs object";
my (%p,$orig_filename,$params);
# If we have the new hashref API
if (ref $_[0] eq 'HASH') {
%p = validate(@_,{
filename => { type => SCALAR },
w => { type => SCALAR | UNDEF, regex => qr/^\d*$/, optional => 1, },
h => { type => SCALAR | UNDEF, regex => qr/^\d*$/, optional => 1 },
});
$orig_filename = $p{filename};
}
# we have the old ugly style API
else {
($orig_filename, $params) = validate_pos(@_,1,{ type => ARRAYREF });
# validate handles a hash or hashref transparently
%p = validate(@$params,{
w => { type => SCALAR | UNDEF, regex => qr/^\d*$/, optional => 1, },
h => { type => SCALAR | UNDEF, regex => qr/^\d*$/, optional => 1 },
});
}
die "must supply 'w' or 'h'" unless (defined $p{w} or defined $p{h});
# Having both Graphics::Magick and Image::Magick loaded at the same time
# can cause very strange problems, so we take care to avoid that
# First see if we have already loaded Graphics::Magick or Image::Magick
# If so, just use whichever one is already loaded.
my $magick_module;
if (exists $INC{'Graphics/Magick.pm'}) {
$magick_module = 'Graphics::Magick';
}
elsif (exists $INC{'Image/Magick.pm'}) {
$magick_module = 'Image::Magick';
}
# If neither are already loaded, try loading either one.
elsif ( _load_magick_module('Graphics::Magick') ) {
$magick_module = 'Graphics::Magick';
}
elsif ( _load_magick_module('Image::Magick') ) {
$magick_module = 'Image::Magick';
}
else {
die "No graphics module found for image resizing. Install Graphics::Magick or Image::Magick: $@ "
}
my ($thumb_tmp_fh, $thumb_tmp_filename) = tempfile('CGIuploaderXXXXX', UNLINK => 1, DIR => $self->{'temp_dir'});
binmode($thumb_tmp_fh);
my $img = $magick_module->new();
my $err;
eval {
$err = $img->Read(filename=>$orig_filename);
die "Error while reading $orig_filename: $err" if $err;
my ($target_w,$target_h) = _calc_target_size($img,$p{w},$p{h});
$err = $img->Resize($target_w.'x'.$target_h);
die "Error while resizing $orig_filename: $err" if $err;
$err = $img->Write($thumb_tmp_filename);
die "Error while writing $orig_filename: $err" if $err;
};
if ($@) {
warn $@;
my $code;
# codes > 400 are fatal
die $err if ((($code) = $err =~ /(\d+)/) and ($code > 400));
}
assert ($thumb_tmp_filename, 'thumbnail tmp file created');
return wantarray ? ($thumb_tmp_filename, $img ) : $thumb_tmp_filename;
}
( run in 1.971 second using v1.01-cache-2.11-cpan-39bf76dae61 )