Java (TM) Advanced Imaging API
Java (TM) Advanced Imaging API
sun.com
http://java.sun.com/products/java-media/jai/forDevelopers/jaifaq.html May 09, 2011
FAQ
Java Advanced Imaging API
This collection of answers to frequently asked questions (FAQ) provides brief answers to many common questions about the
Java Advanced Imaging API. Please check here before posting a question to the jai-interest@java.sun.com mailing list.
Many of the answers are derived from the jai-interest e-mail archive. For legal reasons, sample code provided by users outside
Sun cannot be included in the FAQ. However, links to that sample code in the archives are included.
Question Index
General
What is the Java Advanced Imaging API?
Who needs the Java Advanced Imaging API?
What features will the Java Advanced Imaging API add to the Java 2 platform?
Is the Java Advanced Imaging API compatible with the Java 2D API?
What other APIs relate to the Java Advanced Imaging API?
How and when can I get the Java Advanced Imaging API?
Is the Java Advanced Imaging API 100% pure Java?
How can I determine whether an operation has a native acceleration method?
Will the Java Advanced Imaging API source code be made available?
Where can I get more information?
How can I unsubscribe from the jai-interest mailing list?
Why don't my messages to the jai-interest mailing list appear?
My question may already be answered in the mail archives - where are they?
Reporting problems to the jai-interest alias.
Where can I get the Java Advanced Imaging Tutorial?
Does Java Advanced Imaging work with JDK 1.1?
Technical
How many bands and how many bits per band are supported?
What data formats are supported?
What is the best to use for performance?
What is the Java Advanced Imaging API doing about performance?
What is "mediaLib" (or "mlib") in the Java Advanced Imaging API?
Does Java Advanced Imaging require native code?
How can I avoid s?
How can I control the amount of memory allocated to the tile cache?
How can I control the amount of memory allocated to the Java runtime?
Java Advanced Imaging appears to have a memory leak
What is the best way to display large images efficiently in the Java Advanced Imaging API?
When/where are tiles cached in the Java Advanced Imaging API?
My image is in color, but the Java Advanced Imaging API is telling me there's only 1 band!
On Solaris, Java Advanced Imaging complains about lack of access to an X server.
How can I use a BufferedImage as a source for a Java Advanced Imaging operation?
How can I use a from the AWT in Java Advanced Imaging?
How do I create a from an array of data?
How do I convert images between color spaces?
How do I convert any image (with any color model) to a 1 bit image (B&W)?
How does the image coordinate system work?
How are regions of interest (ROIs) used?
How do I tell when a Java Advanced Imaging operator is complete?
How do I create an overlay?
How do I convert an image with 10 or 12 bit color to 8 bit color?
How do I handle palette-color images?
How does Java Advanced Imaging handle image borders?
How do I convert an into a grayscale Image?
How can I perform convolution with a different kernel for each band?
Can I serialize a ?
How can I create and run an Applet?
1 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
Platform
Image I/O
What image file formats are supported? What limitations do these have?
How does Image File I/O relate to Java Advanced Imaging?
How do I load an image into Java Advanced Imaging?
How can I load a page of a multi-page TIFF file?
How do I save an image as a TIFF (or: BMP, JPEG, PNG, ...)?
Why can't I delete a file that I read in using the "FileLoad" operator?
How can I store float data?
Is there any way to know the extent of an image before loading the complete file?
I wrote a PNG image with transparency but it looks opaque in my browser.
How come Java Advanced Imaging can't read one of my image files?
Why won't a remote operation load my image file?
Why doesn't Java Advanced Imaging support my favorite file format?
How can I save space when using the BMP format?
How can I save the data displayed on a Canvas in a file?
Why don't certain operations with GIF source images function correctly?
General
2 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
acceleration.
Will the source code for the Java Advanced Imaging API be made available?
The source code for the Java Advanced Imaging (JAI) API is not available at this time. We would however like to hear from
customers who might have an interest in obtaining the source code in the future. The exact mechanism by which the source
might be made available is at present undefined.
The latest API, programmers guide, and other available documents can be found at: http://java.sun.com/products/java-
media/jai/
3 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
appears in the subscription list, your posting may be disallowed. If this happens to you, please send mail to
jai-comments@sun.com and we will attempt to rectify the situation.
The other situation where it may seem that postings to the jai-interest mailing list do not appear, it may be that the
subscription options for you are set to not send you a copy of your posting. To rectify this, send mail to listserv@java.sun.com
with the following as body of mail
My question may already be answered in the mail archives - where are they?
The jai-interest archives are available on line at:
http://archives.java.sun.com/archives/jai-interest.html
The archives are available directly, grouped by month, in reverse chronological order and, within each month, in alphabetical
order by subject. Messages appear in the archive almost immediately after being posted to the list.
A search tool is available for the archives. Access to it may be obtained via the page referred to above or directly here.
Before posting a message to the discussion list, please consider searching the archives to determine whether the topic has
already been addressed.
For code that generates errors or exceptions, please use the Java command line option "-Djava.compiler=none" as this will
produce a stack trace with line numbers. These line numbers are important for us to locate the root cause of most bugs.
This tutorial is an interactive Java application that uses the Java Advanced Imaging API to showcase real-world imaging
examples, that run as a part of the tutorial. It will help you rapidly create new applications using Java Advanced Imaging.
Technical
How many bands and how many bits per band are supported?
The Java 2D and Java Advanced Imaging APIs support:
up to 32 bits for integral data
32 and 64 bit (float and double) floating-point data
any number of bands
Users may define their own custom classes to support other data types.
4 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
imaginary portion of each sample. Certain operators require the use of an integral data type (not float or double), e.g., table
lookup and bitwise logical operators.
On those Win32 platforms which support MMX, Java Advanced Imaging uses a version of mediaLib containing MMX
instructions for acceleration. For those Win32 and Solaris/Intel platforms where MMX is not supported, Java Advanced
Imaging uses a pure C version of mediaLib. On Solaris/SPARC platforms, it uses a version containing VIS instructions for
acceleration. On the Linux platform, it uses a pure C version of medialib. The use of mediaLib is not essential to the design of
the Java Advanced Imaging API; other native platform-specific libraries could be integrated in the future.
JAI creates a object to store computed portions of images. By default, the cache size is allowed to store up to 16
megabytes of image data. Therefore the JVM should generally be started up with a size larger than this. The actual memory
requirements depend on many factors such as the sizes of the images being used and how many operations are used to
produce an output image. A setting of , giving 128 megabytes of (virtual) memory to the JVM is a reasonable
starting value. Alternatively, you can specify the size of the tile cache yourself with the
method.
Another possible cause of excessive memory use is the use of tile sizes which are too large. By default, images inherit their
tile size from their source, i.e. the previous image in a chain. If the tile size is large, more data may be generated than required
by an operation. You can specify a smaller tile size for use by an image by creating an object, setting its tile size
fields and passing it to the call via a object.
You might also consider adjusting the capacity of the tile cache being used for your particular instance of Java Advanced
Imaging. The cache to use for a specific operation may also be specified via the . For all operations, a tile is
not calculated until a region of the image overlapping the tile is requested. To save re-computation, the resulting tiles are
stored in a cache. When the cache runs out of memory it removes tiles until it has enough memory to store the new tiles. For
example, if you are scrolling an image you might scroll to one area and then back to the original area. Tiles required in the
original area might have been flushed from the cache in the intervening time, thereby necessitating their recalculation. By
5 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
allowing recalculation to take place, there is no need to store all of the computed tiles permanently.
The most efficient storage of image data in RAM will be accomplished when the images are tiled and those tiles which are not
currently needed are flushed from memory. The deferred execution architecture of the operation chain attempts to process
only the tiles that it must. The tile cache attempts to flush those tiles which are no longer needed. These two facilities working
in tandem attempt to provide a reasonable tradeoff between memory use and computation.
The operation chain itself does not, however, handle the way image data are managed in the source and sink portions of the
chain as this cannot always be controlled by the API itself. For example, if the image source is a file which is not tiled, then the
entire image will be loaded. If a tiled source image file is used (e.g., tiled TIFF or FlashPIX), then only those tiles required to
execute the operation chain will be read from the disk.
Similarly, at the data sink end of a chain, e.g., the display, if the entire image is requested and held in memory then that will
provoke computation of all tiles in all intermediate operations in the chain and consequently reading of the entire image from
disk. The data sink will be most efficient if it requests only those tiles that it needs and uses some kind of efficient algorithm
for disposing of the destination tiles that it does not need, e.g., those neither being displayed nor adjacent to tiles being
displayed.
To reduce RAM usage even further you also have the option of implementing your own tile cache which uses an alternate
type of backing storage for the tiles in the cache, e.g., a disk file or a database. Such an approach may lower execution
speed in some cases but there are always tradeoffs. There is also a mechanism to replace the "Least Recently Used"
algorithm with a custom implementation via the tile cache metric and tile comparator features.
When images with non-standard bit depths (e.g., 1 or 2 bits per sample) are processed, some JAI operators may perform
temporary expansion to an 8 bit per sample format. This may require excessive memory in some cases. This behavior was
particularly pronounced in the 1.0.2 release; the 1.1 and later releases are significantly more efficient when performing scale,
rotate, affine, and transpose operations on 1-bit images.
In JAI 1.0.2, tiles were only removed from the Tile Cache when the cache became full. At this point, tiles were released from
memory until 25% of the memory was freed. As of JAI 1.1 and later, tiles can also be released if no "hard references" to the
tiles remain. This can occur for example, if an operation goes "out of scope". JAI 1.1 also checks for OutOfMemoryErrors
when requesting tiles, and if one occurs, tiles will be released from the cache and the compute request will be reissued. This
has significantly reduced OutOfMemoryError conditions in applications. Applications should still check for OutOfMemoryError
conditions because other portions of a program can trigger these independent of JAI.
Some improvements were made in JAI 1.1.1 to reduce memory related exceptions while loading image files that may have
been noticed with previous JAI versions.
How can I control the amount of memory allocated to the tile cache?
You may obtain a reference to the default tile cache and call its method, supplying the cache capacity in
bytes:
<size>
Sets the startup size of the memory allocation pool (the garbage collected heap) to <size>. The default is 4
megabytes of memory. The size must be at least 1000 bytes and must be less than or equal to the maximum
memory size (as specified by the option).
By default, the size is measured in bytes. To specify the size in either kilobytes or megabytes, append "k" for
kilobytes or "m" for megabytes.
6 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
In the JAI 1.1.1 version, the GIF and JPEG decoders were improved to no longer have a dependency on the X server.
How can I use a BufferedImage as a source for a Java Advanced Imaging operation?
A may be used directly as a source to any Java Advanced Imaging operator or method that calls for a
or source or sources.
7 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
3. Construct a from the and . You can use methods from the class to do
this.
6. Populate the with your data by using the method to copy your raster into the
TiledImage.
Only the last step involves any actual processing. The rest is just object creation.
CMY
CMYK
YCbCr based on REC 601
YCbCr linear based on REC 601
YCbCr based on REC 701
YCbCr linear based on REC 709
Linear Y part of YCbCr for Color Conversion Support
8 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
For simple linear conversions to grayscale, the "bandcombine" operator could also be used.
The dither operation needs to have a lookup table that converts any values less than half the grayscale range to zero and
any values above half the range to one. The dither operation will automatically vary the threshold to minimize any contouring
effects. Here is some sample code that illustrates using the "errordiffusion" and "ordereddither" operations for dithering a
grayscale image to a monochrome (1-bit or bilevel) image.
An alternative to dithering for converting an 8-bit grayscale image to a 1-bit monochrome image is simply to apply a threshold
to the image. The "Binarize" operation may be used for this purpose. A threshold may be derived by first creating a Histogram
using the "Histogram" operation and then calculating the threshold using one of several methods:
This code example demonstrates how "binarize" operation can be used to apply the threshold.
The coordinates of the upper-left corner of the image appears at the point given by the and methods.
The width and height of the image are obtained similarly using the and methods. In the illustration, the
image starts at pixel (-100, -90) and has a width of 330 pixels and height of 215 pixels. The lower right pixel of the image is
thus (229, 124). As shown here, the image location is not restricted to the positive quadrant.
Overlayed on the image is its tile grid. Each tile contains a rectangular portion of the image; all tiles have the same width and
height and tiles do not overlap. Tiles are referenced by a pair of indices, i.e., tile (2, 3) is to the right and below tile (1, 2).
Tiles may extend past the edges of the image. The contents of the portion outside the image are undefined. Only tiles that
have some overlap with the image bounds can be obtained by calling . Attempts to retrieve any other tiles will result in
a return value of
The semantics of an image never depend on the layout of its tile grid layout, but performance maybe affected by the choice of
9 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
tile size and offsets. The tile grid is defined by the four methods , ,
and . The first two methods yield the position of the upper-left corner of a notional tile (0, 0). The image need
not actually contain such a tile. For example, the tile grid of the image illustrated above may renumbered so that the upper left
tile has index (-1, -3) and the lower right tile has index (2, -1):
The image doesn't contain a (0, 0) tile at all, and the pixel ( , ) does not even fall
within the image. Both images should act exactly identically when used as a source for all JAI operations except possibly for
the output tile grid layout.
The minimum and maximum tile indices may be derived by determining the tile indices of the upper left and lower right pixels
of the image. To determine the tile index of a given point, the following methods (available in the class) may be
used:
It is not sufficent to compute since this will produce the wrong result for negative indices.
Instead, it is necessary to compute the equivalent of . The code above
produces the same results using integer arithmetic only.
Most often, images loaded from external sources will have their minimum X and Y and tile grid X and Y offsets all equal to
zero. As operations are performed, however, such as scaling, rotation or translation, the coordinates of the resultant images
will change.
On a more microscopic level, pixels in a may be thought of as squares with a 1 x 1 extent centered at (x +
0.5, y + 0.5). Geometric mapping operations may need to take this half pixel shift into account.
Unlike the coordinate system, which is discrete, the coordinate system is continuous. The
image dimensions are described in terms of floating-point miniumum X and Y coordinates, a height, and an aspect ratio. For
the "renderable" operation, you supply the height in the renderable coordinate space and the aspect ratio is derived
automatically from the ratio of the source image width to its height (width/height) in the rendered image coordinate system.
When a is rendered, an is applied to map its coordinate system into the rendered pixel
coordinate system which is appropriate to a target device such as a display, printer, file, etc. You have to specify the
appropriate transformation.
10 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
One way that you might be able to subtract regions in two images defined by a ROI is as follows:
Validates the sources and parameters of the operations according to the specification of the associated
Even at this point, actual tile data will not necessarily have been computed. A loop such as the following may be used to force
actual tile computation:
Note that if you wish to measure the execution time of a given node you will need to force computation on its source nodes
first to exclude their evaluation time from the measurement. The tile caching should also be disabled.
11 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
The result dst will have src2 on the top and src1 on the bottom. The part of src1 covered by src2 will not be seen. The image
layout (width, height, etc.) of dst is copied from src1.
One constraint is that src1 and src2 must have the same data type and number of bands, or the library will throw an
.
The position of src2 is based on its minimum X and Y. If you wish to move src2 to a different location, you must do a
"translate" operation on src2 first, and overlay the translated image on src1.
If src2 is bigger than src1, it may cover the entire src1 and you'll only see part of src2 as a result (since dst has the
dimensions of src1). To increase the dimensions of an image, the "border" operation may be used.
A refinement of this is to apply a linear "contrast stretch" (really a brightness adjustment) by mapping the min and max values
in the 12 bit image to 0 and 255 in the 8 bit image. (Note that we're cheating here and stuffing values we're interpreting as
unsigned into Java's signed byte type).
You can determine the min/max using Extrema operator. You will normally want to choose the min of all bands as the
minimum, and likewise for the max. Doing it band by band will cause color shifts. Of course, if the imagery is false color, you
may not care.
You may find that these approaches sacrifice too much detail at the low radiance end of the scale. Frequently a non-linear
transformation is needed, usually somewhere between square-root and cube-root.
12 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
specified via the it is incumbent on the user to ensure that it will be compatible with the destination
).
Some operations perform processing on the colormap, effectively changing the colormap and not performing any pixel
manipulation. This behavior is accomplished by the operations being subclasses of . The
operations which are implemented as subclasses of ColormapOpImage are "addConst", "andConst", "divideIntoConst", "exp",
"invert", "log", "lookup", "multiplyConst", "not", "orConst", "piecewise", "rescale", "subtractFromConst", "threshold" and
"xorConst".
Other operations, like "translate" (with integral translation factors) and "crop" operations do not actually perform any
processing of the data: they effectively forward tile requests on to the source image.
One of the common uses of the format operator is to cast the pixel values of an image to a given data type. In such a case,
since JAI 1.1.2, the format operation adds a object for with the
value of , if the source image provided has an . Due to the addition of this new
, using the "format" operation with source(s) that have an will cause the destination to have
an expanded non- . This expansion ensures that the conversion to a different data type,
or happens correctly such that the indices into the color map (for images) are not
treated as pixel data.
One further thing to note is that even if you pass in an via the this will not change the way in
which the image data per se are handled, although you might be able to display the result. For those operations that are not
subclasses of ColormapOpImage, or where color translation is not being performed through the use of
, the image data will still be processed as if they represent grayscale data.
Sometimes it might be useful to convert the palette-color images into RGB images at the beginning of the processing. One
way to expand the palette-color images is by inserting a "format" operation which changes the , thereby forcing
expansion. (Note that as mentioned "crop" and integral translation merely forward the tile requests to the source so you can't
expand the data via those operations.) Obviously expanding the palette-color data to RGB will increase the memory footprint
but this way you are assured of obtaining a valid result.
Probably the best means of converting a palette-color image to a 3-band RGB image is to use the "lookup" operation. You
can construct the lookup table using values returned by the getBlues()/getGreens()/getReds() methods of
the method should tell you the number of elements in the lookup table. This code example shows how to
perform the conversion.
The Java Advanced Imaging API does not have a "drop shadow" or similar special effect operator as found in some imaging
software. Such an effect could be created by overlaying an image over a modified version of itself to produce a 3D look.
13 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
How can I perform convolution with a different kernel for each band?
If you intend to convolve all bands of a given multi-band image (the common case) with the same kernel then you can use the
"convolve" operation as is. If however you would like to convolve each band of a multi-band image with a different kernel then
you would need to extract each band, e.g., using "bandselect", apply the appropriate convolution kernel to each band using
"convolve", and then merge the separate filtered bands into a resultant multi-band image.
If you are attempting to do some sort of multispectral template matching however, the above scenario might not be what you
want. In that case, you could use single-band convolution by, for example, first converting the images to a different color
space such as HIS or YCC and perform the template matching using the intensity or luminance band.
Can I serialize a ?
A may not be serialized directly as it does not implement the interface. You may however
construct a from a . See the
documentation for more information. Alternatively, if a suitable external file format exists the interfaces may be
useful.
Install the Java Plugin for your architecture (Solaris, Windows, etc.). The Java Plug-in is available from the Java Plug-in
download page. The Plug-in is now part of the JRE. Follow the links to download the plugins and patches for the
platform of your choice. There are also pointers to a FAQ, Documentation and other relevant information at this site.
Follow the Java Plug-in Browser Registration Instructions for the platform of your choice
Once the Java Plug-in is registered with the browser, download the JAI JRE installation executable
On Solaris: jai-1_1_2_01-lib-solaris-sparc-jre.bin
On Linux: jai-1_1_2_01-lib-linux-i586-jre.bin
On Windows: jai-1_1_2_01-lib-windows-i586-jre.exe
Follow the installation instruction to install JRE version of JAI into the Java Plugin just installed.
After JAI is installed in the manner described above, certain permissions may need to be added to the
On Solaris:
$HOME/.java.policy
On Windows (NT, for example)
C:\WINNT\Profiles\$User\.java.policy
The permissions needed to be added are:
On solaris:
On Windows:
14 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
If the users encode images in the applet, the applet may write to some temporary file. If the users don't encode images in
the applet, no permission is needed on Windows. As mentioned above, on Solaris, the user still needs to grant execute
permission to /usr/bin/uname on Solaris.
The above steps will make sure the JAI files are picked up by the Plugin at runtime.
Applets can also utilize the Auto Installation capabilities provided by Java Plugin (JPI) including Java extension deployment to
facilitate applet deployment. For details please refer to the The Java Advanced Imaging Installation Instructions.
In most of the reference port operation implementations there is also eventually an implementation class which is a descendent
of . For example, it may be a subclass of , , etc., as appropriate. The RIF or CRIF is
responsible for creating an instance of this class. It is possible for a RIF to instantiate different implementation classes
depending on the types of the sources and parameters. It is also possible for multiple RIFs to instantiate the same
implementation class (e.g., "rotate" and "affine" operators might share a common implementation). A RIF may even instantiate a
chain of several connected objects.
1. The for the operation in question will be retrieved from the registry.
2. The source(s) and parameter(s) will be checked for compatibility with the operation as defined by the
3. A is created for the given operation. The contains the name of the operation, the sources and
parameters and any rendering hints, but no actual image data until it is rendered as the result of a call to methods such as
, or .
2. The registry creates a list of RIFs for this operation in the preferred order and invokes the method of each RIF in
sequence; the first non- returned value is the result of the operation.
3. When the method of a RIF is invoked it is responsible for returning an instance of (usually an
subclass) created for this operation.
15 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
4. Register your operation descriptor, RIF/CRIF, and preferences if appropriate with the .
It is recommended that the user create a (and include it in the jar file or the classpath) and add the
necessary entries in that file to register the new operator, the image factories for each supported mode and preferences if any.
To avoid the hassles involved in creating a separate file, it is possible to register s and
RIFs/CRIFs, using the 's and / methods. After this
registering (and setting of preferences, if desired), the new operation can then be invoked through . Of course, the
drawback of this is that the new operator will not be automatically reloaded every time a Java Advanced Imaging program is
executed, since it is not present in . So, in order to use it, the registry methods would always have to be invoked
beforehand.
An example of how to use the 's methods to register a descriptor and it's image factories :
Aids to writing your own codec can be found in the Programmer's Guide, section 14.5 and the PNM code supplied with the
sample demo.
Bugs/Issues
Platform
16 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
Image I/O
What image file formats are supported? What limitations do these have?
The codec classes supplied with Java Advanced Imaging 1.1.2_01 support BMP, GIF (read only), FlashPix (read only), JPEG,
PNG, PNM, TIFF, and WBMP.
Please note the codec classes are not a committed part of the Java Advanced Imaging API, and that there is a separate Java
Image File I/O package. For more information on Image I/O in JAI please refer to Image I/O in Java Advanced Imaging.
The two file formats which support short integer (16-bit) data in the file I/O package supplied with Java Advanced Imaging
1.1.2_01 are Portable Network Graphics (PNG) and TIFF. There is support in the codec APIs for reading multi-image files, and
the TIFF codec was enhanced in 1.1 to support both reading and writing of multi-image files. Below are some answers to
common format-specific questions.
TIFF
The documentation incorrectly showed an example of using the "tiff" operator in renderable mode; all codecs operate in the
rendered mode only. You can do a followed by a to get a
renderable source based on an image file.
LZW compressed format (encoding) is not supported for the usual reason.
Planar format (PlanarConfiguration field has value 2) is not supported for decoding or encoding.
The TIFF reader reads only the tiles which overlap the data rectangle requested by operations which are "downstream" in
the imaging chain. Consequently for tiled TIFF the tiles are not read from the TIFF disk image until such time as their
geometric region is needed to complete processing of the chain for which they are the data source. If tiles have been
previously loaded but have since been flushed from the cache then they will of course need to be reloaded.
BMP
The Windows 95 version of BMP is supported. The bit depth of the output when saving a BMP will be determined by that
of the source image.
GIF
As of JAI 1.1.1, the JAI GIF decoder is no longer implemented by calling into the AWT Toolkit. The new implementation of
the JAI GIF decoder correctly handles images with transparent backgrounds.
GIF encoding is problematic due to active patents. See the jai-interest mail archive for possible solutions.
PNG
PNG is fully implemented. The type of the encoded image (RGB, Greyscale, or Palette) is determined by the type of the
image being saved, not by the choice of subclass.
JPEG
The JPEG support is currently implemented on top of the unofficial JDK classes in the package,
which may not exist in all Java 2 environments.
FlashPix
FlashPIX reading is only partially implemented. There is no FlashPIX writer. Tiles of FlashPIX images are read only when
17 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
required.
The Java Advanced Imaging API includes an extention interface allowing third parties to provide their favorite file format
handling. Some of the file formats which have been requested and which we encourage third parties to provide are FITS, NITF,
DICOM, EPS, RDF, or other vector formats.
How does Image File I/O relate to the Java Advanced Imaging API?
Please refer to http://java.sun.com/products/javamedia/jai/iio.html
It should be noted, if using the first option listed above, that since there are no requirements on the Java VM for when it actually
releases objects no longer referenced, there's no guarantee that invoking the garbage collector will actually cause the objects to
be garbage-collected. Thus the second option listed above is the better method.
18 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
If the objective is to actually reduce the number of colors in the image and then store it as a BMP, the following sequence of
steps could be followed:
1. Choose the 16 colors that will be used as the color palette for the output and dither the 24 bit image down to 4 bits per
channel.
2. Re-format this 4 bit image, so that the palette is stored in an associated and the data is stored 2 pixels
packed per byte (using a )
19 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
You can also use the freely available utility "tiffcp" (part of the libtiff distribution) to retile TIFF images. This works well with Java
Advanced Imaging. tiffcp is also a bit more tolerant of images with "bad" headers than Java Advanced Imaging and you can use
it on a TIFF image that Java Advanced Imaging can't read in order to clean it up. You can get libtiff here.
The utility "tiffsplit" is also in the libtiff distribution. This program splits a multi-image TIFF into single-image TIFFs.
20 of 21 5/10/2011 7:39 AM
Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=http://java.sun.com/prod...
The preceding snippet assumes that the images and have compatible s and that the min X and Y of these
images are set to give the correct relative positions. The translate operation can be used to set the min X and Y of the images to
the correct relative positions. The TiledImage should contain the desired result.
This assumes that the Collection object contains a number of s. Of course you can a use different layout for the
. If you want to display images in separate windows, just create a new for each image and put the panel in there.
21 of 21 5/10/2011 7:39 AM