# Image::Size - phpMan

## NAME
    [Image::Size] - read the dimensions of an image in several popular formats

## SYNOPSIS
        use [Image::Size];
        # Get the size of globe.gif
        ($globe_x, $globe_y) = imgsize("globe.gif");
        # Assume X=60 and Y=40 for remaining examples

        use [Image::Size] 'html_imgsize';
        # Get the size as 'width="X" height="Y"' for HTML generation
        $size = html_imgsize("globe.gif");
        # $size == 'width="60" height="40"'

        use [Image::Size] 'attr_imgsize';
        # Get the size as a list passable to routines in CGI.pm
        @attrs = attr_imgsize("globe.gif");
        # @attrs == ('-width', 60, '-height', 40)

        use [Image::Size];
        # Get the size of an in-memory buffer
        ($buf_x, $buf_y) = imgsize(\$buf);
        # Assuming that $buf was the data, imgsize() needed a
        $ reference to a scalar

## DESCRIPTION
    The [Image::Size] library is based upon the "wwwis" script written by Alex
    Knowles *(<alex@ed.ac.uk>)*, a tool to examine HTML and add 'width' and
    'height' parameters to image tags. The sizes are cached internally based
    on file name, so multiple calls on the same file name (such as images
    used in bulleted lists, for example) do not result in repeated
    computations.

