Rudesind

 view release on metacpan or  search on metacpan

lib/Rudesind/Image.pm  view on Meta::CPAN

package Rudesind::Image;

use strict;

use Rudesind::Captioned;

use Class::Roles does => 'Rudesind::Captioned';

use File::Basename ();
use File::Path ();
use File::Slurp ();
use Image::Magick;
use Image::Size ();
use Params::Validate qw( validate UNDEF SCALAR ARRAYREF );
use Path::Class ();

use Rudesind::Config;


sub new
{
    my $class = shift;
    my %p = validate( @_,
                      { file   => { type => SCALAR },
                        path   => { type => SCALAR },
                        config => { isa => 'Rudesind::Config' },
                      },
                    );

    # XXX - check if image module can handle this type

    my ( $w, $h ) = Image::Size::imgsize( $p{file} );

    return bless { %p,
                   dir => Path::Class::dir( File::Basename::dirname( $p{file} ) ),
                   height => $h,
                   width  => $w,
                 }, $class;
}

sub file   { $_[0]->{file} }
sub path   { $_[0]->{path} }
sub config { $_[0]->{config} }

sub uri    { $_[0]->{path} . '.html' }

sub height { $_[0]->{height} }
sub width  { $_[0]->{width} }

sub filename { File::Basename::basename( $_[0]->file ) }
sub title    { $_[0]->filename }

sub gallery
{
    Rudesind::Gallery->new( path   => File::Basename::dirname( $_[0]->path ),
                            config => $_[0]->config );
}

sub _transforms
{
    my $config = $_[0]->config;

    return
    { default   =>
      { max_width   => $config->image_page_max_width,
        max_height  => $config->image_page_max_height,
      },
      thumbnail =>
      { max_width   => $config->thumbnail_max_width,
        max_height  => $config->thumbnail_max_height
      },
      double    => '_double_size',

lib/Rudesind/Image.pm  view on Meta::CPAN

    my %transform = $self->_transform_params(@_);

    my $file = $self->file;

    my $image_dir = $self->config->image_dir;

    my $t = join '-', sort ( keys %transform, values %transform );
    my $transform_dir = Path::Class::dir( $self->config->image_cache_dir, $t );

    $file =~ s/\Q$image_dir\E/$transform_dir/;

    return $file;
}

sub _transform_params
{
    my $self = shift;
    my %p = validate( @_, { transforms => { type => SCALAR | ARRAYREF,
                                            default => [ 'default' ] },
                          },
                    );

    my %transform;
    foreach my $name ( ref $p{transforms} ? @{ $p{transforms} } : $p{transforms} )
    {
        my $t = $self->_transforms->{$name};

        %transform = ( %transform,
                       ref $t ? %$t : $self->$t()
                     );
    }

    return %transform;
}

sub _transform
{
    my $self = shift;
    my %p = validate( @_,
                      { max_width  => { type    => SCALAR,
                                        default => undef,
                                        depends => 'max_height',
                                      },
                        max_height => { type    => SCALAR,
                                        default => undef,
                                        depends => 'max_width',
                                      },
                        width      => { type    => SCALAR,
                                        default => $self->width,
                                      },
                        height     => { type    => SCALAR,
                                        default => $self->height,
                                      },
                        rotate     => { type    => SCALAR,
                                        default => 0,
                                      },
                        output_file => { type => SCALAR },
                      },
                    );

    my $img = Image::Magick->new;
    $img->Read( filename => $self->file );

    if ( $p{max_width} && $p{max_height} )
    {
        if ( $p{max_width}  < $img->Get('width')
             ||
             $p{max_height} < $img->Get('height')
           )
        {
            my $width_r  = $p{max_width}  / $img->get('width');
            my $height_r = $p{max_height} / $img->get('height');

            my $ratio;
            $ratio = $height_r < $width_r ? $height_r : $width_r;

            $img->Scale( width  => int( $img->get('width') * $ratio ),
                         height => int( $img->get('height') * $ratio ),
                       );
        }
    }
    elsif ( $p{height} != $self->height
            ||
            $p{width}  != $self->width
          )
    {
        $img->Scale( height => $p{height},
                     width  => $p{width},
                   );
    }

    if ( $p{rotate} )
    {
        $img->Rotate( degrees => $p{rotate} );
    }

    File::Path::mkpath( File::Basename::dirname( $p{output_file} ), 0, 0755 );

    my $q = $img->Get('quality');
    $img->Write( filename => $p{output_file},
                 ( defined $q ? ( quality  => $q ) : () ),
                 type     => 'Palette',
               );
}

sub _caption_file
{
    my $self = shift;

    return $self->{dir}->file( '.' . $self->filename . '.caption' );
}

{
    my $ext =
        ( join '|',
          map { "\Q.$_\E" }
          qw( gif jpg jpeg jpe png )
        );

    sub image_extension_re { qr/(?:$ext)$/i }
}



( run in 2.649 seconds using v1.01-cache-2.11-cpan-ceb78f64989 )