NAME
    Plack::Middleware::Image::Scale - Resize jpeg and png images on the fly

VERSION
    version 0.008

SYNOPSIS
        ## example1.psgi
    
        builder {
            enable 'ConditionalGET';
            enable 'Image::Scale';
            enable 'Static', path => qr{^/images/};
            $app;
        };

    A request to /images/foo_40x40.png will use images/foo.(png|jpg|gif) as
    original, scale it to 40x40 px size and convert to PNG format.

        ## example2.psgi

        my $thumber = builder {
            enable 'ConditionalGET';
            enable 'Image::Scale',
                width => 200, height => 100,
                flags => { fill => 'ff00ff' };
            Plack::App::File->new( root => 'images' );
        };

        builder {
            mount '/thumbs' => $thumber;
            mount '/' => $app;
        };

    A request to /thumbs/foo.png will use images/foo.(png|jpg|gif) as
    original, scale it small enough to fit 200x100 px size, fill extra
    borders (top/down or left/right, depending on the original image aspect
    ratio) with cyan background, and convert to PNG format. Also clipping is
    available, see "CONFIGURATION".

        ## see example4.psgi

        my %imagesize = Config::General->new('imagesize.conf')->getall;
    
        # ...
    
        enable 'Image::Scale', size => \%imagesize;

    A request to /images/foo_medium.png will use images/foo.(png|jpg|gif) as
    original. The size and flags are taken from the configuration file as
    parsed by Config::General.

        ## imagesize.conf

        <medium>
            width   200
            height  100
            crop
        </medium>
        <big>
            width   300
            height  100
            crop
        </big>
        <thumbred>
            width   50
            height  100
            fill    ff0000
        </thumbred>

    For more examples, browse into directory <eg> inside the distribution
    directory for this version.

DESCRIPTION
    Scale and convert images to the requested format on the fly. By default
    the size and other scaling parameters are extracted from the request
    URI. Scaling is done with Image::Scale.

    The original image is not modified or even accessed directly by this
    module. The converted image is not cached, but the request can be
    validated (If-Modified-Since) against original image without doing the
    image processing. This middleware should be used together a cache proxy,
    that caches the converted images for all clients, and implements content
    validation.

    The response headers (like Last-Modified or ETag) are from the original
    image, but body is replaced with a PSGI content filter to do the image
    processing. The original image is fetched from next middleware layer or
    application with a normal PSGI request. You can use
    Plack::Middleware::Static, or Catalyst::Plugin::Static::Simple for
    example.

    See "CONFIGURATION" for various size/format specifications that can be
    used in the request URI, and "ATTRIBUTES" for common configuration
    options that you can use when constructing the middleware.

ATTRIBUTES
  path
    Must be a RegexpRef, CodeRef, Str or Undef.

    The PATH_INFO is compared against this value to evaluate if the request
    should be processed. Undef (the default) will match always. "PATH_INFO"
    is topicalized by settings it to $_, and it may be rewritten during
    "CodeRef" matching. Rewriting can be used to relocate image paths, much
    like "path" parameter for Plack::Middleware::Static.

    If path matches, next it will be compared against "name". If path
    doesn't match, the request will be delegated to the next middleware
    layer or application.

  match
    Must be a RegexpRef, or CodeRef.

    The PATH_INFO, possibly rewritten during "path" matching, is compared
    against this value to extract "name", "size" and "ext". The default
    value is:

        qr{^(.+)(?:_(.+?))?(?:\.(jpe?g|png|image))$}

    The expression is evaluated in array context and may return three
    elements: "name", "size" and "ext". Returning an empty array means no
    match. Non-matching requests are delegated to the next middleware layer
    or application.

    If the path matches, the original image is fetched from
    "name"."orig_ext", scaled with parameters extracted from "size" and
    converted to the content type defined by "ext". See also "any_ext".

  size
    Must be a RegexpRef, CodeRef, HashRef, Undef.

    The "size" extracted by "match" is compared against this value to
    evaluate if the request should be processed, and to map it into width,
    height and flags for image processing. Undef will match always and use
    default width, height and flags as defined by the "ATTRIBUTES". The
    default value is:

        qr{^(\d+)?x(\d+)?(?:-(.+))?$}

    The expression is evaluated in array context and may return three
    elements; "width", "height" and "flags". Returning an empty array means
    no match. Non-matching requests are delegated to the next middleware
    layer or application.

    Optionally a hash reference can be returned. Keys "width", "height", and
    any remaining keys as an hash reference, will be unrolled from the hash
    reference.

  any_ext
    If defined and request "ext" is equal to this, the content type of the
    original image is used in the output. This means that the image format
    of the original image is preserved. Default is "image".

  orig_ext
    ArrayRef of possible original image formats. See "fetch_orig".

  memory_limit
    Memory limit for the image scaling in bytes, as defined in Image::Scale.

  jpeg_quality
    JPEG quality, as defined in Image::Scale.

  width
    Use this to set and override image width.

  height
    Use this to set and override image height.

  flags
    Use this to set and override image processing flags.