SUBROUTINES/METHODS
    [Image::Size] provides three interfaces for possible import:

    imgsize(*stream*)
        Returns a three-item list of the X and Y dimensions (width and
        height, in that order) and image type of *stream*. Errors are noted
        by undefined (undef) values for the first two elements, and an error
        string in the third. The third element can be (and usually is)
        ignored, but is useful when sizing data whose type is unknown.

    html_imgsize(*stream*)
        Returns the width and height (X and Y) of *stream* pre-formatted as
        a single string 'width="X" height="Y"' suitable for addition into
        generated HTML IMG tags. If the underlying call to "imgsize" fails,
        undef is returned. The format returned is dually suited to both HTML
        and XHTML.

    attr_imgsize(*stream*)
        Returns the width and height of *stream* as part of a 4-element list
        useful for routines that use hash tables for the manipulation of
        named parameters, such as the Tk or CGI libraries. A typical return
        value looks like "("-width", X, "-height", Y)". If the underlying
        call to "imgsize" fails, undef is returned.

    By default, only "imgsize()" is exported. Any one or combination of the
    three may be explicitly imported, or all three may be with the tag :all.

  Input Types
    The sort of data passed as *stream* can be one of three forms:

    string
        If an ordinary scalar (string) is passed, it is assumed to be a file
        name (either absolute or relative to the current working directory
        of the process) and is searched for and opened (if found) as the
        source of data. Possible error messages (see DIAGNOSTICS below) may
        include file-access problems.

    scalar reference
        If the passed-in stream is a scalar reference, it is interpreted as
        pointing to an in-memory buffer containing the image data.

                # Assume that &read_data gets data somewhere (WWW, etc.)
                $img = &read_data;
                ($x, $y, $id) = imgsize(\$img);
                # $x and $y are dimensions, $id is the type of the image

    Open file handle
        The third option is to pass in an open filehandle (such as an object
        of the "[IO::File]" class, for example) that has already been
        associated with the target image file. The file pointer will
        necessarily move, but will be restored to its original position
        before subroutine end.

                # $fh was passed in, is [IO::File] reference:
                ($x, $y, $id) = imgsize($fh);
                # Same as calling with filename, but more abstract.

  Recognized Formats
    [Image::Size] natively understands and sizes data in the following
    formats:

    GIF
    JPG
    XBM
    XPM
    PPM family (PPM/PGM/PBM)
    XV thumbnails
    PNG
    MNG
    TIF
    BMP
    PSD (Adobe PhotoShop)
    SWF (ShockWave/Flash)
    CWS (FlashMX, compressed SWF, Flash 6)
    PCD (Kodak PhotoCD, see notes below)
    EMF (Windows Enhanced Metafile Format)
    WEBP
    ICO (Microsoft icon format)
    CUR (Microsoft mouse cursor format)

    Additionally, if the [Image::Magick] module is present, the file types
    supported by it are also supported by [Image::Size]. See also "CAVEATS".

    When using the "imgsize" interface, there is a third, unused value
    returned if the programmer wishes to save and examine it. This value is
    the identity of the data type, expressed as a 2-3 letter abbreviation as
    listed above. This is useful when operating on open file handles or
    in-memory data, where the type is as unknown as the size. The two
    support routines ignore this third return value, so those wishing to use
    it must use the base "imgsize" routine.

    Note that when the [Image::Magick] fallback is used (for all non-natively
    supported files), the data type identity comes directly from the
    'format' parameter reported by [Image::Magick], so it may not meet the 2-3
    letter abbreviation format. For example, a WBMP file might be reported
    as 'Wireless Bitmap (level 0) image' in this case.

  Information Caching and $NO_CACHE
    When a filename is passed to any of the sizing routines, the default
    behavior of the library is to cache the resulting information. The
    modification-time of the file is also recorded, to determine whether the
    cache should be purged and updated. This was originally added due to the
    fact that a number of CGI applications were using this library to
    generate attributes for pages that often used the same graphical element
    many times over.

    However, the caching can lead to problems when the files are generated
    dynamically, at a rate that exceeds the resolution of the
    modification-time value on the filesystem. Thus, the
    optionally-importable control variable $NO_CACHE has been introduced. If
    this value is anything that evaluates to a non-false value (be that the
    value 1, any non-null string, etc.) then the cacheing is disabled until
    such time as the program re-enables it by setting the value to false.

    The parameter $NO_CACHE may be imported as with the imgsize routine, and
    is also imported when using the import tag ":all". If the programmer
    chooses not to import it, it is still accessible by the fully-qualified
    package name, $[Image::Size::NO_CACHE].

  Sharing the Cache Between Processes
    If you are using [Image::Size] in a multi-thread or multi-process
    environment, you may wish to enable sharing of the cached information
    between the processes (or threads). [Image::Size] does not natively
    provide any facility for this, as it would add to the list of
    dependencies.

    To make it possible for users to do this themselves, the %CACHE
    hash-table that [Image::Size] uses internally for storage may be imported
    in the use statement. The user may then make use of packages such as
    [IPC::MMA] ([IPC::MMA]) that can "tie" a hash to a shared-memory segment:

        use [Image::Size] qw(imgsize %CACHE);
        use [IPC::MMA];

        ...

        tie %CACHE, '[IPC::MM::Hash]', $mmHash; # $mmHash via mm_make_hash
        # Now, forked processes will share any changes made to the cache

  Sizing PhotoCD Images
    With version 2.95, support for the Kodak PhotoCD image format is
    included. However, these image files are not quite like the others. One
    file is the source of the image in any of a range of pre-set resolutions
    (all with the same aspect ratio). Supporting this here is tricky, since
    there is nothing inherent in the file to limit it to a specific
    resolution.

    The library addresses this by using a scale mapping, and requiring the
    user (you) to specify which scale is preferred for return. Like the
    $NO_CACHE setting described earlier, this is an importable scalar
    variable that may be used within the application that uses [Image::Size].
    This parameter is called $PCD_SCALE, and is imported by the same name.
    It, too, is also imported when using the tag ":all" or may be referenced
    as $[Image::Size::PCD_SCALE].

    The parameter should be set to one of the following values:

            base/16
            base/4
            base
            base4
            base16
            base64

    Note that not all PhotoCD disks will have included the "base64"
    resolution. The actual resolutions are not listed here, as they are
    constant and can be found in any documentation on the PCD format. The
    value of $PCD_SCALE is treated in a case-insensitive manner, so "base"
    is the same as "Base" or "BaSe". The default scale is set to "base".

    Also note that the library makes no effort to read enough of the PCD
    file to verify that the requested resolution is available. The point of
    this library is to read as little as necessary so as to operate
    efficiently. Thus, the only real difference to be found is in whether
    the orientation of the image is portrait or landscape. That is in fact
    all that the library extracts from the image file.

  Controlling Behavior with GIF Images
    GIF images present a sort of unusual situation when it comes to reading
    size. Because GIFs can be a series of sub-images to be played as an
    animated sequence, what part does the user want to get the size for?

    When dealing with GIF files, the user may control the behavior by
    setting the global value $[Image::Size::GIF_BEHAVIOR]. Like the PCD
    setting, this may be imported when loading the library. Three values are
    recognized by the GIF-handling code:

    0   This is the default value. When this value is chosen, the returned
        dimensions are those of the "screen". The "screen" is the display
        area that the GIF declares in the first data block of the file. No
        sub-images will be greater than this in size; if they are, the
        specification dictates that they be cropped to fit within the box.

        This is also the fastest method for sizing the GIF, as it reads the
        least amount of data from the image stream.

    1   If this value is set, then the size of the first sub-image within
        the GIF is returned. For plain (non-animated) GIF files, this would
        be the same as the screen (though it doesn't have to be,
        strictly-speaking).

        When the first image descriptor block is read, the code immediately
        returns, making this only slightly-less efficient than the previous
        setting.

    2   If this value is chosen, then the code loops through all the
        sub-images of the animated GIF, and returns the dimensions of the
        largest of them.

        This option requires that the full GIF image be read, in order to
        ensure that the largest is found.

    Any value outside this range will produce an error in the GIF code
    before any image data is read.

    The value of dimensions other than the view-port ("screen") is dubious.
    However, some users have asked for that functionality.

