Plack-Middleware-Image-Scale

 view release on metacpan or  search on metacpan

lib/Plack/Middleware/Image/Scale.pm  view on Meta::CPAN

    my ($self,$env,$basename) = @_;

    for my $ext ( @{$self->orig_ext} ) {
        local $env->{PATH_INFO} = "$basename.$ext";
        my $r = $self->app->($env);
        return $r unless ref $r eq 'ARRAY' and $r->[0] == 404;
    }
    return;
}


sub body_scaler {
    my $self = shift;
    my @args = @_;

    my $buffer = q{};
    my $filter_cb = sub {
        my $chunk = shift;

        ## Buffer until we get EOF
        if ( defined $chunk ) {
            $buffer .= $chunk;
            return q{}; #empty
        }

        ## Return EOF when done
        return if not defined $buffer;

        ## Process the buffer
        my $img = $buffer ? $self->image_scale(\$buffer,@args) : '';
        undef $buffer;
        return $img;
    };

    return $filter_cb;
}


sub image_scale {
    my ($self, $bufref, $ct, $orig_ct, $width, $height, $flags) = @_;

    ## $flags can be a HashRef, or it's parsed as a string
    my %flag = 'HASH' eq ref $flags ? %{ $flags } :
    map { (split /(?<=\w)(?=\d)/, $_, 2)[0,1]; } split '-', $flags || '';

    $width  = $self->width      if defined $self->width;
    $height = $self->height     if defined $self->height;
    %flag   = %{ $self->flags } if defined $self->flags;

    my $owidth  = $width;
    my $oheight = $height;

    if ( defined $flag{z} and $flag{z} > 0 ) {
        $width  *= 1 + $flag{z} / 100 if $width;
        $height *= 1 + $flag{z} / 100 if $height;
    }

    my $output;
    if (defined $orig_ct and $orig_ct eq 'application/pdf') {
        try {
            Class::Load::load_class('Image::Magick::Thumbnail::PDF');
            Class::Load::load_class('File::Temp');
            my $in = File::Temp->new( SUFFIX => '.pdf' );
            my $out = File::Temp->new( SUFFIX => '.png' );
            $in->write( $$bufref ); $in->close;
            Image::Magick::Thumbnail::PDF::create_thumbnail(
                $in->filename, $out->filename, $flag{p}||1, {
                    frame => 0, normalize => 0,
                    restriction => max($width, $height),
                }
            );
            my $pdfdata;
            $out->seek( 0, 0 );
            $out->read( $pdfdata, 9999999 );
            $bufref = \$pdfdata;
        } catch {
            carp $_;
            $output = $$bufref;
        };
    }
    try {
        my $img = Image::Scale->new($bufref)
            or die 'Invalid data / image format not recognized';

        if ( exists $flag{crop} and defined $width and defined $height ) {
            my $ratio = $img->width / $img->height;
            $width  = max $width , $height * $ratio;
            $height = max $height, $width / $ratio;
        } elsif ( exists $flag{fit} and defined $width and defined $height ) {
            my $ratio = $img->width / $img->height;
            $width  = min $width , $height * $ratio;
            $height = min $height, $width / $ratio;
        }

        unless ( defined $width or defined $height ) {
            ## We want to keep the size, but Image::Scale
            ## doesn't return data unless we call resize.
            $width = $img->width; $height = $img->height;
        }
        $img->resize({
            defined $width  ? (width  => $width)  : (),
            defined $height ? (height => $height) : (),
            exists  $flag{fill} ? (keep_aspect => 1) : (),
            defined $flag{fill} ? (bgcolor => hex $flag{fill}) : (),
            defined $self->memory_limit ?
                (memory_limit => $self->memory_limit) : (),
        });

        $output = $ct eq 'image/jpeg' ? $img->as_jpeg($self->jpeg_quality || ()) :
                  $ct eq 'image/png'  ? $img->as_png :
                  die "Conversion to '$ct' is not implemented";
    } catch {
        carp $_;
        $output = $$bufref;
    };

    if ( defined $owidth  and $width  > $owidth or
         defined $oheight and $height > $oheight ) {
        try {
            Class::Load::load_class('Imager');
            my $img = Imager->new;
            $img->read( data => $output ) || die;
            my $crop = $img->crop(
                defined $owidth  ? (width  => $owidth)  : (),
                defined $oheight ? (height => $oheight) : (),
            );



( run in 1.325 second using v1.01-cache-2.11-cpan-39bf76dae61 )