org.modeshape.sequencer.image

## Class ImageMetadata

- java.lang.Object
- - org.modeshape.sequencer.image.ImageMetadata

-     public class ImageMetadata
      extends Object

  Get file format, image resolution, number of bits per pixel and optionally number of images, comments and physical resolution from JPEG, GIF, BMP, PCX, PNG, IFF, RAS, PBM, PGM, PPM and PSD files (or input streams).

  Use the class like this:

       ImageMetadata ii = new ImageMetadata();
       ii.setInput(in); // in can be InputStream or RandomAccessFile
       ii.setDetermineImageNumber(true); // default is false
       ii.setCollectComments(true); // default is false
       if (!ii.check()) {
           System.err.println("Not a supported image file format.");
           return;
       }
       System.out.println(ii.getFormatName() + ", " + ii.getMimeType() + ", " + ii.getWidth() + " x " + ii.getHeight() + " pixels, "
                          + ii.getBitsPerPixel() + " bits per pixel, " + ii.getNumberOfImages() + " image(s), "
                          + ii.getNumberOfComments() + " comment(s).");
       // there are other properties, check out the API documentation

  You can also use this class as a command line program. Call it with a number of image file names and URLs as parameters:

         java ImageMetadata *.jpg *.png *.gif http://somesite.tld/image.jpg

  or call it without parameters and pipe data to it:

         java ImageMetadata < image.jpg

  Known limitations:

  - When the determination of the number of images is turned off, GIF bits per pixel are only read from the global header. For some GIFs, local palettes change this to a typically larger value. To be certain to get the correct color depth, call setDetermineImageNumber(true) before calling check(). The complete scan over the GIF file will take additional time.
  - Transparency information is not included in the bits per pixel count. Actually, it was my decision not to include those bits, so it's a feature! ;-)

  Requirements:

  - Java 1.1 or higher

  The latest version can be found at http://schmidt.devlib.org/image-info/.

  Written by Marco Schmidt.

  This class is contributed to the Public Domain. Use it at your own risk.

  History:

  - 2001-08-24 Initial version.
  - 2001-10-13 Added support for the file formats BMP and PCX.
  - 2001-10-16 Fixed bug in read(int[], int, int) that returned
  - 2002-01-22 Added support for file formats Amiga IFF and Sun Raster (RAS).
  - 2002-01-24 Added support for file formats Portable Bitmap / Graymap / Pixmap (PBM, PGM, PPM) and Adobe Photoshop (PSD). Added new method getMimeType() to return the MIME type associated with a particular file format.
  - 2002-03-15 Added support to recognize number of images in file. Only works with GIF. Use `setDetermineImageNumber(boolean)` with `true` as argument to identify animated GIFs (`getNumberOfImages()` will return a value larger than `1`).
  - 2002-04-10 Fixed a bug in the feature 'determine number of images in animated GIF' introduced with version 1.1. Thanks to Marcelo P. Lima for sending in the bug report. Released as 1.1.1.
  - 2002-04-18 Added `setCollectComments(boolean)`. That new method lets the user specify whether textual comments are to be stored in an internal list when encountered in an input image file / stream. Added two methods to return the physical width and height of the image in dpi: `getPhysicalWidthDpi()` and `getPhysicalHeightDpi()`. If the physical resolution could not be retrieved, these methods return `-1`.
  - 2002-04-23 Added support for the new properties physical resolution and comments for some formats. Released as 1.2.
  - 2002-06-17 Added support for SWF, sent in by Michael Aird. Changed checkJpeg() so that other APP markers than APP0 will not lead to a failure anymore. Released as 1.3.
  - 2003-07-28 Bug fix - skip method now takes return values into consideration. Less bytes than necessary may have been skipped, leading to flaws in the retrieved information in some cases. Thanks to Bernard Bernstein for pointing that out. Released as 1.4.
  - 2004-02-29 Added support for recognizing progressive JPEG and interlaced PNG and GIF. A new method `isProgressive()` returns whether ImageMetadata has found that the storage type is progressive (or interlaced). Thanks to Joe Germuska for suggesting the feature. Bug fix: BMP physical resolution is now correctly determined. Released as 1.5.
  - 2004-11-30 Bug fix: recognizing progressive GIFs (interlaced in GIF terminology) did not work (thanks to Franz Jeitler for pointing this out). Now it should work, but only if the number of images is determined. This is because information on interlacing is stored in a local image header. In theory, different images could be stored interlaced and non-interlaced in one file. However, I think that's unlikely. Right now, the last image in the GIF file that is examined by ImageMetadata is used for the "progressive" status.
  - 2005-01-02 Some code clean up (unused methods and variables commented out, missing javadoc comments, etc.). Thanks to George Sexton for a long list. Removed usage of Boolean.toString because it's a Java 1.4+ feature (thanks to Gregor Dupont). Changed delimiter character in compact output from semicolon to tabulator (for better integration with cut(1) and other Unix tools). Added some points to the 'Known issues' section of the website. Released as 1.6.
  - 2005-07-26 Removed code to identify Flash (SWF) files. Has repeatedly led to problems and support requests, and I don't know the format and don't have the time and interest to fix it myself. I repeatedly included fixes by others which didn't work for some people. I give up on SWF. Please do not contact me about it anymore. Set package of ImageMetadata class to org.devlib.schmidt.imageinfo (a package was repeatedly requested by some users). Released as 1.7.
  - 2006-02-23 Removed Flash helper methods which weren't used elsewhere. Updated skip method which tries "read" whenever "skip(Bytes)" returns a result of 0. The old method didn't work with certain input stream types on truncated data streams. Thanks to Martin Leidig for reporting this and sending in code. Released as 1.8.