[Image::Size] AND WEBSERVERS
    There are a few approaches to getting the most out of [Image::Size] in a
    multi-process webserver environment. The two most common are pre-caching
    and using shared memory. These examples are focused on Apache, but
    should be adaptable to other server approaches as well.

  Pre-Caching Image Data
    One approach is to include code in an Apache start-up script that reads
    the information on all images ahead of time. A script loaded via
    "PerlRequire", for example, becomes part of the server memory before
    child processes are created. When the children are created, they come
    into existence with a pre-primed cache already available.

    The shortcoming of this approach is that you have to plan ahead of time
    for which image files you need to cache. Also, if the list is
    long-enough it can slow server start-up time.

    The advantage is that it keeps the information centralized in one place
    and thus easier to manage and maintain. It also requires no additional
    CPAN modules.

  Shared Memory Caching
    Another approach is to introduce a shared memory segment that the
    individual processes all have access to. This can be done with any of a
    variety of shared memory modules on CPAN.

    Probably the easiest way to do this is to use one of the packages that
    allow the tying of a hash to a shared memory segment. You can use this
    in combination with importing the hash table variable that is used by
    [Image::Size] for the cache, or you can refer to it explicitly by full
    package name:

        use [IPC::Shareable];
        use [Image::Size];

        tie %[Image::Size::CACHE], '[IPC::Shareable]', 'size', { create => 1 };

    That example uses [IPC::Shareable] (see [IPC::Shareable]) and uses the
    option to the "tie" command that tells [IPC::Shareable] to create the
    segment. Once the initial server process starts to create children, they
    will all share the tied handle to the memory segment.

    Another package that provides this capability is [IPC::MMA] (see
    [IPC::MMA]), which provides shared memory management via the *mm* library
    from Ralf Engelschall (details available in the documentation for
    [IPC::MMA]):

        use [IPC::MMA];
        use [Image::Size] qw(%CACHE);

        my $mm = mm_create(65536, '/tmp/test_lockfile');
        my $mmHash = mm_make_hash($mm);
        tie %CACHE, '[IPC::MM::Hash]', $mmHash;

    As before, this is done in the start-up phase of the webserver. As the
    child processes are created, they inherit the pointer to the existing
    shared segment.

## MORE EXAMPLES
    The attr_imgsize interface is also well-suited to use with the Tk
    extension:

        $image = $widget->Photo(-file => $img_path, attr_imgsize($img_path));

    Since the "[Tk::Image]" classes use dashed option names as "CGI" does, no
    further translation is needed.

    This package is also well-suited for use within an Apache web server
    context. File sizes are cached upon read (with a check against the
    modified time of the file, in case of changes), a useful feature for a
    mod_perl environment in which a child process endures beyond the
    lifetime of a single request. Other aspects of the mod_perl environment
    cooperate nicely with this module, such as the ability to use a
    sub-request to fetch the full pathname for a file within the server
    space. This complements the HTML generation capabilities of the CGI
    module, in which "[CGI::img]" wants a URL but "attr_imgsize" needs a file
    path:

        # Assume $Q is an object of class CGI, $r is an Apache request object.
        # $imgpath is a URL for something like "/img/redball.gif".
        $r->print($Q->img({ -src => $imgpath,
                            attr_imgsize($r->lookup_uri($imgpath)->filename) }));

    The advantage here, besides not having to hard-code the server document
    root, is that Apache passes the sub-request through the usual request
    lifecycle, including any stages that would re-write the URL or otherwise
    modify it.

