Class PDFImage

  • All Implemented Interfaces:
    java.lang.Cloneable

    public final class PDFImage
    extends java.lang.Object

    The PDFImage class encapsulates a bitmap image, like a JPEG or PNG file, which can be inserted directly into the PDF document. Supported formats are:

    PNGAll except for 16 bit PNG
    JPEGNo restrictions
    GIFIf the GIF is animated, only the first frame is embedded
    TIFFAll variations except old-style JPEG, JBIG, SGI, Thunderscan, Next, and Lab images, most of which haven't been seen in years. For multi-page TIFF support see the PDFImageSet class.
    PBM, PGMOnly standard 8-bit PBM and PGM images are supported. Support was added in version 2.0.6
    JPEG 2000These can only be displayed in Acrobat 6 or later. Support added in version 2.1.1
       PDFPage page = pdf.newPage("A4");
       InputStream in = new FileInputStream("mypicture.jpg");
       PDFImage img = new PDFImage(in);
       in.close();
       page.drawImage(img, 100, 100, 100+i.getWidth(), 100+i.getHeight());
     

    Images embedded into the document can be stretched to any size, but it's important to remember that there is a loss in quality as they're stretched. A thumbnail-size image scaled to full page will look bad on a 72dpi screen, and worse on a 600dpi printer. See the getWidth() and getPixelWidth() methods for details.

    Embedded ICC Color Profiles will be respected, as are Transparency (supported by the GIF, PNG, TIFF and JPEG2000 file formats) and TIFF clipping paths. Note that transparency will require Acrobat 5 or later to display the PDF.

    Technical Note. The PDF does not embed the original image file, but instead stores the raw bitmap data. If the original bitmap format uses a compression scheme that is also used by PDF then it will not need to be recompressed, which will speed things up. For that reason, if you have a choice of image format to import try to choose one of the following:

    • TIFF images encoded as a single strip of CCITT Group 4 image data and msb-to-lsb FillOrder
    • JPEG
    • JPEG2000
    • TIFF images encoded using new-style JPEG compression
    • PNG other than 1-bit indexed PNG or 32-bit (= 24-bit plus alpha channel) PNG images
    Since:
    1.0
    • Constructor Summary

      Constructors 
      Constructor Description
      PDFImage​(byte[] buf)
      Load a PDFimage from a byte array.
      PDFImage​(int w, int h, int bpc, double dpix, double dpiy, boolean photo, boolean alpha, java.awt.color.ColorSpace space, java.io.InputStream[] planes)
      Create a PDFImage from the raw bitmap data provided.
      PDFImage​(java.awt.Image img)
      Create a new PDFimage from the specified java.awt.Image.
      PDFImage​(java.awt.Image img, java.lang.String properties)
      Create a new PDFimage from the specified java.awt.Image.
      PDFImage​(java.io.File in)
      Create a new PDFImage from the specifed File.
      PDFImage​(java.io.InputStream in)
      Create a new PDFImage from the specifed InputStream.
      PDFImage​(java.net.URL url)
      Create a new PDFImage from the specifed URL.
      PDFImage​(java.net.URLConnection con)
      Create a new PDFImage from the specifed URLConnection.
      PDFImage​(PDFImage image)
      Create an identical copy of the specified PDFImage.
    • Method Summary

      All Methods Instance Methods Concrete Methods Deprecated Methods 
      Modifier and Type Method Description
      protected java.lang.Object clone()  
      void close()
      Compress the image and close it, preventing any further changes.
      int getBitsPerComponent()
      Return the bit depth of the image; either 1, 2, 4, 8 or 16
      double getDPIX()
      Return the dots-per-inch of the image in the X direction (horizontally).
      double getDPIY()
      Return the dots-per-inch of the image in the Y direction (vertically) Not every image contains this information (for example, it's not part of the GIF specification), in which case this method returns the default resolution of 72, which means 1 pixel = 1 point.
      float getHeight()
      Return the height in points of the image.
      java.awt.color.ColorSpace getImageColorSpace()
      Return the ColorSpace of the image, or null if it cannot be determined.
      java.io.Reader getMetaData()
      Return any XML metadata associated with this object.
      int getOrientation()
      If the image has a valid EXIF Image Orientation tag, return the value of that tag, or 0 if it's invalid or not set.
      int getPixelHeight()
      Get the height of the image in pixels.
      int getPixelWidth()
      Get the width of the image in pixels.
      java.awt.image.RenderedImage getRenderedImage()
      Return a RenderedImage from this PDFImage.
      int getTransparency()
      Return true if the image makes use of transparency.
      float getWidth()
      Return the width in points of the image.
      XMP getXMP()
      Return an XMP Metadata object representing any XM metadata associated wth this object
      boolean hasDPI()
      Return true if the image has an actual DPI specified.
      boolean isIndexed()
      Return true if the image uses indexed color (eg GIF or 8-bit PNG), false if it uses full color.
      boolean isStrictDPIMode()
      Return the value set by setStrictDPIMode(boolean)
      void putLiteral​(java.lang.String key, java.lang.String tokens)
      Put a literal token sequnce.
      void quantize()
      Deprecated.
      call quantize(256, 0)
      void quantize​(int numcolors, int alphaThreshold)
      Convert a PDFImage to an "Indexed" image, by reducing the number of colors in the image to the specified number and storing each color as an index into a color table.
      void setColorSpace​(java.awt.color.ColorSpace space)
      Override the stored ColorSpace in this image.
      void setMetaData​(java.lang.String xmldata)
      Set the XML metadata associated with this object.
      void setStrictDPIMode​(boolean strictdpi)
      Set the "DPI Mode" to strict.
      java.lang.String toString()  
      • Methods inherited from class java.lang.Object

        equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
    • Constructor Detail

      • PDFImage

        public PDFImage​(java.awt.Image img)
                 throws java.lang.InterruptedException
        Create a new PDFimage from the specified java.awt.Image. The image must be fully loaded, ie. the width and height are known, otherwise an IllegalArgumentException is thrown.
        Parameters:
        img - the image to load
        Throws:
        java.lang.InterruptedException - if the library is unable to read the pixels from the image before being interrupted
        java.lang.IllegalArgumentException - if the image is invalid - ie. the width or height is zero or not defined, or if the image is not an embeddable image type
      • PDFImage

        public PDFImage​(java.awt.Image img,
                        java.lang.String properties)
                 throws java.lang.InterruptedException
        Create a new PDFimage from the specified java.awt.Image. The image must be fully loaded, ie. the width and height are known, otherwise an IllegalArgumentException is thrown.
        Parameters:
        img - the image to load
        properties - properties that can be specified to modify the way the image is encoded. For now value values are "JPEG", "JPEG=nnn" (where nnn is the quality between 0 and 100), "JPX" and "JPX=nnn" (where nnn is the quality, ranging from about 0.5 to 1.5). These arguments will cause the image to be compressed using JPEG or JPEG-2000 compression respectively. Another option is "quantize" which will call quantize() on the image after construction
        Throws:
        java.lang.InterruptedException
        Since:
        2.11.8
      • PDFImage

        public PDFImage​(byte[] buf)
                 throws java.io.IOException
        Load a PDFimage from a byte array. This method is identical to the PDFImage(InputStream) constructor, but takes a byte array containing the image as a parameter instead
        Throws:
        java.io.IOException
        Since:
        1.2
      • PDFImage

        public PDFImage​(java.io.File in)
                 throws java.io.IOException
        Create a new PDFImage from the specifed File. The file is not loaded in fully from disk, and the source file should exist for the life of this PDFImage object.
        Parameters:
        in - the File to read the image from
        Throws:
        java.io.IOException - if the method is unable to read or parse the image
        java.lang.IllegalArgumentException - if the image is invalid or can't be embedded.
        Since:
        2.21
      • PDFImage

        public PDFImage​(java.net.URL url)
                 throws java.io.IOException
        Create a new PDFImage from the specifed URL. If the URL is http or https and the server supports the Range header, then only the sections of the image that are required will be requested; although the benefits of this are fairly limited for most image types except TIFF, as usually the entire file is required.
        Parameters:
        url - the URL to read the image from
        Throws:
        java.io.IOException - if the method is unable to read or parse the image
        java.lang.IllegalArgumentException - if the image is invalid or can't be embedded.
        Since:
        2.21
      • PDFImage

        public PDFImage​(java.net.URLConnection con)
                 throws java.io.IOException
        Create a new PDFImage from the specifed URLConnection. If the URL is http or https and the server supports the Range header, then only the sections of the image that are required will be requested; although the benefits of this are fairly limited for most image types except TIFF, as usually the entire file is required.
        Parameters:
        con - the URLConnection to read the image from
        Throws:
        java.io.IOException - if the method is unable to read or parse the image
        java.lang.IllegalArgumentException - if the image is invalid or can't be embedded.
        Since:
        2.21
      • PDFImage

        public PDFImage​(java.io.InputStream in)
                 throws java.io.IOException
        Create a new PDFImage from the specifed InputStream. Note the InputStream is not closed by this constructor - it should be closed by the user
        Parameters:
        in - the InputStream to read the image from
        Throws:
        java.io.IOException - if the method is unable to read or parse the image
        java.lang.IllegalArgumentException - if the image is invalid or can't be embedded.
      • PDFImage

        public PDFImage​(int w,
                        int h,
                        int bpc,
                        double dpix,
                        double dpiy,
                        boolean photo,
                        boolean alpha,
                        java.awt.color.ColorSpace space,
                        java.io.InputStream[] planes)
                 throws java.io.IOException

        Create a PDFImage from the raw bitmap data provided. The vast majority of users will be better off either parsing an encoded image format or calling the PDFImage(java.awt.Image) constructor, but for special cases it's possible to use this constructor to pass the raw bitmap data in for each plane.

        Parameters:
        w - the width of the image in pixels
        h - the height of the image in pixels
        bpc - the number of bits for each component of the image. Must be 1, 2, 4, 8 or 16 - although 16 is only supported by Acrobat 6 or later.
        dpix - the horizontal dots-per-inch of the image
        dpiy - the vertical dots-per-inch of the image
        photo - for 8 bit images, whether to use JPEG compression instead of the normal Flate compression. For non 8-bit images this has no effect
        alpha - whether or not an alpha plane is being passed in as the last plane
        space - The ColorSpace this image is in. The number of components in the colorspace must match the number of planes passed in.
        planes - The planes of the image. Each InputStream represents a single plane (for example, a CMYK image would have four planes passed in, the first representing Cyan, the second Magenta and so on). Each InputStream must contain w*h*bpc bits of image data in the form of a number of horizontal scanlines starting at the top of the image. Each scanline must start on a byte boundary. Note the InputStreams are not closed by this constructor.
        Throws:
        java.io.IOException - if one of the InputStreams throws an IOException while being read, or if one of them returns a -1 from it's read() method.
        Since:
        2.2
      • PDFImage

        public PDFImage​(PDFImage image)
        Create an identical copy of the specified PDFImage. Usually unnecessary, but useful in the rare case that an image is being rendered in multiple threads and also having its properties changed - this can include metadata or compression levels
        Since:
        2.20.3
    • Method Detail

      • getWidth

        public float getWidth()

        Return the width in points of the image. This may be different to the width in pixels, depending on whether the image contains information about it's resolution.

        See Also:
        getDPIX()
      • getHeight

        public float getHeight()

        Return the height in points of the image. This may be different to the height in pixels, depending on whether the image contains information about it's resolution.

        See Also:
        getDPIY()
      • getPixelWidth

        public int getPixelWidth()
        Get the width of the image in pixels.
        Since:
        2.11.5
      • getPixelHeight

        public int getPixelHeight()
        Get the height of the image in pixels.
        Since:
        2.11.5
      • hasDPI

        public boolean hasDPI()
        Return true if the image has an actual DPI specified. Unfortunately this method is necessary to distinguish between (for example) a PNG which specifies 72dpi in the image explicitly, and one that defaults to 72dpi.
        Since:
        2.22.1
      • setStrictDPIMode

        public void setStrictDPIMode​(boolean strictdpi)
        Set the "DPI Mode" to strict. This method has come about because the HTML spec has relatively recently (2021) introduced a particular algorithm for extracting the DPI from bitmap images which is much stricter than the one normally used by the PDF API: it's extracted from the EXIF tags, so only applies to JPEG (in HTML at least; TIFF and JP2 also have EXIF tags, although that's not important to HTML).

        Calling this method immediately after the constructor to set "strict mode" will ensure that the same rules are used as for HTML. There's no physical change to the image, but it may change the values returned from hasDPI(), getDPIX() and getWidth(), as well as the corresponding vertical values.

        Since:
        2.26.4
      • getOrientation

        public int getOrientation()
        If the image has a valid EXIF Image Orientation tag, return the value of that tag, or 0 if it's invalid or not set.
        Since:
        2.22.1
      • getDPIX

        public double getDPIX()
        Return the dots-per-inch of the image in the X direction (horizontally). Not every image contains this information (for example, it's not part of the GIF specification), in which case this method returns the default resolution of 72, which means 1 pixel = 1 point.
        Since:
        1.2
      • getDPIY

        public double getDPIY()
        Return the dots-per-inch of the image in the Y direction (vertically) Not every image contains this information (for example, it's not part of the GIF specification), in which case this method returns the default resolution of 72, which means 1 pixel = 1 point.
        Since:
        1.2
      • getBitsPerComponent

        public int getBitsPerComponent()
        Return the bit depth of the image; either 1, 2, 4, 8 or 16
        Since:
        2.22.2
      • isIndexed

        public boolean isIndexed()
        Return true if the image uses indexed color (eg GIF or 8-bit PNG), false if it uses full color. For grayscale images this is arbitrary.
        Returns:
        true if the image is indexed.
        Since:
        2.27.1
        See Also:
        getImageColorSpace(), #isTranslucent, quantize()
      • getTransparency

        public int getTransparency()
        Return true if the image makes use of transparency. If the image is Indexed (see isIndexed()) this is done by marking an entry in the color index as fully transparent, which is allowed in PDF/A-1. If the image is not indexed, the transparency is done by masking the image - pixels can be fully transparent, fully opaque or anywhere in-between. This is not allowed in PDF/A-1.
        Returns:
        Transparency.OPAQUE, Transparency.BITMASK or Transparency.TRANSLUCENT
        Since:
        2.27.1
        See Also:
        getImageColorSpace(), isIndexed()
      • setMetaData

        public void setMetaData​(java.lang.String xmldata)
        Set the XML metadata associated with this object. Since 2.26 this method calls getXMP().read(new StringReader(xmldata == null ? "" : xmldata)). We strongly recommend using the getXMP() method and modifying the XMP directly rather than using this method.
        Parameters:
        xmldata - the XML data to embed into the document, or null to clear any existing metadata. No validation is performed on this input.
        Since:
        1.1.12
        See Also:
        getXMP()
      • getMetaData

        public java.io.Reader getMetaData()
                                   throws java.io.IOException

        Return any XML metadata associated with this object.

        Note that JPEG2000 images may have more than one MetaData stream embedded in them. If this is the case, in order to present only a single root node to the XML Parser, the XML objects are all wrapped in a single <JPEG2000> node

        Since 2.26 this simply returns getXMP().isEmpty() ? null : new StringReader(getXMP().toString()). It is strongly recommended that any code migrates to using the getXMP() method.

        Since 2.24.3, the returned type is guaranteed to hava a toString() method that will return the Metadata as a String.

        Returns:
        a Reader containing the source of the XML or null if no metadata is available.
        Throws:
        java.io.IOException - if the metadata can't be extracted
        Since:
        1.1.12
        See Also:
        getXMP()
      • getXMP

        public XMP getXMP()
        Return an XMP Metadata object representing any XM metadata associated wth this object
        Returns:
        the XMP, which may be empty or invalid but will never be null
        Since:
        2.26
      • close

        public void close()
        Compress the image and close it, preventing any further changes. Unless you're going to add MetaData to the image, it's always a good idea to call this method so you can claw back some memory.
        Since:
        2.0
        See Also:
        Cache
      • quantize

        public void quantize()
        Deprecated.
        call quantize(256, 0)
        Since:
        2.11.22
      • quantize

        public void quantize​(int numcolors,
                             int alphaThreshold)

        Convert a PDFImage to an "Indexed" image, by reducing the number of colors in the image to the specified number and storing each color as an index into a color table. This operation isn't quick, but for some types of image it can reduce the filesize with little or no loss of quality.

        For RGB source images it's typically better to do this in the image file - PNG and TIFF images can store indexed RGB data and GIF is always indexed - and for grayscale there's no benefit. However for CMYK images this method can make a significant difference.

        Parameters:
        numcolors - the number of colors to quantize to - must be a power of 2, and is almost always 256.
        alphaThreshold - if non-zero, any alpha values less than this amount will be treated as zero, and values greater will be treated as one. This will allow the image to be used with PDF/A-1 documents that disallow translucency, but it may result in visible shifts if the image makes use of translucent pixels. Use with caution and verify the results. Should typically be 128 - higher values will result in more transparency, lower values in less transparency.
        Since:
        2.27.1
        See Also:
        isIndexed()
      • getImageColorSpace

        public java.awt.color.ColorSpace getImageColorSpace()
        Return the ColorSpace of the image, or null if it cannot be determined. If the ColorSpace is device-dependent, it will be one of:
        • ColorSpace.getColorSpace(ColorSpace.CS_sRGB)
        • CMYKColorSpace
        • A private ColorSpace class with type TYPE_GRAY
        And if the ColorSpace is Calibrated it will be one of It may also be a instance of DeviceNColorSpace. If the returned value is null, the image is either an Image Mask indended to be drawn in the current color, or a JPEG2000 image with an unrecognised ColorSpace, in which case it probably can't be used with PDF anyway.
        Since:
        2.23.3
      • setColorSpace

        public void setColorSpace​(java.awt.color.ColorSpace space)

        Override the stored ColorSpace in this image. This may be necessary if the image has been saved with a particular ColorSpace which doesn't match the sRGB space used by Java. Typically this manifests itself by a shift to red or blue in the image when the PDF containing it is opened in Acrobat (a result of the image whitepoint being hotter or colder respectively than D65).

        The supplied ColorSpace should match the number of components as the current colorspace. If it doesn't, the image will be converted to the new ColorSpace (this is new in 2.25.1; prior to that release, an IllegalArgumentException would be thrown in this situation)

        Parameters:
        space - the ColorSpace to set the image to. A value of null will cause the image to use device-dependent color, and a value of Color.red.getColorSpace() will set the image to sRGB. In practice this is the same thing.
        Since:
        2.11.8
      • getRenderedImage

        public java.awt.image.RenderedImage getRenderedImage()
                                                      throws java.io.IOException
        Return a RenderedImage from this PDFImage.
        Throws:
        java.io.IOException - if the image cannot be decoded
        Since:
        2.11.8
      • toString

        public java.lang.String toString()
      • putLiteral

        public void putLiteral​(java.lang.String key,
                               java.lang.String tokens)
        Put a literal token sequnce. For debugging
        Parameters:
        key - the key
        tokens - the token sequence, eg "true" or "/foo" or "[/Foo/Bar]". No refs, just direct objects.
      • clone

        protected java.lang.Object clone()
        Overrides:
        clone in class java.lang.Object