- 2006-11-13 Removed check that made ImageMetadata report JPEG APPx markers smaller than 14 bytes as files in unknown format. Such JPEGs seem to be generated by Google's Picasa application. First reported with fix by Karl von Randow. Released as 1.9.
- 2008-04-10 Changed comment vector to be `Vector<String>`, and removed any unnecessary casting. Also removed the unnecessary else statements where the previous block ended in a return. Also renamed to `ImageMetadata`.

- - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `static int` | `FORMAT_BMP` Return value of `getFormat()` for BMP streams.
    `static int` | `FORMAT_GIF` Return value of `getFormat()` for GIF streams.
    `static int` | `FORMAT_IFF` Return value of `getFormat()` for IFF streams.
    `static int` | `FORMAT_JPEG` Return value of `getFormat()` for JPEG streams.
    `static int` | `FORMAT_PBM` Return value of `getFormat()` for PBM streams.
    `static int` | `FORMAT_PCX` Return value of `getFormat()` for PCX streams.
    `static int` | `FORMAT_PGM` Return value of `getFormat()` for PGM streams.
    `static int` | `FORMAT_PNG` Return value of `getFormat()` for PNG streams.
    `static int` | `FORMAT_PPM` Return value of `getFormat()` for PPM streams.
    `static int` | `FORMAT_PSD` Return value of `getFormat()` for PSD streams.
    `static int` | `FORMAT_RAS` Return value of `getFormat()` for RAS streams.

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `ImageMetadata()`

  - ### Method Summary

    Methods
    Modifier and Type | Method and Description
    --- | ---
    `boolean` | `check()` Call this method after you have provided an input stream or file using `setInput(InputStream)` or `setInput(DataInput)`.
    `int` | `getBitsPerPixel()` If `check()` was successful, returns the image's number of bits per pixel.
    `String` | `getComment(int index)` Returns the index'th comment retrieved from the file.
    `int` | `getFormat()` If `check()` was successful, returns the image format as one of the FORMAT_xyz constants from this class.
    `String` | `getFormatName()` If `check()` was successful, returns the image format's name.
    `int` | `getHeight()` If `check()` was successful, returns one the image's vertical resolution in pixels.
    `String` | `getMimeType()` If `check()` was successful, returns a String with the MIME type of the format.
    `int` | `getNumberOfComments()` If `check()` was successful and `setCollectComments(boolean)` was called with `true` as argument, returns the number of comments retrieved from the input image stream / file.
    `int` | `getNumberOfImages()` Returns the number of images in the examined file.
    `int` | `getPhysicalHeightDpi()` Returns the physical height of this image in dots per inch (dpi).
    `float` | `getPhysicalHeightInch()` If `check()` was successful, returns the physical width of this image in dpi (dots per inch) or -1 if no value could be found.
    `int` | `getPhysicalWidthDpi()` If `check()` was successful, returns the physical width of this image in dpi (dots per inch) or -1 if no value could be found.
    `float` | `getPhysicalWidthInch()` Returns the physical width of an image in inches, or `-1.0f` if width information is not available.
    `int` | `getWidth()` If `check()` was successful, returns one the image's horizontal resolution in pixels.
    `boolean` | `isProgressive()` Returns whether the image is stored in a progressive (also called: interlaced) way.
    `static void` | `main(String[] args)` To use this class as a command line application, give it either some file names as parameters (information on them will be printed to standard output, one line per file) or call it with no parameters.
    `void` | `setCollectComments(boolean newValue)` Specify whether textual comments are supposed to be extracted from input.
    `void` | `setDetermineImageNumber(boolean newValue)` Specify whether the number of images in a file is to be determined - default is `false`.
    `void` | `setInput(DataInput dataInput)` Set the input stream to the argument stream (or file).
    `void` | `setInput(InputStream inputStream)` Set the input stream to the argument stream (or file).

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Field Detail

    - #### FORMAT_JPEG

          public static final int FORMAT_JPEG

      Return value of `getFormat()` for JPEG streams. ImageMetadata can extract physical resolution and comments from JPEGs (only from APP0 headers). Only one image can be stored in a file. It is determined whether the JPEG stream is progressive (see `isProgressive()`).
      See Also:
        Constant Field Values

    - #### FORMAT_GIF

          public static final int FORMAT_GIF

      Return value of `getFormat()` for GIF streams. ImageMetadata can extract comments from GIFs and count the number of images (GIFs with more than one image are animations). It is determined whether the GIF stream is interlaced (see `isProgressive()`).
      See Also:
        Constant Field Values

    - #### FORMAT_PNG

          public static final int FORMAT_PNG

      Return value of `getFormat()` for PNG streams. PNG only supports one image per file. Both physical resolution and comments can be stored with PNG, but ImageMetadata is currently not able to extract those. It is determined whether the PNG stream is interlaced (see `isProgressive()`).
      See Also:
        Constant Field Values

    - #### FORMAT_BMP

          public static final int FORMAT_BMP

      Return value of `getFormat()` for BMP streams. BMP only supports one image per file. BMP does not allow for comments. The physical resolution can be stored.
      See Also:
        Constant Field Values

    - #### FORMAT_PCX

          public static final int FORMAT_PCX

      Return value of `getFormat()` for PCX streams. PCX does not allow for comments or more than one image per file. However, the physical resolution can be stored.
      See Also:
        Constant Field Values

    - #### FORMAT_IFF

          public static final int FORMAT_IFF

      Return value of `getFormat()` for IFF streams.
      See Also:
        Constant Field Values

    - #### FORMAT_RAS

          public static final int FORMAT_RAS

      Return value of `getFormat()` for RAS streams. Sun Raster allows for one image per file only and is not able to store physical resolution or comments.
      See Also:
        Constant Field Values

    - #### FORMAT_PBM

          public static final int FORMAT_PBM

      Return value of `getFormat()` for PBM streams.
      See Also:
        Constant Field Values

    - #### FORMAT_PGM

          public static final int FORMAT_PGM

      Return value of `getFormat()` for PGM streams.
      See Also:
        Constant Field Values

    - #### FORMAT_PPM

          public static final int FORMAT_PPM

      Return value of `getFormat()` for PPM streams.
      See Also:
        Constant Field Values

    - #### FORMAT_PSD

          public static final int FORMAT_PSD

      Return value of `getFormat()` for PSD streams.
      See Also:
        Constant Field Values

  - ### Constructor Detail

    - #### ImageMetadata

          public ImageMetadata()

  - ### Method Detail

    - #### check

          public boolean check()

      Call this method after you have provided an input stream or file using `setInput(InputStream)` or `setInput(DataInput)`. If true is returned, the file format was known and information on the file's content can be retrieved using the various getXyz methods.
      Returns:
        if information could be retrieved from input

    - #### getBitsPerPixel

          public int getBitsPerPixel()

      If `check()` was successful, returns the image's number of bits per pixel. Does not include transparency information like the alpha channel.
      Returns:
        number of bits per image pixel

    - #### getComment

          public String getComment(int index)

      Returns the index'th comment retrieved from the file.
      Parameters:
        `index` - int index of comment to return
      Returns:
        the comment at the supplied index
      Throws:
        `IllegalArgumentException` - if index is smaller than 0 or larger than or equal to the number of comments retrieved
      See Also:
        `getNumberOfComments()`

    - #### getFormat

          public int getFormat()

      If `check()` was successful, returns the image format as one of the FORMAT_xyz constants from this class. Use `getFormatName()` to get a textual description of the file format.
      Returns:
        file format as a FORMAT_xyz constant

    - #### getFormatName

          public String getFormatName()

      If `check()` was successful, returns the image format's name. Use `getFormat()` to get a unique number.
      Returns:
        file format name

    - #### getHeight

          public int getHeight()

      If `check()` was successful, returns one the image's vertical resolution in pixels.
      Returns:
        image height in pixels

    - #### getMimeType

          public String getMimeType()

      If `check()` was successful, returns a String with the MIME type of the format.
      Returns:
        MIME type, e.g. `image/jpeg`

    - #### getNumberOfComments

          public int getNumberOfComments()

      If `check()` was successful and `setCollectComments(boolean)` was called with `true` as argument, returns the number of comments retrieved from the input image stream / file. Any number >= 0 and smaller than this number of comments is then a valid argument for the `getComment(int)` method.
      Returns:
        number of comments retrieved from input image

    - #### getNumberOfImages

          public int getNumberOfImages()

      Returns the number of images in the examined file. Assumes that `setDetermineImageNumber(true);` was called before a successful call to `check()`. This value can currently be only different from `1` for GIF images.
      Returns:
        number of images in file

    - #### getPhysicalHeightDpi

          public int getPhysicalHeightDpi()

      Returns the physical height of this image in dots per inch (dpi). Assumes that `check()` was successful. Returns `-1` on failure.
      Returns:
        physical height (in dpi)
      See Also:
        `getPhysicalWidthDpi()`, `getPhysicalHeightInch()`

    - #### getPhysicalHeightInch

          public float getPhysicalHeightInch()

      If `check()` was successful, returns the physical width of this image in dpi (dots per inch) or -1 if no value could be found.
      Returns:
        physical height (in dpi)
      See Also:
        `getPhysicalHeightDpi()`, `getPhysicalWidthDpi()`, `getPhysicalWidthInch()`

    - #### getPhysicalWidthDpi

          public int getPhysicalWidthDpi()

      If `check()` was successful, returns the physical width of this image in dpi (dots per inch) or -1 if no value could be found.
      Returns:
        physical width (in dpi)
      See Also:
        `getPhysicalHeightDpi()`, `getPhysicalWidthInch()`, `getPhysicalHeightInch()`

    - #### getPhysicalWidthInch

          public float getPhysicalWidthInch()

      Returns the physical width of an image in inches, or `-1.0f` if width information is not available. Assumes that `check()` has been called successfully.
      Returns:
        physical width in inches or `-1.0f` on failure
      See Also:
        `getPhysicalWidthDpi()`, `getPhysicalHeightInch()`

    - #### getWidth

          public int getWidth()

      If `check()` was successful, returns one the image's horizontal resolution in pixels.
      Returns:
        image width in pixels

    - #### isProgressive

          public boolean isProgressive()

      Returns whether the image is stored in a progressive (also called: interlaced) way.
      Returns:
        true for progressive/interlaced, false otherwise

    - #### main

          public static void main(String[] args)

      To use this class as a command line application, give it either some file names as parameters (information on them will be printed to standard output, one line per file) or call it with no parameters. It will then check data given to it via standard input.
      Parameters:
        `args` - the program arguments which must be file names

    - #### setCollectComments

          public void setCollectComments(boolean newValue)

      Specify whether textual comments are supposed to be extracted from input. Default is `false`. If enabled, comments will be added to an internal list.
      Parameters:
        `newValue` - if `true`, this class will read comments
      See Also:
        `getNumberOfComments()`, `getComment(int)`

    - #### setDetermineImageNumber

          public void setDetermineImageNumber(boolean newValue)

      Specify whether the number of images in a file is to be determined - default is `false`. This is a special option because some file formats require running over the entire file to find out the number of images, a rather time-consuming task. Not all file formats support more than one image. If this method is called with `true` as argument, the actual number of images can be queried via `getNumberOfImages()` after a successful call to `check()`.
      Parameters:
        `newValue` - will the number of images be determined?
      See Also:
        `getNumberOfImages()`

    - #### setInput

          public void setInput(DataInput dataInput)

      Set the input stream to the argument stream (or file). Note that `RandomAccessFile` implements `DataInput`.
      Parameters:
        `dataInput` - the input stream to read from

    - #### setInput

          public void setInput(InputStream inputStream)

      Set the input stream to the argument stream (or file).
      Parameters:
        `inputStream` - the input stream to read from

Copyright © 2008-2014 JBoss, a division of Red Hat. All Rights Reserved.