## DIAGNOSTICS
    The base routine, "imgsize", returns undef as the first value in its
    list when an error has occurred. The third element contains a
    descriptive error message.

    The other two routines simply return undef in the case of error.

## CAVEATS
    Caching of size data can only be done on inputs that are file names.
    Open file handles and scalar references cannot be reliably transformed
    into a unique key for the table of cache data. Buffers could be cached
    using the MD5 module, and perhaps in the future I will make that an
    option. I do not, however, wish to lengthen the dependency list by
    another item at this time.

    As [Image::Magick] operates on file names, not handles, the use of it is
    restricted to cases where the input to "imgsize" is provided as file
    name.

## SEE ALSO
    [Image::Magick] and [Image::Info] Perl modules at CPAN. The [Graphics::Magick]
    Perl API at <<http://www.graphicsmagick.org/perl.html>>.

## CONTRIBUTORS
    Perl module interface by Randy J. Ray *(<rjray@blackperl.com>)*, original
    image-sizing code by Alex Knowles *(<alex@ed.ac.uk>)* and Andrew Tong
    *(<werdna@ugcs.caltech.edu>)*, used with their joint permission.

    Some bug fixes submitted by Bernd Leibing
    *(<bernd.leibing@rz.uni-ulm.de>)*. PPM/PGM/PBM sizing code contributed by
    Carsten Dominik *(<dominik@strw.LeidenUniv.nl>)*. Tom Metro
    *(<tmetro@vl.com>)* re-wrote the JPG and PNG code, and also provided a PNG
    image for the test suite. Dan Klein *(<dvk@lonewolf.com>)* contributed a
    re-write of the GIF code. Cloyce Spradling *(<cloyce@headgear.org>)*
    contributed TIFF sizing code and test images. Aldo Calpini
    *(<a.calpini@romagiubileo.it>)* suggested support of BMP images (which I
    *really* should have already thought of :-) and provided code to work
    with. A patch to allow html_imgsize to produce valid output for XHTML,
    as well as some documentation fixes was provided by Charles Levert
    *(<charles@comm.polymtl.ca>)*. The ShockWave/Flash support was provided by
    Dmitry Dorofeev *(<dima@yasp.com>)*. Though I neglected to take note of
    who supplied the PSD (PhotoShop) code, a bug was identified by Alex
    Weslowski <<aweslowski@rpinteractive.com>>, who also provided a test
    image. PCD support was adapted from a script made available by Phil
    Greenspun, as guided to my attention by Matt Mueller
    *<mueller@wetafx.co.nz>*. A thorough read of the documentation and source
    by Philip Newton *<Philip.Newton@datenrevision.de>* found several typos
    and a small buglet. Ville Skytt� *(<ville.skytta@iki.fi>)* provided the
    MNG and the [Image::Magick] fallback code. Craig MacKenna
    *(<mackenna@animalhead.com>)* suggested making the cache available so that
    it could be used with shared memory, and helped test my change before
    release.

## BUGS
    Please report any bugs or feature requests to "bug-image-size at
    rt.cpan.org", or through the web interface at
    <<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Image-Size>>. I will be
    notified, and then you'll automatically be notified of progress on your
    bug as I make changes.

## SUPPORT
    *   RT: CPAN's request tracker

        <<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Image-Size>>

    *   AnnoCPAN: Annotated CPAN documentation

        <<http://annocpan.org/dist/Image-Size>>

    *   CPAN Ratings

        <<http://cpanratings.perl.org/d/Image-Size>>

    *   Search CPAN

        <<http://search.cpan.org/dist/Image-Size>>

    *   Project page on GitHub

        <<http://github.com/rjray/image-size>>

## REPOSITORY
    <<https://github.com/rjray/image-size>>

## LICENSE AND COPYRIGHT
    This file and the code within are copyright (c) 1996-2009 by Randy J.
    Ray.

    Copying and distribution are permitted under the terms of the Artistic
    License 2.0
    (<<http://www.opensource.org/licenses/artistic-license-2.0.php>>) or the
    GNU LGPL 2.1 (<<http://www.opensource.org/licenses/lgpl-2.1.php>>).

## AUTHOR
    Randy J. Ray "<<rjray@blackperl.com>>"

