{
    "content": [
        {
            "type": "text",
            "text": "# Image::Size (perldoc)\n\n## NAME\n\nImage::Size - read the dimensions of an image in several popular formats\n\n## SYNOPSIS\n\nuse Image::Size;\n# Get the size of globe.gif\n($globex, $globey) = imgsize(\"globe.gif\");\n# Assume X=60 and Y=40 for remaining examples\nuse Image::Size 'htmlimgsize';\n# Get the size as 'width=\"X\" height=\"Y\"' for HTML generation\n$size = htmlimgsize(\"globe.gif\");\n# $size == 'width=\"60\" height=\"40\"'\nuse Image::Size 'attrimgsize';\n# Get the size as a list passable to routines in CGI.pm\n@attrs = attrimgsize(\"globe.gif\");\n# @attrs == ('-width', 60, '-height', 40)\nuse Image::Size;\n# Get the size of an in-memory buffer\n($bufx, $bufy) = imgsize(\\$buf);\n# Assuming that $buf was the data, imgsize() needed a\n$ reference to a scalar\n\n## DESCRIPTION\n\nThe Image::Size library is based upon the \"wwwis\" script written by Alex Knowles\n*(alex@ed.ac.uk)*, a tool to examine HTML and add 'width' and 'height' parameters to image tags.\nThe sizes are cached internally based on file name, so multiple calls on the same file name\n(such as images used in bulleted lists, for example) do not result in repeated computations.\n\n## Sections\n\n- **NAME**\n- **SYNOPSIS**\n- **DESCRIPTION**\n- **SUBROUTINES/METHODS** (8 subsections)\n- **Image::Size AND WEBSERVERS** (2 subsections)\n- **MORE EXAMPLES**\n- **DIAGNOSTICS**\n- **CAVEATS**\n- **SEE ALSO**\n- **CONTRIBUTORS**\n- **BUGS**\n- **SUPPORT**\n- **REPOSITORY**\n- **LICENSE AND COPYRIGHT**\n- **AUTHOR**\n\nUse structuredContent.sections for detailed options, examples, and full documentation.\n"
        }
    ],
    "structuredContent": {
        "command": "Image::Size",
        "section": "",
        "mode": "perldoc",
        "summary": "Image::Size - read the dimensions of an image in several popular formats",
        "synopsis": "use Image::Size;\n# Get the size of globe.gif\n($globex, $globey) = imgsize(\"globe.gif\");\n# Assume X=60 and Y=40 for remaining examples\nuse Image::Size 'htmlimgsize';\n# Get the size as 'width=\"X\" height=\"Y\"' for HTML generation\n$size = htmlimgsize(\"globe.gif\");\n# $size == 'width=\"60\" height=\"40\"'\nuse Image::Size 'attrimgsize';\n# Get the size as a list passable to routines in CGI.pm\n@attrs = attrimgsize(\"globe.gif\");\n# @attrs == ('-width', 60, '-height', 40)\nuse Image::Size;\n# Get the size of an in-memory buffer\n($bufx, $bufy) = imgsize(\\$buf);\n# Assuming that $buf was the data, imgsize() needed a\n$ reference to a scalar",
        "tldr_summary": null,
        "tldr_examples": [],
        "tldr_source": null,
        "flags": [],
        "examples": [],
        "see_also": [],
        "section_outline": [
            {
                "name": "NAME",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "SYNOPSIS",
                "lines": 21,
                "subsections": []
            },
            {
                "name": "DESCRIPTION",
                "lines": 5,
                "subsections": []
            },
            {
                "name": "SUBROUTINES/METHODS",
                "lines": 2,
                "subsections": [
                    {
                        "name": "imgsize",
                        "lines": 5
                    },
                    {
                        "name": "html_imgsize",
                        "lines": 5
                    },
                    {
                        "name": "attr_imgsize",
                        "lines": 8
                    },
                    {
                        "name": "Input Types",
                        "lines": 27
                    },
                    {
                        "name": "Recognized Formats",
                        "lines": 52
                    },
                    {
                        "name": "Sharing the Cache Between Processes",
                        "lines": 16
                    },
                    {
                        "name": "Sizing PhotoCD Images",
                        "lines": 31
                    },
                    {
                        "name": "Controlling Behavior with GIF Images",
                        "lines": 35
                    }
                ]
            },
            {
                "name": "Image::Size AND WEBSERVERS",
                "lines": 4,
                "subsections": [
                    {
                        "name": "Pre-Caching Image Data",
                        "lines": 11
                    },
                    {
                        "name": "Shared Memory Caching",
                        "lines": 31
                    }
                ]
            },
            {
                "name": "MORE EXAMPLES",
                "lines": 24,
                "subsections": []
            },
            {
                "name": "DIAGNOSTICS",
                "lines": 5,
                "subsections": []
            },
            {
                "name": "CAVEATS",
                "lines": 8,
                "subsections": []
            },
            {
                "name": "SEE ALSO",
                "lines": 3,
                "subsections": []
            },
            {
                "name": "CONTRIBUTORS",
                "lines": 22,
                "subsections": []
            },
            {
                "name": "BUGS",
                "lines": 4,
                "subsections": []
            },
            {
                "name": "SUPPORT",
                "lines": 20,
                "subsections": []
            },
            {
                "name": "REPOSITORY",
                "lines": 2,
                "subsections": []
            },
            {
                "name": "LICENSE AND COPYRIGHT",
                "lines": 6,
                "subsections": []
            },
            {
                "name": "AUTHOR",
                "lines": 2,
                "subsections": []
            }
        ],
        "sections": {
            "NAME": {
                "content": "Image::Size - read the dimensions of an image in several popular formats\n",
                "subsections": []
            },
            "SYNOPSIS": {
                "content": "use Image::Size;\n# Get the size of globe.gif\n($globex, $globey) = imgsize(\"globe.gif\");\n# Assume X=60 and Y=40 for remaining examples\n\nuse Image::Size 'htmlimgsize';\n# Get the size as 'width=\"X\" height=\"Y\"' for HTML generation\n$size = htmlimgsize(\"globe.gif\");\n# $size == 'width=\"60\" height=\"40\"'\n\nuse Image::Size 'attrimgsize';\n# Get the size as a list passable to routines in CGI.pm\n@attrs = attrimgsize(\"globe.gif\");\n# @attrs == ('-width', 60, '-height', 40)\n\nuse Image::Size;\n# Get the size of an in-memory buffer\n($bufx, $bufy) = imgsize(\\$buf);\n# Assuming that $buf was the data, imgsize() needed a\n$ reference to a scalar\n",
                "subsections": []
            },
            "DESCRIPTION": {
                "content": "The Image::Size library is based upon the \"wwwis\" script written by Alex Knowles\n*(alex@ed.ac.uk)*, a tool to examine HTML and add 'width' and 'height' parameters to image tags.\nThe sizes are cached internally based on file name, so multiple calls on the same file name\n(such as images used in bulleted lists, for example) do not result in repeated computations.\n",
                "subsections": []
            },
            "SUBROUTINES/METHODS": {
                "content": "Image::Size provides three interfaces for possible import:\n",
                "subsections": [
                    {
                        "name": "imgsize",
                        "content": "Returns a three-item list of the X and Y dimensions (width and height, in that order) and\nimage type of *stream*. Errors are noted by undefined (undef) values for the first two\nelements, and an error string in the third. The third element can be (and usually is)\nignored, but is useful when sizing data whose type is unknown.\n"
                    },
                    {
                        "name": "html_imgsize",
                        "content": "Returns the width and height (X and Y) of *stream* pre-formatted as a single string\n'width=\"X\" height=\"Y\"' suitable for addition into generated HTML IMG tags. If the underlying\ncall to \"imgsize\" fails, undef is returned. The format returned is dually suited to both\nHTML and XHTML.\n"
                    },
                    {
                        "name": "attr_imgsize",
                        "content": "Returns the width and height of *stream* as part of a 4-element list useful for routines\nthat use hash tables for the manipulation of named parameters, such as the Tk or CGI\nlibraries. A typical return value looks like \"(\"-width\", X, \"-height\", Y)\". If the\nunderlying call to \"imgsize\" fails, undef is returned.\n\nBy default, only \"imgsize()\" is exported. Any one or combination of the three may be explicitly\nimported, or all three may be with the tag :all.\n"
                    },
                    {
                        "name": "Input Types",
                        "content": "The sort of data passed as *stream* can be one of three forms:\n\nstring\nIf an ordinary scalar (string) is passed, it is assumed to be a file name (either absolute\nor relative to the current working directory of the process) and is searched for and opened\n(if found) as the source of data. Possible error messages (see DIAGNOSTICS below) may\ninclude file-access problems.\n\nscalar reference\nIf the passed-in stream is a scalar reference, it is interpreted as pointing to an in-memory\nbuffer containing the image data.\n\n# Assume that &readdata gets data somewhere (WWW, etc.)\n$img = &readdata;\n($x, $y, $id) = imgsize(\\$img);\n# $x and $y are dimensions, $id is the type of the image\n\nOpen file handle\nThe third option is to pass in an open filehandle (such as an object of the \"IO::File\"\nclass, for example) that has already been associated with the target image file. The file\npointer will necessarily move, but will be restored to its original position before\nsubroutine end.\n\n# $fh was passed in, is IO::File reference:\n($x, $y, $id) = imgsize($fh);\n# Same as calling with filename, but more abstract.\n"
                    },
                    {
                        "name": "Recognized Formats",
                        "content": "Image::Size natively understands and sizes data in the following formats:\n\nGIF\nJPG\nXBM\nXPM\nPPM family (PPM/PGM/PBM)\nXV thumbnails\nPNG\nMNG\nTIF\nBMP\nPSD (Adobe PhotoShop)\nSWF (ShockWave/Flash)\nCWS (FlashMX, compressed SWF, Flash 6)\nPCD (Kodak PhotoCD, see notes below)\nEMF (Windows Enhanced Metafile Format)\nWEBP\nICO (Microsoft icon format)\nCUR (Microsoft mouse cursor format)\n\nAdditionally, if the Image::Magick module is present, the file types supported by it are also\nsupported by Image::Size. See also \"CAVEATS\".\n\nWhen using the \"imgsize\" interface, there is a third, unused value returned if the programmer\nwishes to save and examine it. This value is the identity of the data type, expressed as a 2-3\nletter abbreviation as listed above. This is useful when operating on open file handles or\nin-memory data, where the type is as unknown as the size. The two support routines ignore this\nthird return value, so those wishing to use it must use the base \"imgsize\" routine.\n\nNote that when the Image::Magick fallback is used (for all non-natively supported files), the\ndata type identity comes directly from the 'format' parameter reported by Image::Magick, so it\nmay not meet the 2-3 letter abbreviation format. For example, a WBMP file might be reported as\n'Wireless Bitmap (level 0) image' in this case.\n\nInformation Caching and $NOCACHE\nWhen a filename is passed to any of the sizing routines, the default behavior of the library is\nto cache the resulting information. The modification-time of the file is also recorded, to\ndetermine whether the cache should be purged and updated. This was originally added due to the\nfact that a number of CGI applications were using this library to generate attributes for pages\nthat often used the same graphical element many times over.\n\nHowever, the caching can lead to problems when the files are generated dynamically, at a rate\nthat exceeds the resolution of the modification-time value on the filesystem. Thus, the\noptionally-importable control variable $NOCACHE has been introduced. If this value is anything\nthat evaluates to a non-false value (be that the value 1, any non-null string, etc.) then the\ncacheing is disabled until such time as the program re-enables it by setting the value to false.\n\nThe parameter $NOCACHE may be imported as with the imgsize routine, and is also imported when\nusing the import tag \":all\". If the programmer chooses not to import it, it is still accessible\nby the fully-qualified package name, $Image::Size::NOCACHE.\n"
                    },
                    {
                        "name": "Sharing the Cache Between Processes",
                        "content": "If you are using Image::Size in a multi-thread or multi-process environment, you may wish to\nenable sharing of the cached information between the processes (or threads). Image::Size does\nnot natively provide any facility for this, as it would add to the list of dependencies.\n\nTo make it possible for users to do this themselves, the %CACHE hash-table that Image::Size uses\ninternally for storage may be imported in the use statement. The user may then make use of\npackages such as IPC::MMA (IPC::MMA) that can \"tie\" a hash to a shared-memory segment:\n\nuse Image::Size qw(imgsize %CACHE);\nuse IPC::MMA;\n\n...\n\ntie %CACHE, 'IPC::MM::Hash', $mmHash; # $mmHash via mmmakehash\n# Now, forked processes will share any changes made to the cache\n"
                    },
                    {
                        "name": "Sizing PhotoCD Images",
                        "content": "With version 2.95, support for the Kodak PhotoCD image format is included. However, these image\nfiles are not quite like the others. One file is the source of the image in any of a range of\npre-set resolutions (all with the same aspect ratio). Supporting this here is tricky, since\nthere is nothing inherent in the file to limit it to a specific resolution.\n\nThe library addresses this by using a scale mapping, and requiring the user (you) to specify\nwhich scale is preferred for return. Like the $NOCACHE setting described earlier, this is an\nimportable scalar variable that may be used within the application that uses Image::Size. This\nparameter is called $PCDSCALE, and is imported by the same name. It, too, is also imported when\nusing the tag \":all\" or may be referenced as $Image::Size::PCDSCALE.\n\nThe parameter should be set to one of the following values:\n\nbase/16\nbase/4\nbase\nbase4\nbase16\nbase64\n\nNote that not all PhotoCD disks will have included the \"base64\" resolution. The actual\nresolutions are not listed here, as they are constant and can be found in any documentation on\nthe PCD format. The value of $PCDSCALE is treated in a case-insensitive manner, so \"base\" is\nthe same as \"Base\" or \"BaSe\". The default scale is set to \"base\".\n\nAlso note that the library makes no effort to read enough of the PCD file to verify that the\nrequested resolution is available. The point of this library is to read as little as necessary\nso as to operate efficiently. Thus, the only real difference to be found is in whether the\norientation of the image is portrait or landscape. That is in fact all that the library extracts\nfrom the image file.\n"
                    },
                    {
                        "name": "Controlling Behavior with GIF Images",
                        "content": "GIF images present a sort of unusual situation when it comes to reading size. Because GIFs can\nbe a series of sub-images to be played as an animated sequence, what part does the user want to\nget the size for?\n\nWhen dealing with GIF files, the user may control the behavior by setting the global value\n$Image::Size::GIFBEHAVIOR. Like the PCD setting, this may be imported when loading the library.\nThree values are recognized by the GIF-handling code:\n\n0   This is the default value. When this value is chosen, the returned dimensions are those of\nthe \"screen\". The \"screen\" is the display area that the GIF declares in the first data block\nof the file. No sub-images will be greater than this in size; if they are, the specification\ndictates that they be cropped to fit within the box.\n\nThis is also the fastest method for sizing the GIF, as it reads the least amount of data\nfrom the image stream.\n\n1   If this value is set, then the size of the first sub-image within the GIF is returned. For\nplain (non-animated) GIF files, this would be the same as the screen (though it doesn't have\nto be, strictly-speaking).\n\nWhen the first image descriptor block is read, the code immediately returns, making this\nonly slightly-less efficient than the previous setting.\n\n2   If this value is chosen, then the code loops through all the sub-images of the animated GIF,\nand returns the dimensions of the largest of them.\n\nThis option requires that the full GIF image be read, in order to ensure that the largest is\nfound.\n\nAny value outside this range will produce an error in the GIF code before any image data is\nread.\n\nThe value of dimensions other than the view-port (\"screen\") is dubious. However, some users have\nasked for that functionality.\n"
                    }
                ]
            },
            "Image::Size AND WEBSERVERS": {
                "content": "There are a few approaches to getting the most out of Image::Size in a multi-process webserver\nenvironment. The two most common are pre-caching and using shared memory. These examples are\nfocused on Apache, but should be adaptable to other server approaches as well.\n",
                "subsections": [
                    {
                        "name": "Pre-Caching Image Data",
                        "content": "One approach is to include code in an Apache start-up script that reads the information on all\nimages ahead of time. A script loaded via \"PerlRequire\", for example, becomes part of the server\nmemory before child processes are created. When the children are created, they come into\nexistence with a pre-primed cache already available.\n\nThe shortcoming of this approach is that you have to plan ahead of time for which image files\nyou need to cache. Also, if the list is long-enough it can slow server start-up time.\n\nThe advantage is that it keeps the information centralized in one place and thus easier to\nmanage and maintain. It also requires no additional CPAN modules.\n"
                    },
                    {
                        "name": "Shared Memory Caching",
                        "content": "Another approach is to introduce a shared memory segment that the individual processes all have\naccess to. This can be done with any of a variety of shared memory modules on CPAN.\n\nProbably the easiest way to do this is to use one of the packages that allow the tying of a hash\nto a shared memory segment. You can use this in combination with importing the hash table\nvariable that is used by Image::Size for the cache, or you can refer to it explicitly by full\npackage name:\n\nuse IPC::Shareable;\nuse Image::Size;\n\ntie %Image::Size::CACHE, 'IPC::Shareable', 'size', { create => 1 };\n\nThat example uses IPC::Shareable (see IPC::Shareable) and uses the option to the \"tie\" command\nthat tells IPC::Shareable to create the segment. Once the initial server process starts to\ncreate children, they will all share the tied handle to the memory segment.\n\nAnother package that provides this capability is IPC::MMA (see IPC::MMA), which provides shared\nmemory management via the *mm* library from Ralf Engelschall (details available in the\ndocumentation for IPC::MMA):\n\nuse IPC::MMA;\nuse Image::Size qw(%CACHE);\n\nmy $mm = mmcreate(65536, '/tmp/testlockfile');\nmy $mmHash = mmmakehash($mm);\ntie %CACHE, 'IPC::MM::Hash', $mmHash;\n\nAs before, this is done in the start-up phase of the webserver. As the child processes are\ncreated, they inherit the pointer to the existing shared segment.\n"
                    }
                ]
            },
            "MORE EXAMPLES": {
                "content": "The attrimgsize interface is also well-suited to use with the Tk extension:\n\n$image = $widget->Photo(-file => $imgpath, attrimgsize($imgpath));\n\nSince the \"Tk::Image\" classes use dashed option names as \"CGI\" does, no further translation is\nneeded.\n\nThis package is also well-suited for use within an Apache web server context. File sizes are\ncached upon read (with a check against the modified time of the file, in case of changes), a\nuseful feature for a modperl environment in which a child process endures beyond the lifetime\nof a single request. Other aspects of the modperl environment cooperate nicely with this\nmodule, such as the ability to use a sub-request to fetch the full pathname for a file within\nthe server space. This complements the HTML generation capabilities of the CGI module, in which\n\"CGI::img\" wants a URL but \"attrimgsize\" needs a file path:\n\n# Assume $Q is an object of class CGI, $r is an Apache request object.\n# $imgpath is a URL for something like \"/img/redball.gif\".\n$r->print($Q->img({ -src => $imgpath,\nattrimgsize($r->lookupuri($imgpath)->filename) }));\n\nThe advantage here, besides not having to hard-code the server document root, is that Apache\npasses the sub-request through the usual request lifecycle, including any stages that would\nre-write the URL or otherwise modify it.\n",
                "subsections": []
            },
            "DIAGNOSTICS": {
                "content": "The base routine, \"imgsize\", returns undef as the first value in its list when an error has\noccurred. The third element contains a descriptive error message.\n\nThe other two routines simply return undef in the case of error.\n",
                "subsections": []
            },
            "CAVEATS": {
                "content": "Caching of size data can only be done on inputs that are file names. Open file handles and\nscalar references cannot be reliably transformed into a unique key for the table of cache data.\nBuffers could be cached using the MD5 module, and perhaps in the future I will make that an\noption. I do not, however, wish to lengthen the dependency list by another item at this time.\n\nAs Image::Magick operates on file names, not handles, the use of it is restricted to cases where\nthe input to \"imgsize\" is provided as file name.\n",
                "subsections": []
            },
            "SEE ALSO": {
                "content": "Image::Magick and Image::Info Perl modules at CPAN. The Graphics::Magick Perl API at\n<http://www.graphicsmagick.org/perl.html>.\n",
                "subsections": []
            },
            "CONTRIBUTORS": {
                "content": "Perl module interface by Randy J. Ray *(rjray@blackperl.com)*, original image-sizing code by\nAlex Knowles *(alex@ed.ac.uk)* and Andrew Tong *(werdna@ugcs.caltech.edu)*, used with their\njoint permission.\n\nSome bug fixes submitted by Bernd Leibing *(bernd.leibing@rz.uni-ulm.de)*. PPM/PGM/PBM sizing\ncode contributed by Carsten Dominik *(dominik@strw.LeidenUniv.nl)*. Tom Metro *(tmetro@vl.com)*\nre-wrote the JPG and PNG code, and also provided a PNG image for the test suite. Dan Klein\n*(dvk@lonewolf.com)* contributed a re-write of the GIF code. Cloyce Spradling\n*(cloyce@headgear.org)* contributed TIFF sizing code and test images. Aldo Calpini\n*(a.calpini@romagiubileo.it)* suggested support of BMP images (which I *really* should have\nalready thought of :-) and provided code to work with. A patch to allow htmlimgsize to produce\nvalid output for XHTML, as well as some documentation fixes was provided by Charles Levert\n*(charles@comm.polymtl.ca)*. The ShockWave/Flash support was provided by Dmitry Dorofeev\n*(dima@yasp.com)*. Though I neglected to take note of who supplied the PSD (PhotoShop) code, a\nbug was identified by Alex Weslowski <aweslowski@rpinteractive.com>, who also provided a test\nimage. PCD support was adapted from a script made available by Phil Greenspun, as guided to my\nattention by Matt Mueller *mueller@wetafx.co.nz*. A thorough read of the documentation and\nsource by Philip Newton *Philip.Newton@datenrevision.de* found several typos and a small buglet.\nVille Skytt� *(ville.skytta@iki.fi)* provided the MNG and the Image::Magick fallback code. Craig\nMacKenna *(mackenna@animalhead.com)* suggested making the cache available so that it could be\nused with shared memory, and helped test my change before release.\n",
                "subsections": []
            },
            "BUGS": {
                "content": "Please report any bugs or feature requests to \"bug-image-size at rt.cpan.org\", or through the\nweb interface at <http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Image-Size>. I will be\nnotified, and then you'll automatically be notified of progress on your bug as I make changes.\n",
                "subsections": []
            },
            "SUPPORT": {
                "content": "*   RT: CPAN's request tracker\n\n<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Image-Size>\n\n*   AnnoCPAN: Annotated CPAN documentation\n\n<http://annocpan.org/dist/Image-Size>\n\n*   CPAN Ratings\n\n<http://cpanratings.perl.org/d/Image-Size>\n\n*   Search CPAN\n\n<http://search.cpan.org/dist/Image-Size>\n\n*   Project page on GitHub\n\n<http://github.com/rjray/image-size>\n",
                "subsections": []
            },
            "REPOSITORY": {
                "content": "<https://github.com/rjray/image-size>\n",
                "subsections": []
            },
            "LICENSE AND COPYRIGHT": {
                "content": "This file and the code within are copyright (c) 1996-2009 by Randy J. Ray.\n\nCopying and distribution are permitted under the terms of the Artistic License 2.0\n(<http://www.opensource.org/licenses/artistic-license-2.0.php>) or the GNU LGPL 2.1\n(<http://www.opensource.org/licenses/lgpl-2.1.php>).\n",
                "subsections": []
            },
            "AUTHOR": {
                "content": "Randy J. Ray \"<rjray@blackperl.com>\"\n",
                "subsections": []
            }
        }
    }
}