Class PDFImage
- java.lang.Object
-
- org.faceless.pdf2.PDFImage
-
- All Implemented Interfaces:
Cloneable
public final class PDFImage extends 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:
PNG All except for 16 bit PNG JPEG No restrictions GIF If the GIF is animated, only the first frame is embedded TIFF All 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, PGM Only standard 8-bit PBM and PGM images are supported. Support was added in version 2.0.6 JPEG 2000 These 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()
andgetPixelWidth()
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, ColorSpace space, InputStream[] planes)
Create a PDFImage from the raw bitmap data provided.PDFImage(Image img)
Create a new PDFimage from the specifiedjava.awt.Image
.PDFImage(Image img, String properties)
Create a new PDFimage from the specifiedjava.awt.Image
.PDFImage(File in)
Create a new PDFImage from the specifed File.PDFImage(InputStream in)
Create a new PDFImage from the specifed InputStream.PDFImage(URL url)
Create a new PDFImage from the specifed URL.PDFImage(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 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 16double
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.ColorSpace
getImageColorSpace()
Return the ColorSpace of the image, or null if it cannot be determined.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.RenderedImage
getRenderedImage()
Return aRenderedImage
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 objectboolean
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 bysetStrictDPIMode(boolean)
void
putLiteral(String key, 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(ColorSpace space)
Override the stored ColorSpace in this image.void
setMetaData(String xmldata)
Set the XML metadata associated with this object.void
setStrictDPIMode(boolean strictdpi)
Set the "DPI Mode" to strict.String
toString()
-
-
-
Constructor Detail
-
PDFImage
public PDFImage(Image img) throws InterruptedException
Create a new PDFimage from the specifiedjava.awt.Image
. The image must be fully loaded, ie. the width and height are known, otherwise anIllegalArgumentException
is thrown.- Parameters:
img
- the image to load- Throws:
InterruptedException
- if the library is unable to read the pixels from the image before being interruptedIllegalArgumentException
- 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(Image img, String properties) throws InterruptedException
Create a new PDFimage from the specifiedjava.awt.Image
. The image must be fully loaded, ie. the width and height are known, otherwise anIllegalArgumentException
is thrown.- Parameters:
img
- the image to loadproperties
- 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 callquantize()
on the image after construction- Throws:
InterruptedException
- Since:
- 2.11.8
-
PDFImage
public PDFImage(byte[] buf) throws IOException
Load a PDFimage from a byte array. This method is identical to thePDFImage(InputStream)
constructor, but takes a byte array containing the image as a parameter instead- Throws:
IOException
- Since:
- 1.2
-
PDFImage
public PDFImage(File in) throws 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
- theFile
to read the image from- Throws:
IOException
- if the method is unable to read or parse the imageIllegalArgumentException
- if the image is invalid or can't be embedded.- Since:
- 2.21
-
PDFImage
public PDFImage(URL url) throws 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
- theURL
to read the image from- Throws:
IOException
- if the method is unable to read or parse the imageIllegalArgumentException
- if the image is invalid or can't be embedded.- Since:
- 2.21
-
PDFImage
public PDFImage(URLConnection con) throws 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
- theURLConnection
to read the image from- Throws:
IOException
- if the method is unable to read or parse the imageIllegalArgumentException
- if the image is invalid or can't be embedded.- Since:
- 2.21
-
PDFImage
public PDFImage(InputStream in) throws 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
- theInputStream
to read the image from- Throws:
IOException
- if the method is unable to read or parse the imageIllegalArgumentException
- 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, ColorSpace space, InputStream[] planes) throws 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 pixelsh
- the height of the image in pixelsbpc
- 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 imagedpiy
- the vertical dots-per-inch of the imagephoto
- for 8 bit images, whether to use JPEG compression instead of the normal Flate compression. For non 8-bit images this has no effectalpha
- whether or not an alpha plane is being passed in as the last planespace
- 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 containw*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:
IOException
- if one of the InputStreams throws an IOException while being read, or if one of them returns a -1 from it'sread()
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()
andgetWidth()
, as well as the corresponding vertical values.- Since:
- 2.26.4
-
isStrictDPIMode
public boolean isStrictDPIMode()
Return the value set bysetStrictDPIMode(boolean)
- 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 (seeisIndexed()
) 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
orTransparency.TRANSLUCENT
- Since:
- 2.27.1
- See Also:
getImageColorSpace()
,isIndexed()
-
setMetaData
public void setMetaData(String xmldata)
Set the XML metadata associated with this object. Since 2.26 this method callsgetXMP().read(new StringReader(xmldata == null ? "" : xmldata))
. We strongly recommend using thegetXMP()
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 Reader getMetaData() throws 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>
nodeSince 2.26 this simply returns
getXMP().isEmpty() ? null : new StringReader(getXMP().toString())
. It is strongly recommended that any code migrates to using thegetXMP()
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:
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)Callsquantize(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 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
ICCColorSpace
LabColorSpace
- A private ColorSpace class with type TYPE_RGB
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(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
- theColorSpace
to set the image to. A value ofnull
will cause the image to use device-dependent color, and a value ofColor.red.getColorSpace()
will set the image to sRGB. In practice this is the same thing.- Since:
- 2.11.8
-
getRenderedImage
public RenderedImage getRenderedImage() throws IOException
Return aRenderedImage
from this PDFImage.- Throws:
IOException
- if the image cannot be decoded- Since:
- 2.11.8
-
toString
public String toString()
-
putLiteral
public void putLiteral(String key, String tokens)
Put a literal token sequnce. For debugging- Parameters:
key
- the keytokens
- the token sequence, eg "true" or "/foo" or "[/Foo/Bar]". No refs, just direct objects.
-
-