METHODS
  fetch_orig
    Call parameters: PSGI request HashRef $env, Str $basename. Return value:
    PSGI response ArrayRef $res.

    The original image is fetched from the next layer or application. All
    possible extensions defined in "orig_ext" are tried in order, to search
    for the original image. All other responses except a straight 404 (as
    returned by Plack::Middleware::Static for example) are considered
    matches.

  body_scaler
    Call parameters: @args. Return value: PSGI content filter CodeRef $cb.

    Create the content filter callback and return a CodeRef to it. The
    filter will buffer the data and call "image_scale" with parameters @args
    when EOF is received, and finally return the converted data.

  image_scale
    Call parameters: ScalarRef $buffer, String $ct, Int $width, Int $height,
    HashRef|Str $flags. Return value: $imagedata

    Read image from $buffer, scale it to $width x $height and return as
    content-type $ct. Optional $flags to specify image processing options
    like background fills or cropping.

CONFIGURATION
    The default match pattern for URI is
    "*...*_*width*x*height*-*flags*.*ext*".

    If URI doesn't match, the request is passed through. Any number of flags
    can be specified, separated with "-". Flags can be boolean (exists or
    doesn't exist), or have a numerical value. Flag name and value are
    separated with a zero-width word to number boundary. For example "z20"
    specifies flag "z" with value 20.

  width
    Width of the output image. If not defined, it can be anything (to
    preserve the image aspect ratio).

  height
    Height of the output image. If not defined, it can be anything (to
    preserve the image aspect ratio).

  flags: fill
    Image aspect ratio is preserved by scaling the image to fit within the
    specified size. This means scaling to the smaller or the two possible
    sizes that preserve aspect ratio. Extra borders of background color are
    added to fill the requested image size exactly.

        /images/foo_400x200-fill.png

    If fill has a value, it specifies the background color to use. Undefined
    color with png output means transparent background.

  flags: crop
    Image aspect ratio is preserved by scaling and cropping from middle of
    the image. This means scaling to the bigger of the two possible sizes
    that preserve the aspect ratio, and then cropping to the exact size.

  flags: fit
    Image aspect ratio is preserved by scaling the image to the smaller of
    the two possible sizes. This means that the resulting picture may have
    one dimension smaller than specified, but cropping or filling is
    avoided.

    See documentation in distribution directory "doc" for a visual
    explanation.

  flags: z
    Zoom the original image N percent bigger. For example "z20" to zoom 20%.
    Zooming applies only to explicitly defined width and/or height, and it
    does not change the crop size.

        /images/foo_40x-z20.png

CAVEATS
    The cropping requires Imager. This is a run-time dependency, and
    fallback is not to crop the image to the expected size.

SEE ALSO
    Image::Scale

    Imager

    Plack::App::ImageMagick

AUTHOR
    Panu Ervamaa <pnu@cpan.org>

COPYRIGHT AND LICENSE
    This software is copyright (c) 2011 by Panu Ervamaa.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

