Top Banner
http://java.sun.com/products/java-media/jai/forDevelopers/jaifaq.html Sep 29, 2009 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 [email protected] 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 SampleModel 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 OutOfMemoryErrors? 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 java.awt.Image from the AWT in Java Advanced Imaging? How do I create a PlanarImage 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)? Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt... 1 de 26 29-09-2009 13:46
26
Welcome message from author
This document is posted to help you gain knowledge. Please leave a comment to let me know what you think about it! Share it to your friends and learn new things together.
Transcript
Page 1: Java Advanced Imaging API

http://java.sun.com/products/java-media/jai/forDevelopers/jaifaq.html Sep 29, 2009

FAQ

Java Advanced Imaging API

This collection of answers to frequently asked questions (FAQ) provides brief answers to many common questionsabout the Java Advanced Imaging API. Please check here before posting a question to the [email protected] list.

Many of the answers are derived from the jai-interest e-mail archive. For legal reasons, sample code provided byusers outside Sun cannot be included in the FAQ. However, links to that sample code in the archives are included.

Question Index

GeneralWhat 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 SampleModel 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 OutOfMemoryErrors? 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 java.awt.Image from the AWT in Java Advanced Imaging?How do I create a PlanarImage 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)?

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

1 de 26 29-09-2009 13:46

Page 2: Java Advanced Imaging API

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 IndexColorModel into a grayscale Image? How can I perform convolution with a different kernel for each band? Can I serialize a TiledImage? How can I create and run an Applet? Where can I find an example of how to write a custom operator?

Bugs/Issues (see also the JAI bug page)

Why is my application crashing?

Platform

What platforms are supported? Does Java Advanced Imaging run on my Macintosh? When will Java Advanced Imaging be available for Linux? Is there code which accelerates the image operators on some platforms?

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?

Additional Code SamplesAdd a transparency mask (alpha channel) to an image. Scale an image or image region. Retile an image. Choose an image with a file dialog and load it into a ScrollingImagePanel. Convolve an image. Combine multiple separate images into one multibanded image. Load an image, do something to every pixel, and display the result. Place one smaller Image within a larger template image into a pre-defined area. Display a collection of images.

General

What is the Java Advanced Imaging API?

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

2 de 26 29-09-2009 13:46

Page 3: Java Advanced Imaging API

The Java Advanced Imaging API extends the Java 2 platform by allowing sophisticated, high-performance imageprocessing to be incorporated into Java applets and applications. It is a set of classes providing imagingfunctionality beyond that of Java 2D and the Java Foundation classes, though it is designed for compatibility withthose APIs. This API implements a set of core image processing capabilities including image tiling, regions ofinterest, deferred execution and a set of core image processing operators, including many common point, area,and frequency domain operators.

Back to Question Index

Who needs the Java Advanced Imaging API? The Java Advanced Imaging API is intended to meet the needs of technical (medical, seismological, remotesensing, etc.) as well as commercial imaging (such as document production and photography). The API canbenefit all Java developers who want to incorporate imaging into their Java applets and applications.

Back to Question Index

What features does the Java Advanced Imaging API add to the Java 2 platform? Rich set of functionality for digital imaging. High level of extensibility to allow arbitrary processing capabilities. Support for a wide variety of data types. Deferred Execution. Remote Imaging and truly distributed imaging. Allow multiple implementations with different trade-offs of memory usage, operator optimization, and hardwareacceleration.

Back to Question Index

Is the Java Advanced Imaging API compatible with the Java 2D API? Yes. Applications written using the Java 2D API are completely forward compatible with the Java AdvancedImaging API.

Back to Question Index

What other APIs relate to the Java Advanced Imaging API? The Java Advanced Imaging API is part of the Java Media API suite that work together to provide customers withenhanced graphics, imaging and communication capabilities. These APIs include: Java 2D for graphics, text, andfundamental image manipulation; Java 3D; Image I/O; the Java Media Framework (JMF) for components to playand control time-based media such as audio and video; Java Shared Data Toolkit; Java Sound; and Java Speech.

Back to Question Index

How and when can I get the Java Advanced Imaging API?A 1.1.2_01 implementation of the Java Advanced Imaging API is available as a standard extension to the Java 2platform from the Java Advanced Imaging Website.

Back to Question Index

Is the Java Advanced Imaging API 100% pure Java?The Java Advanced Imaging API may be run without any native code, i.e., without the code which provides nativeacceleration. When run in this manner, the Java Advanced Imaging API uses only Java code. However, the JavaAdvanced Imaging API has not yet been certified as meeting the requirements of the "100% Pure Java" Programper se.

Back to Question Index

How can I determine whether an operation has a native acceleration method?The Java Advanced Imaging 1.1.2_01 README lists all the operations that have a native implementation (Seesection "Operators").

If a native implementation is present it is, by default, the preferred implementation. But if the nature of the sourcesand parameters of the operation are incompatible with the native operation then processing will revert to Javacode. In general the following minimum requirements must be adhered to for the mediaLib native implementation ofan operation to be executed:

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

3 de 26 29-09-2009 13:46

Page 4: Java Advanced Imaging API

All sources must be RenderedImages.All sources and destination must have

a SampleModel which is a ComponentSampleModel anda ColorModel which is a ComponentColorModel or no ColorModel (i.e., it is null).

All sources and the destination must have at most 4 bands of pixel data.

Further restrictions may be imposed by individual operations but the above are the most common requirements.

Back to Question Index

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 tohear from customers who might have an interest in obtaining the source code in the future. The exact mechanismby which the source might be made available is at present undefined.

Back to Question Index

Where can I get more information?A very good source of code snippets and discussions on more obscure topics in the Java Advanced Imaging APIis the jai-interest mail archive, at: http://archives.java.sun.com/archives/jai-interest.html

The latest API, programmers guide, and other available documents can be found at: http://java.sun.com/products/java-media/jai/

Back to Question Index

How can I unsubscribe from the jai-interest mailing list?To unsubscribe, send email to [email protected] and include in the body of the message signoffjai-interest. For general help, send email to [email protected] and include "help" in the body of themessage.

Back to Question Index

Why don't my messages to the jai-interest mailing list appear?From time to time, in order to prevent unsolicited commercial messages ("spam") from appearing on the list, wemay allow postings only from list subscribers. If the email address from which you sent the message does notmatch your address as it appears in the subscription list, your posting may be disallowed. If this happens to you,please send mail to [email protected] 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 thesubscription options for you are set to not send you a copy of your posting. To rectify this, send mail [email protected] with the following as body of mail

SET [email protected] MAIL SUBJECTHDR REPRO NOACK

Back to Question Index

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, inalphabetical 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 directlyhere.

Before posting a message to the discussion list, please consider searching the archives to determine whether thetopic has already been addressed.

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

4 de 26 29-09-2009 13:46

Page 5: Java Advanced Imaging API

Back to Question Index

Reporting problems to the jai-interest alias.Please scan this FAQ and the mail archives to see if your problem has already been addressed. If it hasn't, thereare several things you can do to increase the chances that we will be able to help you resolve your problem.Please supply the simplest possible code that exhibits the problem if at all possible. A self-contained, compilableexample is best. Where this is not possible, as much context as you can give will be helpful.

For code that generates errors or exceptions, please use the Java command line option "-Djava.compiler=none" asthis will produce a stack trace with line numbers. These line numbers are important for us to locate the root causeof most bugs.

Back to Question Index

Where can I get the Java Advanced Imaging Tutorial?The Java Advanced Imaging Tutorial is available for download athttp://java.sun.com/products/javamedia/jai (Click Download)

This tutorial is an interactive Java application that uses the Java Advanced Imaging API to showcase real-worldimaging examples, that run as a part of the tutorial. It will help you rapidly create new applications using JavaAdvanced Imaging.

Back to Question Index

Does Java Advanced Imaging work with JDK 1.1?No. You need the Java 2 platform (a/k/a JDK 1.2). Specifically, Java Advanced Imaging 1.1.2_01 requires theJava 2 platform, version 1.3 or higher.

Back to Question Index

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 data32 and 64 bit (float and double) floating-point dataany number of bands

Users may define their own custom SampleModel classes to support other data types.

Back to Question Index

What data formats are supported?The Java Advanced Imaging API supports unsigned byte, signed and unsigned short (Java 2 only partiallysupports signed short), int, float, and double data types. Complex numbers are represented using two bands, onefor the real and one for the imaginary portion of each sample. Certain operators require the use of an integral datatype (not float or double), e.g., table lookup and bitwise logical operators.

Back to Question Index

What is the best SampleModel to use for performance?Fastest processing performance will be achieved when the Raster is composed of aPixelInterleavedSampleModel and a DataBuffer type that is supported by native acceleration for the operationsof interest. The BandOffsets arrays of all sources and the destinations should match.

Back to Question Index

What is the Java Advanced Imaging API doing about performance?

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

5 de 26 29-09-2009 13:46

Page 6: Java Advanced Imaging API

An optional C-based library for Win32, Solaris and Linux provides performance enhancements for many operators.This library is called mediaLib.Additional hardware optimization on UltraSPARC running Solaris is achieved using the VIS Instruction Set.Additional hardware optimization on the Intel x86 architecture is achieved using MMX.

Back to Question Index

What is "mediaLib" (or "mlib") in the Java Advanced Imaging API?mediaLib is a Sun-developed high-performance image processing library. The reference implementation of the JavaAdvanced Imaging API makes use of a special version of mediaLib which is a subset of mediaLib 2.0 and includesa JNI wrapper. For more information on mediaLib 2.0, see:http://www.sun.com/sparc/vis/mediaLib.html

On those Win32 platforms which support MMX, Java Advanced Imaging uses a version of mediaLib containingMMX instructions for acceleration. For those Win32 and Solaris/Intel platforms where MMX is not supported, JavaAdvanced Imaging uses a pure C version of mediaLib. On Solaris/SPARC platforms, it uses a version containingVIS instructions for acceleration. On the Linux platform, it uses a pure C version of medialib. The use of mediaLibis not essential to the design of the Java Advanced Imaging API; other native platform-specific libraries could beintegrated in the future.

Back to Question Index

Does Java Advanced Imaging require native code?No. Native code is supplied for performance purposes only. A C library is supplied for SPARC, Linux and Intel x86platforms which accelerates most of the operators. In addition there is a lower level SPARC library (VIS) and aMMX library allowing additional hardware acceleration for many operators. If Java Advanced Imaging code doesnot find these libraries, pure Java code is used.

Back to Question Index

How can I avoid OutOfMemoryErrors?There are several possible reasons for an application to produce an OutOfMemoryError.

A common reason is a failure to specify enough memory for the Java virtual machine (JVM) at application startuptime. Regardless of how much physical and virtual memory is available on your system, the Java runtime will onlyallocate a fixed amount, which is determined when the Java Virtual Machine (JVM) starts up. How to allocatemore memory to the JVM is discussed below.

JAI creates a TileCache object to store computed portions of images. By default, the cache size is allowed tostore up to 16 megabytes of image data. Therefore the JVM should generally be started up with a size larger thanthis. The actual memory requirements depend on many factors such as the sizes of the images being used andhow many operations are used to produce an output image. A setting of -Xmx128m, giving 128 megabytes of(virtual) memory to the JVM is a reasonable starting value. Alternatively, you can specify the size of the tile cacheyourself with the TileCache.setMemoryCapacity() method.

Another possible cause of excessive memory use is the use of tile sizes which are too large. By default, imagesinherit their tile size from their source, i.e. the previous image in a chain. If the tile size is large, more data may begenerated than required by an operation. You can specify a smaller tile size for use by an image by creating anImageLayout object, setting its tile size fields and passing it to the JAI.create() call via a RenderingHintsobject.

You might also consider adjusting the capacity of the tile cache being used for your particular instance of JavaAdvanced Imaging. The cache to use for a specific operation may also be specified via the RenderingHints. Forall operations, a tile is not calculated until a region of the image overlapping the tile is requested. To savere-computation, the resulting tiles are stored in a cache. When the cache runs out of memory it removes tiles untilit has enough memory to store the new tiles. For example, if you are scrolling an image you might scroll to onearea and then back to the original area. Tiles required in the original area might have been flushed from the cache

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

6 de 26 29-09-2009 13:46

Page 7: Java Advanced Imaging API

in the intervening time, thereby necessitating their recalculation. By allowing recalculation to take place, there is noneed 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 tileswhich are not currently needed are flushed from memory. The deferred execution architecture of the operationchain attempts to process only the tiles that it must. The tile cache attempts to flush those tiles which are nolonger needed. These two facilities working in tandem attempt to provide a reasonable tradeoff between memoryuse and computation.

The operation chain itself does not, however, handle the way image data are managed in the source and sinkportions of the chain as this cannot always be controlled by the API itself. For example, if the image source is afile which is not tiled, then the entire image will be loaded. If a tiled source image file is used (e.g., tiled TIFF orFlashPIX), 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 memorythen that will provoke computation of all tiles in all intermediate operations in the chain and consequently reading ofthe entire image from disk. The data sink will be most efficient if it requests only those tiles that it needs and usessome kind of efficient algorithm for disposing of the destination tiles that it does not need, e.g., those neither beingdisplayed 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 analternate type of backing storage for the tiles in the cache, e.g., a disk file or a database. Such an approach maylower 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 comparatorfeatures.

When images with non-standard bit depths (e.g., 1 or 2 bits per sample) are processed, some JAI operators mayperform 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 moreefficient 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 werereleased 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 alsochecks for OutOfMemoryErrors when requesting tiles, and if one occurs, tiles will be released from the cache andthe 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 triggerthese independent of JAI.

Some improvements were made in JAI 1.1.1 to reduce memory related exceptions while loading image files thatmay have been noticed with previous JAI versions.

Back to Question Index

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 setMemoryCapacity method, supplying the cachecapacity in bytes:

TileCache cache =    JAI.getDefaultInstance().getTileCache();long size = 32*1024*1024L; // 32 megabytescache.setMemoryCapacity(size);

Back to Question Index

How can I control the amount of memory allocated to the Java runtime?It may be necessary to set the maximum size of the memory allocation pool of the Java interpreter using the -Xmx

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

7 de 26 29-09-2009 13:46

Page 8: Java Advanced Imaging API

command line option. This is particularly important if you are attempting to work with large, untiled imagery.-Xmx<size>

Sets the maximum size of the memory allocation pool (the garbage collected heap) to <size>. The defaultis 1 megabyte of memory. The size must be at least 1000 bytes.

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.

-Xms<size>Sets the startup size of the memory allocation pool (the garbage collected heap) to <size>. The default is4 megabytes of memory. The size must be at least 1000 bytes and must be less than or equal to themaximum memory size (as specified by the -Xmx 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.

Back to Question Index

Java Advanced Imaging appears to have a memory leak.While it is certainly possible that a bug in either the Java runtime or the implementation of the Java AdvancedImaging API itself could cause a memory leak, in most cases what appears to be a memory leak is simply theresult of a temporary demand for more memory than is available from the Java runtime. A true memory leakimplies that an ever-increasing amount of memory will be required by the application; an application that requests alarge amount of memory but will eventually release it may be inefficient but cannot truly be said to exhibit amemory leak. The JAI 1.0.2 implementation of the tile cache allowed the cache to fill completely before releasingtiles, giving the impression of an increasing consumption of memory. JAI 1.1 allows tiles to be released whenthere are no longer any "hard references" to the operation objects.

Back to Question Index

What is the best way to display large images efficiently in the Java AdvancedImaging API?In general, the proper use of tiling is the easiest way to limit the amount of work done. Setting the tile sizes will bevery application-dependent. The Java Advanced Imaging API will perform work on a per-tile basis. If the finaloperator in a chain requires a certain source rectangle to be computed, the actual computation may extend pastthe actual area needed, up to the next set of tile boundaries.Experiments have shown that tile sizes of 512x512 and larger appear to be the most efficient.

Back to Question Index

When/where are tiles cached in the Java Advanced Imaging API?The only place where caching takes place automatically is in the method OpImage.getTile. So if you subclassfrom OpImage and override the computeTile or computeRect methods, but not the getTile method (or youoverride getTile but call the superclass method somehow), you get caching automatically. Otherwise, you don't.You can construct your own implementations of the TileCache interface or use the factory method in the JAIclass and insert tiles manually, or you can construct a NullOpImage around your image which will performcaching.

If you're using an OpImage subclass, but don't want caching, you can call:

this.setTileCache(null);

Back to Question Index

My image is in color, but the Java Advanced Imaging API is telling me there's only 1band!A RenderedImage has a SampleModel and a ColorModel. The SampleModel describes the pixel data the imagehas and how it is stored in the buffer. The ColorModel interprets the pixel data in a specific ColorSpace. The

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

8 de 26 29-09-2009 13:46

Page 9: Java Advanced Imaging API

color definition of a particular band of the pixel is dependent on the ColorModel and its associated ColorSpace.Without a ColorModel, the pixel data of an image has no color definition.

Your image may have an IndexColorModel. In this case, the image data is stored in a 1-banded form, and theColorModel is used to determine the red, green, blue, and optional alpha values for each pixel. Thejavax.media.jai.RasterAccessor will automatically cause such images to appear to have 3 or 4 bands asappropriate.

Back to Question Index

On Solaris, Java Advanced Imaging complains about lack of access to an X server.Java Advanced Imaging versions previous to JAI 1.1.1 used the AWT toolkit to load GIF and JPEG files. Thisproblem is a manifestation of a JDK bug in which creation of the AWT Toolkit class results in an attempt to openthe X display. To work around this problem in Java Advanced Imaging versions prior to 1.1.1, either make an Xdisplay available to the Java runtime using the DISPLAY environment variable (no windows will appear on thedisplay), or consider running a dummy X server that will satisfy the AWT, such as the Xvfb utility included with theX11R6.4 distribution.

In the JAI 1.1.1 version, the GIF and JPEG decoders were improved to no longer have a dependency on the Xserver.

Back to Question Index

How can I use a BufferedImage as a source for a Java Advanced Imagingoperation?A BufferedImage may be used directly as a source to any Java Advanced Imaging operator or method that callsfor a RenderedImage or WritableRenderedImage source or sources.

Back to Question Index

How can I use a java.awt.Image from the AWT in Java Advanced Imaging?This code sample reads a GIF or JPEG file using the java.awt.Toolkit class into a java.awt.Image, convertsthe AWT-Image into a RenderedImage in JAI, then displays the RenderedImage.

You can also do this in Java2D. Use a MediaTracker to ensure the image is loaded, get its width and height andcreate a BufferedImage with the right dimensions. Then call createGraphics() on the BufferedImage and thencall drawImage() on the returned Graphics, passing it the java.awt.Image. Now you have a BufferedImagecontaining your image data. A BufferedImage is an instance of RenderedImage, so you can pass it to any JavaAdvanced Imaging interface that calls for a RenderedImage.

An example of creating an image from float data can be found here.

Back to Question Index

How do I create a PlanarImage from an array of data?The steps to do this are:

1. Construct a DataBuffer from your data array.

2. Construct a SampleModel describing the data layout.

3. Construct a Raster from the DataBuffer and SampleModel. You can use methods from the RasterFactoryclass to do this.

4. Construct a ColorModel which describes your data. The factory methodPlanarImage.createColorModel(sampleModel) will take care of this for some common cases.

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

9 de 26 29-09-2009 13:46

Page 10: Java Advanced Imaging API

5. Construct a TiledImage with the SampleModel and ColorModel.

6. Populate the TiledImage with your data by using the TiledImage.setData() method to copy your raster intothe TiledImage.

Only the last step involves any actual processing. The rest is just object creation.

Alternatively, a BufferedImage may be constructed directly from the Raster and ColorModel. TheRenderedImageAdapter class may then be used to produce a PlanarImage from the BufferedImage. Thisapproach avoids copying entirely.

Sample code to make a RenderedImage out of a 2D array of floats can be found here.

Back to Question Index

How do I convert images between color spaces?The Java 2 platform (JDK 1.2 and later) contains a Kodak color management engine which uses ICC profiles forconversion. You will need to provide the ICC profiles in a form from which you can create ajava.awt.color.ICC_Profile object. The ICC_Profile can then be used to create ajava.awt.color.ICC_Colorspace, which can be used to create a ColorModel that can be supplied to the JAI"colorconvert" operation. If you use the "colorconvert" operation in this manner, and the SampleModel of the sourceimage (and thus the resultant destination image) is not compatible with the ColorModel being specified to the"colorconvert" operation, then you should also provide an appropriate SampleModel in an ImageLayout objectpassed as a RenderingHint. The SampleModel should be compatible with the ColorModel provided.

ICC profiles for the following color spaces may be downloaded here.

CMYCMYKYCbCr based on REC 601YCbCr linear based on REC 601YCbCr based on REC 701YCbCr linear based on REC 709Linear Y part of YCbCr for Color Conversion Support

Back to Question Index

How do I convert any image (with any color model) to a 1 bit image (B&W)?Use one of the dither operators -- either OrderedDither (fast) or ErrorDiffusion (slower, but higher quality).First, convert the image to a luminance (grayscale) image and then dither it. You can convert to a grayscale spaceusing the ColorConvert operator:

pb = new ParameterBlock();pb.addSource(src);ColorModel cm = 

new ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_GRAY),                                                      new int[] {8},           false,                false,                Transparency.OPAQUE,                DataBuffer.TYPE_BYTE);pb.add(cm);PlanarImage dst = JAI.create("ColorConvert", pb);

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

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

10 de 26 29-09-2009 13:46

Page 11: Java Advanced Imaging API

zero and any values above half the range to one. The dither operation will automatically vary the threshold tominimize 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 applya threshold to the image. The "Binarize" operation may be used for this purpose. A threshold may be derived byfirst creating a Histogram using the "Histogram" operation and then calculating the threshold using one of severalmethods:

        getIterativeThreshold()        getMaxEntropyThreshold()        getMaxVarianceThreshold()        getMean()        getMinErrorThreshold()        getMinFuzzinessThreshold()        getModeThreshold()        getPTileThreshold()

This code example demonstrates how "binarize" operation can be used to apply the threshold.

Back to Question Index

How does the image coordinate system work?A RenderedImage occupies an arbitrary rectangular area in the 2D plane. Note that, as in the Java 2D API, the Yaxis values increase from top to bottom.

Consider this annoted image:

The coordinates of the upper-left corner of the image appears at the point given by the getMinX() and getMinY()methods. The width and height of the image are obtained similarly using the getWidth() and getHeight()methods. In the illustration, the image starts at pixel (-100, -90) and has a width of 330 pixels and height of 215pixels. The lower right pixel of the image is thus (229, 124). As shown here, the image location is not restricted tothe positive quadrant.

Overlayed on the image is its tile grid. Each tile contains a rectangular portion of the image; all tiles have the samewidth and height and tiles do not overlap. Tiles are referenced by a pair of indices, i.e., tile (2, 3) is to the right andbelow tile (1, 2). Tiles may extend past the edges of the image. The contents of the portion outside the image areundefined. Only tiles that have some overlap with the image bounds can be obtained by calling getTile. Attemptsto retrieve any other tiles will result in a return value of null.

The semantics of an image never depend on the layout of its tile grid layout, but performance maybe affected by

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

11 de 26 29-09-2009 13:46

Page 12: Java Advanced Imaging API

the choice of tile size and offsets. The tile grid is defined by the four methods getTileGridXOffset(),getTileGridYOffset(), getTileWidth(), and getTileHeight(). The first two methods yield the position of theupper-left corner of a notional tile (0, 0). The image need not actually contain such a tile. For example, the tile gridof 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 (getTileGridXOffset(), getTileGridYOffset()) doesnot even fall within the image. Both images should act exactly identically when used as a source for all JAIoperations 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 lowerright pixels of the image. To determine the tile index of a given point, the following methods (available in thePlanarImage class) may be used:

static int XToTileX(int x,                    int tileGridXOffset,                    int tileWidth) {    x -= tileGridXOffset;    if (x < 0) {        // Force round to -infinity        x += 1 - tileWidth;    }    return x/tileWidth;}

static int YToTileY(int y,                    int tileGridYOffset,                    int tileHeight) {    y -= tileGridYOffset;    if (y < 0) {        // Force round to -infinity        y += 1 - tileHeight;    }    return y/tileHeight;}

It is not sufficent to compute (x - tileGridXOffset)/tileWidth since this will produce the wrong result fornegative indices. Instead, it is necessary to compute the equivalent of (int)Math.floor((double)(x -tileGridXOffset)/tileWidth). 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 allequal to zero. As operations are performed, however, such as scaling, rotation or translation, the coordinates of

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

12 de 26 29-09-2009 13:46

Page 13: Java Advanced Imaging API

the resultant images will change.

On a more microscopic level, pixels in a RenderedImage may be thought of as squares with a 1 x 1 extentcentered at (x + 0.5, y + 0.5). Geometric mapping operations may need to take this half pixel shift into account.

Unlike the RenderedImage coordinate system, which is discrete, the RenderableImage coordinate system iscontinuous. The image dimensions are described in terms of floating-point miniumum X and Y coordinates, aheight, and an aspect ratio. For the "renderable" operation, you supply the height in the renderable coordinatespace 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 RenderableImage is rendered, an AffineTransform is applied to map its coordinate system into therendered pixel coordinate system which is appropriate to a target device such as a display, printer, file, etc. Youhave to specify the appropriate transformation.

Back to Question Index

How are regions of interest (ROIs) used?At this time ROIs are used in Java Advanced Imaging for three purposes:

To delimit the area of data to be initialized in the TiledImage set() and setData() methods.To specify the region to be considered in calculating image statistics such as mean, extrema, and histogram.As meta-data which are associated with images via properties.

In the latter case ROIs may be geometrically transformed or "shrunk" by operators in an image chain but otherwiseare ignored (this geometric modification of the ROI occurs in parallel with the actual image processing operations).In no case other than the statistics operations does the presence of a ROI affect the operation per se.

One way that you might be able to subtract regions in two images defined by a ROI is as follows:

Set up an image chain to calculate the overall difference image.Intersect the two ROIs.Determine the bounding box of the intersection.Create a TiledImage covering the area of the bounding box.Extract from the difference image a Raster of data over the bounding box.Use setData(Raster,ROI) with the Raster of the previous step and the bounding box to set the data of theTiledImage.

Note that the only tiles which will be calculated in the difference image are those which overlap the bounding boxof the intersection of the two ROIs. Thus if you are using tiled source and destination images computation will beminimized.

Back to Question Index

How can I tell when a Java Advanced Imaging operator is complete?Normally, the deferred execution model makes the notion of "completing" the computation of an imagemeaningless. Images are computed a tile at a time, and tiles may be computed multiple times if the tile cache isunable to reserve storage for them. However, in some cases such as perfomance benchmarking you may wish toforce an image to be computed in its entirety.JAI.create() is a convenience method which effectively does the following:

Validates the sources and parameters of the operations according to the specification of the associatedOperationDescriptor.Inserts a RenderedOp node into the imaging chain.

No actual computation of image data will occur until data is requested from a node in the chain unless theisImmediate() method of the associated OperationDescriptor returns true. In this case, the chain will beevaluated as soon as the node is appended to the chain. Otherwise, you can force a chain to be evaluated up to agiven node by invoking getRendering() on the RenderedOp of that node. This will force evaluation of the entire

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

13 de 26 29-09-2009 13:46

Page 14: Java Advanced Imaging API

chain up to and including that node.

Even at this point, actual tile data will not necessarily have been computed. A loop such as the following may beused to force actual tile computation:

void forceLoad(RenderedImage im) {    int minX = im.getMinTileX();    int minY = im.getMinTileY();    int maxX = minX + im.getNumXTiles();    int maxY = minY + im.getNumYTiles();

    for (int j = minY; j < maxY; j++) {        for (int i = minX; i < maxX; i++) {            im.getTile(i, j);        }    }}

Note that if you wish to measure the execution time of a given node you will need to force computation on itssource nodes first to exclude their evaluation time from the measurement. The tile caching should also bedisabled.

Back to Question Index

How do I create an overlay?As indicated in the specification of the "overlay" operator, it puts one RenderedImage on top of anotherRenderedImage. To use this operator, two source RenderedImages are needed; call them src1 and src2. Then tocreate an "overlay" op, you simply do:

RenderedImage dst =    JAI.create("overlay", src1, src2);

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 throwan IllegalArgumentException.

The position of src2 is based on its minimum X and Y. If you wish to move src2 to a different location, you mustdo 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 hasthe dimensions of src1). To increase the dimensions of an image, the "border" operation may be used.

Back to Question Index

How do I convert an image with 10 or 12 bit color to 8 bit color?The most direct approach is to use the "lookup" operator to map your 10 or 12 bit data to 8-bit values. If you justwant to do simple range conversion, then, for 12 bit data the lookup table's data can be created by:

byte[] blut = new byte[4096];for (int i=0; i < 4096; i++) {    blut[i] = (byte)(i >> 4);}

A refinement of this is to apply a linear "contrast stretch" (really a brightness adjustment) by mapping the min andmax values in the 12 bit image to 0 and 255 in the 8 bit image. (Note that we're cheating here and stuffing valueswe're interpreting as unsigned into Java's signed byte type).

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

14 de 26 29-09-2009 13:46

Page 15: Java Advanced Imaging API

You can determine the min/max using Extrema operator. You will normally want to choose the min of all bands asthe minimum, and likewise for the max. Doing it band by band will cause color shifts. Of course, if the imagery isfalse color, you may not care.

You then create the table by:

double scale = 255.0/(float)(max-min);for (int i = min; i <= max; i++) {   blut[i] = (byte)((i - min)*scale);}

// Clamp any input values outside// min/max range, just in casefor (int i = 0; i < min; i++) {   blut[i] = 0;}

for (int i = max; i < 4096; i++) {    blut[i] = (byte)255;}

You may find that these approaches sacrifice too much detail at the low radiance end of the scale. Frequently anon-linear transformation is needed, usually somewhere between square-root and cube-root.

for (int i = 0; i < 4096; i++) {    double f = i*(1.0/4095.0);    // Take the square root    f = Math.pow(f, 0.5);    // Scale to 8 bits and round    blut[i] = (byte)(f*255.0 + 0.5);}

Back to Question Index

How do I handle palette-color images?This type of image, e.g., one derived from a TIFF palette-color file, will have a ColorModel that is an instance ofIndexColorModel. In general, if the ColorModel of the source image is an IndexColorModel but that of thedestination is not, then the source image is temporarily "expanded" during processing to the number of bandsindicated by the IndexColorModel (which is the same as the number returned byOpImage.getExpandedNumBands()).

The destination ColorModel is either specified by an ImageLayout object passed in via the RenderingHintsparameter to JAI.create() or it is derived from the SampleModel of the (first) source image: a "best guess"ColorModel is constructed for the destination by passing the source SampleModel toPlanarImage.createColorModel(). If source data are not expanded, it is assumed that the operation in questionwill apply any special handling needed when it encounters an IndexColorModel case. If it does not speciallyhandle such a case then the raster data will be treated as grayscale (note that if a ColorModel is specified via theRenderingHints it is incumbent on the user to ensure that it will be compatible with the destination SampleModel).

Some operations perform processing on the colormap, effectively changing the colormap and not performing anypixel manipulation. This behavior is accomplished by the operations being subclasses ofjavax.media.jai.ColormapOpImage. The operations which are implemented as subclasses of ColormapOpImageare "addConst", "andConst", "divideIntoConst", "exp", "invert", "log", "lookup", "multiplyConst", "not", "orConst","piecewise", "rescale", "subtractFromConst", "threshold" and "xorConst".

As of JAI 1.1.2, a new RenderingHint JAI.KEY_TRANSFORM_ON_COLORMAP specifies whether processing shouldtake place on the colormap, or on the pixel (index) data for those operations that are implemented as subclasses

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

15 de 26 29-09-2009 13:46

Page 16: Java Advanced Imaging API

of javax.media.jai.ColormapOpImage. By default, a ColormapOpImage node has a hint with a value ofBoolean.TRUE, which means the processing is done on the colormap, and not on the indices. To suppress thisbehavior, a hint with a value of Boolean.FALSE should be attached to the node.

Other operations, like "translate" (with integral translation factors) and "crop" operations do not actually perform anyprocessing of the data: they effectively forward tile requests on to the source image.

As of JAI 1.1.2, a new RenderingHint JAI.KEY_REPLACE_INDEX_COLOR_MODEL has been provided that allows forautomatic color translation for colormapped imagery in those situations where not doing so would result inunexpected / incorrect results (such as geometric operations). Operations that are implemented as subclasses ofjavax.media.jai.AreaOpImage and javax.media.jai.GeometricOpImage set this RenderingHint to true, suchthat these operations are performed correctly on the colormapped imagery, not treating the indices into the colormap as pixel data. These operations are listed in the The Java Advanced Imaging 1.1.2 README

One of the common uses of the format operator is to cast the pixel values of an image to a given data type. Insuch a case, since JAI 1.1.2, the format operation adds a RenderingHints object forJAI.KEY_REPLACE_INDEX_COLOR_MODEL with the value of Boolean.TRUE, if the source image provided has anIndexColorModel. Due to the addition of this new RenderingHint, using the "format" operation with source(s) thathave an IndexColorModel will cause the destination to have an expanded non-IndexColorModel ColorModel.This expansion ensures that the conversion to a different data type, ColorModel or SampleModel happenscorrectly such that the indices into the color map (for IndexColorModel images) are not treated as pixel data.

One further thing to note is that even if you pass in an IndexColorModel via the RenderingHints this will notchange the way in which the image data per se are handled, although you might be able to display the result. Forthose operations that are not subclasses of ColormapOpImage, or where color translation is not being performedthrough the use of JAI.KEY_REPLACE_INDEX_COLOR_MODEL, the image data will still be processed as if theyrepresent grayscale data.

Sometimes it might be useful to convert the palette-color images into RGB images at the beginning of theprocessing. One way to expand the palette-color images is by inserting a "format" operation which changes theColorModel, thereby forcing expansion. (Note that as mentioned "crop" and integral translation merely forward thetile requests to the source so you can't expand the data via those operations.) Obviously expanding thepalette-color data to RGB will increase the memory footprint but this way you are assured of obtaining a validresult.

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 IndexColorModel; the method getMapSize() should tell you the number of elements in the lookuptable. This code example shows how to perform the conversion.

Back to Question Index

How does Java Advanced Imaging API handle image borders?Java Advanced Imaging API's "border" operation and BorderExtender classes are capable of extending an imageoutward for a specified number of pixels in various ways. This is used mainly for geometric operations whereinterpolation is needed.

To display an image with a decorative border, the Swing toolkit supports several kinds of borders injavax.swing.border package. For some applications, you may want to use an IconJAI (found in the sampledirectory) to display the image, then add a Swing border to it.

The Java Advanced Imaging API does not have a "drop shadow" or similar special effect operator as found insome imaging software. Such an effect could be created by overlaying an image over a modified version of itselfto produce a 3D look.

Back to Question Index

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

16 de 26 29-09-2009 13:46

Page 17: Java Advanced Imaging API

How do I convert an IndexColorModel into a grayscale image?A method to convert an CS_sRGB into a grayscale Image (CS_GRAY) can be found here.

Back to Question Index

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 youcan use the "convolve" operation as is. If however you would like to convolve each band of a multi-band imagewith a different kernel then you would need to extract each band, e.g., using "bandselect", apply the appropriateconvolution kernel to each band using "convolve", and then merge the separate filtered bands into a resultantmulti-band image.If you are attempting to do some sort of multispectral template matching however, the above scenario might notbe what you want. In that case, you could use single-band convolution by, for example, first converting the imagesto a different color space such as HIS or YCC and perform the template matching using the intensity or luminanceband.

Back to Question Index

Can I serialize a TiledImage?A TiledImage may not be serialized directly as it does not implement the java.io.Serializable interface. Youmay however construct a SerializableRenderedImage from a TiledImage. See thejavax.media.jai.remote.SerializableRenderedImage documentation for more information. Alternatively, if asuitable external file format exists the ImageCodec interfaces may be useful.

Back to Question Index

How can I create and run an Applet?In order to use Java Advanced Imaging in a browser environment, your applet HTML file should be converted withthe Java Plug-in HTMLConverter (now sits in the JDK 1.3.1 and JDK 1.4 bin directories). The Java Plug-in (nowpart of JRE/JDK 1.3.1 and 1.4) and JAI configuration requirements are as follows:

Install the Java Plugin for your architecture (Solaris, Windows, etc.). The Java Plug-in is available from theJava Plug-in download page. The Plug-in is now part of the JRE. Follow the links to download the plugins andpatches for the platform of your choice. There are also pointers to a FAQ, Documentation and other relevantinformation at this site.

Follow the Java Plug-in Browser Registration Instructions for the platform of your choice

Solaris Browser Registration InstructionsLinux Browser Registration InstructionsWindows Browser Registration Instructions. Look for the section on running Netscape 7.x/Mozilla 1.xwith Java Plug-in.

Once the Java Plug-in is registered with the browser, download the JAI JRE installation executableOn Solaris: jai-1_1_2_01-lib-solaris-sparc-jre.binOn Linux: jai-1_1_2_01-lib-linux-i586-jre.binOn 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

Java policy file

$JREHOME/lib/security/java.policy

Or user java policy file

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

17 de 26 29-09-2009 13:46

Page 18: Java Advanced Imaging API

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:

grant {  // Necessary for JAI to utilize mediaLib in applets.  permission java.io.FilePermission "/usr/bin/uname", "execute";  // May be necessary for JAI to do encoding in applets.  permission java.io.FilePermission "${java.io.tmpdir}/*", "write, delete";};

On Windows:

grant {  // May be necessary for JAI to do encoding in applets.  permission java.io.FilePermission "${java.io.tmpdir}/*", "write, delete";};

If the users encode images in the applet, the applet may write to some temporary file. If the users don'tencode images in the applet, no permission is needed on Windows. As mentioned above, on Solaris, the userstill 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.

An example html file to run the applet is here.

Applets can also utilize the Auto Installation capabilities provided by Java Plugin (JPI) including Java extensiondeployment to facilitate applet deployment. For details please refer to the The Java Advanced Imaging InstallationInstructions.

Back to Question Index

Where can I find an example of how to write a custom operator?Let's say I want to create a new operator called the 2D Fourier Transform operator.Operations which are to be created using JAI.create() must be registered with the default OperationRegistry. Theycan also be automatically detected and registered by listing it in a registry file (META-INF/registryFile.jai) which isoften contained in a jar file with the user's other class files (see the javadoc for OperationRegistry andOperationRegistrySpi classes for more information). Each operation has an OperationDescriptor (denoted"descriptor" in the registry file) which provides a textual description of the operation and specifies the number andtype of its sources and parameters. The OperationDescriptor also specifies the supported operation modes("rendered", "renderable", "collection" etc.). Rendered and renderable mode correspond to resolution-dependent andresolution-independent operations, respectively. For more information on these concepts please refer to the JavaAdvanced Imaging Programmer's Guide available via the Java Advanced Imaging home page.

For each OperationDescriptor there should also be at least one of either a RenderedImageFactory (RIF) orContextualRenderedImageFactory (CRIF). The RIF is for rendered mode operations only; the CRIF can handleoperations which function only in renderable mode or in both rendered and renderable modes. The RIFs and CRIFshave entries in the registry file denoted "rendered" and "renderable", respectively. Preferences for RIFs may also beset in the registry file.

In most of the reference port operation implementations there is also eventually an implementation class which is adescendent of OpImage. For example, it may be a subclass of PointOpImage, AreaOpImage, etc., as appropriate.

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

18 de 26 29-09-2009 13:46

Page 19: Java Advanced Imaging API

The RIF or CRIF is responsible for creating an instance of this class. It is possible for a RIF to instantiate differentimplementation classes depending on the types of the sources and parameters. It is also possible for multiple RIFsto instantiate the same implementation class (e.g., "rotate" and "affine" operators might share a commonimplementation). A RIF may even instantiate a chain of several connected objects.

What happens when JAI.create() is invoked is as follows:

The OperationDescriptor for the operation in question will be retrieved from the registry.1.

The source(s) and parameter(s) will be checked for compatibility with the operation as defined by theOperationDescriptor.

2.

A RenderedOp is created for the given operation. The RenderedOp contains the name of the operation, thesources and parameters and any rendering hints, but no actual image data until it is rendered as the result of acall to methods such as getWidth, getData or getTile.

3.

When the RenderedOp is eventually rendered, the following occurs:

The registry create() method is called using the information stored in the RenderedOp.1.

The registry creates a list of RIFs for this operation in the preferred order and invokes the create method ofeach RIF in sequence; the first non-null returned value is the result of the operation.

2.

When the create method of a RIF is invoked it is responsible for returning an instance of RenderedImage(usually an OpImage subclass) created for this operation.

3.

A similar sequence of events occurs for renderable mode operations using JAI.createRenderable().

In summary, to create a new operation you need to do the following:

Create an OpImage subclass for your operation.1.Create a RIF or CRIF as appropriate.2.Create an OperationDescriptor.3.Register your operation descriptor, RIF/CRIF, and preferences if appropriate with the OperationRegistry.4.

It is recommended that the user create a META-INF/registryFile.jai (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 modeand preferences if any. To avoid the hassles involved in creating a separate registryFile.jai file, it is possible toregister OperationDescriptors and RIFs/CRIFs, using the OperationRegistry's registerOperationDescriptorand registerRIF/registerCRIF methods. After this registering (and setting of preferences, if desired), the newoperation can then be invoked through JAI.create(). Of course, the drawback of this is that the new operator willnot be automatically reloaded every time a Java Advanced Imaging program is executed, since it is not present inregistryFile.jai. So, in order to use it, the registry methods would always have to be invoked beforehand.

An example of how to use the OperationRegistry's methods to register a descriptor and it's image factories :

    public static void init() {OperationRegistry    or =

JAI.getDefaultInstance().getOperationRegistry();

// An OperationDescriptor describing the "fourier" transform// operatorOperationDescriptor  fd = new FourierDescriptor();

// A RenderedImageFactory which could presumably create

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

19 de 26 29-09-2009 13:46

Page 20: Java Advanced Imaging API

// FourierOpImage'sRenderedImageFactory rifJava = new FourierRIF();

// A RenderedImageFactory which could create a// NativeFourierOpImage which used a native implementation// of the fourier transform.RenderedImageFactory rifNative = new NativeFourierRIF();

// First register the "fourier" OperationDescriptoror.registerDescriptor(fd);

// Now register the two RenderedImageFactory-s for this operatorRIFRegistry.register(or, fd.getName(), "com.xxx.yyy", rifJava);RIFRegistry.register(or, fd.getName(), "com.xxx.yyy", rifNative);

// Now set a preference such that the Native implementation// is preferred over the java implementationRIFRegistry.setPreference(or, fd.getName(),

    "com.xxx.yyy", rifNative, rifJava);    }

Aids to writing your own codec can be found in the Programmer's Guide, section 14.5 and the PNM code suppliedwith the sample demo.

Back to Question Index

Bugs/Issues

Why is my application crashing?If you encounter JVM crashes or exceptions that you believe are not the fault of your code, please send adescription of the problem and any available program output to [email protected] Please specify yourhardware configuration and JVM version (as reported by java -version). If you are sending in a stack trace from anexception, please run Java with the -Djava.compiler=none flag so that line numbers appear in the stack traceoutput.

Back to Question Index

Platform

What platforms are supported?The Java Advanced Imaging API should run on the Java 2 Platform, Standard Edition version 1.3 and higher. TheJava 2 Platform is available for Win32, Solaris, Linux, IBM-AIX, Mac OS X and Digital Unix.However, Java Advanced Imaging has only been tested on Win32, Solaris, and Linux (Red Hat 6.1 JVM) Java 2platforms. Please check the Java 2 Website for the latest porting information. Native performance enhancements forthe Java Advanced Imaging API are currently available for Windows, Solaris and Linux. Java Advanced Imagingshould work without native performance enhancements for other platforms, however this usage is unsupported.

Back to Question Index

Does Java Advanced Imaging run on my Macintosh?Yes - Apple supports Java Advanced Imaging on the Mac. For details and downloads, please visit Java 3D and JavaAdvanced Imaging Update.

Back to Question Index

When will Java Advanced Imaging be available for Linux?The Java Advanced Imaging API implementation is now available for Linux. It can be downloaded fromhttp://java.sun.com/products/javamedia/jai/downloads/download.html

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

20 de 26 29-09-2009 13:46

Page 21: Java Advanced Imaging API

Back to Question Index

Is there code which accelerates the image operators on some platforms?A C library is supplied for sparc, linux and intel which accelerates most of the operators. In addition there is a lowerlevel sparc library and an MMX enabled library allowing additional hardware acceleration for many operators. If JavaAdvanced Imaging code does not find these libraries, pure java code is used.

Back to Question Index

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 (readonly), 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 aseparate Java Image File I/O package. For more information on Image I/O in JAI please refer to Image I/O in JavaAdvanced Imaging.

The two file formats which support short integer (16-bit) data in the file I/O package supplied with Java AdvancedImaging 1.1.2_01 are Portable Network Graphics (PNG) and TIFF. There is support in the codec APIs for readingmulti-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 codecsoperate in the rendered mode only. You can do a JAI.create("fileload", ...) followed by aJAI.createRenderable("renderable", ...) to get a renderable source based on an image file.

Limitations of the TIFF codec in 1.1.2_01:

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 imageuntil such time as their geometric region is needed to complete processing of the chain for which they are thedata source. If tiles have been previously loaded but have since been flushed from the cache then they will ofcourse need to be reloaded.

BMP

The Windows 95 version of BMP is supported. The bit depth of the output when saving a BMP will bedetermined 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 newimplementation 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 thetype of the image being saved, not by the choice of PNGEncodeParam subclass.

JPEG

The JPEG support is currently implemented on top of the unofficial JDK classes in thecom.sun.image.codec.jpeg package, which may not exist in all Java 2 environments.

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

21 de 26 29-09-2009 13:46

Page 22: Java Advanced Imaging API

FlashPix

FlashPIX reading is only partially implemented. There is no FlashPIX writer. Tiles of FlashPIX images are readonly when required.

The Java Advanced Imaging API includes an extention interface allowing third parties to provide their favorite fileformat handling. Some of the file formats which have been requested and which we encourage third parties toprovide are FITS, NITF, DICOM, EPS, RDF, or other vector formats.

Back to Question Index

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

Back to Question Index

How do I load an image into Java Advanced Imaging?The easiest way to load a local image file stored in TIFF or any other supported image file format is to use the"fileload" operation as follows:

String fileName; // Path of the file to be readPlanarImage image =    JAI.create("fileload", fileName);

Or, using getAsBufferedImage to produce a BufferedImage:

URL url; // URL of image to be readPlanarImage pi = JAI.create("URL", url);BufferedImage bi = pi.getAsBufferedImage();

Back to Question Index

How can I load a page of a multi-page TIFF file?A code sample is included here to show one method of loading a page of a multi-page TIFF file. Within the JAI API a"page" parameter was added to the "TIFF" operator to simplify this procedure.

Back to Question Index

How do I save an image as a TIFF (or: BMP, JPEG, PNG, ...)?Use the "filestore" operator:

RenderedOp op = JAI.create("filestore", image, filename, filetype, encodeParam);

Back to Question Index

Why can't I delete a file that I read in using the "FileLoad" operator?The "FileLoad" operator is merely a wrapper for what is effected by the "Stream" operator. While the "FileLoad"operator saves the user having to create the stream, it has a side effect. This is that the stream has to have areference that is held by the "FileLoad" operator as long as there is a possibility that the data might be read. Onlywhen data will no longer be read, can the stream be released. This means that as long as the stream is held the filewill be locked. It is this locking of the file that prevents the file from being deleted, till the reference to the stream isreleased. Since the reference to the stream will be held until the internal objects created by the "FileLoad" operatorare garbage-collected, the two options to allow the file to be deleted are:

Ensuring that all references to the "FileLoad" operation result are nullified and then invoking the garbagecollector.Using the "Stream" operator instead of the "FileLoad" and having the application manage the stream closing.

It should be noted, if using the first option listed above, that since there are no requirements on the Java VM forwhen it actually releases objects no longer referenced, there's no guarantee that invoking the garbage collector willactually cause the objects to be garbage-collected. Thus the second option listed above is the better method.

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

22 de 26 29-09-2009 13:46

Page 23: Java Advanced Imaging API

Back to Question Index

How can I store float data?Currently the only supported image format which possesses the ability to store float data at all is TIFF. Thecapability of writing out float data to a TIFF format has been added in Java Advanced Imaging 1.1.

Back to Question Index

Is there any way to know the extent of an image before loading the complete file?Depending on the particular codec, invoking the getWidth() and getHeight() methods on the RenderedImagereturned by ImageDecoder.decodeAsRenderedImage() may or may not cause the image data per se to be read fromthe file. For TIFF and FlashPix images, actual reading of the image data from the file is deferred until a request fordata is actually made by invoking the getData() or getTile() methods.

Back to Question Index

I wrote a PNG image with transparency but it looks opaque in my browser.Many popular browsers do not support PNG transparency correctly. The PNG Home Site lists the current status ofmany popular browsers here.

Back to Question Index

How come Java Advanced Imaging can't read one of my image files?Many image file format specifications have areas that are capable of varying interpretations, and interoperabilitybetween image readers and writers is not always perfect. If you find an image in a supported format that cannot beread by the Java Advanced Imaging API (or an image written by Java Advanced Imaging that cannot be read byother programs), we encourage you to send us the image along with any available information about other programsthat can and cannot read it. Although future work on image I/O will be done under a separate framework, we are stillcommitted to fixing bugs in the existing implementation.

Back to Question Index

Why won't a remote operation load my image file?If you are using Java Advanced Imaging's remote imaging classes:When passed to the server, the file path must be an absolute path to the file in question, which must be visible fromthe server. A single name will always fail as the server has no way to know on which machine or in which directory("folder") the file in question resides.

Back to Question Index

Why doesn't Java Advanced Imaging support my favorite file format?Most file I/O enhancements will be made in the context of the image I/O standard extension. The exact nature ofthese enhancements is yet to be determined. Please refer to the JSR for more information.

Back to Question Index

How can I save space when using the BMP format?24 bit BMP images tend to be large since they are not compressed, and an R, G and B triplet has to be stored foreach pixel. If the objective is to store the image in a lesser amount of space, a simple way of doing this would be toconvert the BMP image to a format that inherently supports compression, like JPEG. Here is a piece of code youcan use to convert BMP images to JPEG images:

// Load the input image.String inputFile = "image.bmp";RenderedOp src = JAI.create("fileload", inputFile);

// Store it as a JPEGString outputFile = "image.jpg";JAI.create("filestore", src, outputFile, "jpeg",           (ImageEncodeParam)null);

If the objective is to actually reduce the number of colors in the image and then store it as a BMP, the following

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

23 de 26 29-09-2009 13:46

Page 24: Java Advanced Imaging API

sequence of steps could be followed:

Choose the 16 colors that will be used as the color palette for the output and dither the 24 bit image down to 4bits per channel.

1.

Re-format this 4 bit image, so that the palette is stored in an associated IndexColorModel and the data isstored 2 pixels packed per byte (using a MultiPixelPackedSampleModel)

2.

Write this re-formatted image as a BMP using the "filestore" operator.3.

Back to Question Index

How can I save the data displayed on a Canvas in a file?There is a new class in the Java 2 Platform Standard Edition version 1.3 called java.awt.Robot that allows directscreen capture. Also, if the image is drawn into a Swing component, its print method can be used to capture theimage.

Another approach is to create an AWT image and call the same application paint method to draw into it.

Next, convert the AWTImage to a PlanarImage:

ParameterBlock pb = new ParameterBlock();pb.add(tAWTImage);PlanarImage tPlanarImage =    (PlanarImage) JAI.create("awtImage", pb );

Then, write out the PlanarImage (for example, in BMP format):

OutputStream tOutput =    new FileOutputStream(tFilename);ImageEncoder tEncoder =    ImageCodec.createImageEncoder("BMP",                                  tOutput,                                  null);tEncoder.encode(tPlanarImage);tOutput.close();

Back to Question Index

Why don't certain operations with GIF source images function correctly?As of JAI 1.1.1, the GIF decoder produces an image which has an IndexColorModel instead of aComponentColorModel as was previously the case. This may provoke strange discrepancies in applications whichhave made assumptions about the nature of image ColorModels. Such applications might need to add anImageLayout containing a ComponentColorModel to the RenderingHints of certain operations or perhaps simplyconvert all IndexColorModel images to 3-band RGB images when they are loaded.As of JAI 1.1.2, applications may no longer need to add an ImageLayout containing a ComponentColorModel to theRenderingHints of certain operations or to convert all IndexColorModel images to 3-band RGB images when they areloaded. While the GIF decoder still produces an image which has an IndexColorModel, those operations that wouldproduce an incorrect result when operating on a source with an IndexColorModel use theJAI.KEY_REPLACE_INDEX_COLOR_MODEL RenderingHint (as of JAI 1.1.2) to cause the resultant image to havea non-IndexColorModel, and do the processing on the color translated pixels, as opposed to performing theoperations on the indices into the colormap. A detailed discussion of these issues can be found here.

Back to Question Index

Additional Code Samples

Add a transparency mask (alpha channel) to an image.This code example expects two command line arguments which are the paths to a three-band and a one-band byte

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

24 de 26 29-09-2009 13:46

Page 25: Java Advanced Imaging API

image, respectively, with the same width and height and stored in a supported format.

Back to Question Index

Scale an image or image region.A method used to scale image or image region can be found here.

Back to Question Index

Retile an image.Sample code which will work for all the supported image types may be found here.

Most operators allow tile layout to be specified via the ImageLayout hint. One may retile an image, in the nextoperator this image is used as a source by specifying a new tileWidth/tileHeight. If you don't want to perform anyoperations on the image, you can always use the reformat operator, with the same data type.

You can also use the freely available utility "tiffcp" (part of the libtiff distribution) to retile TIFF images. This workswell with Java Advanced Imaging. tiffcp is also a bit more tolerant of images with "bad" headers than Java AdvancedImaging and you can use it on a TIFF image that Java Advanced Imaging can't read in order to clean it up. You canget libtiff here.

The utility "tiffsplit" is also in the libtiff distribution. This program splits a multi-image TIFF into single-image TIFFs.

Back to Question Index

Choose an image with a file dialog and load it into a ScrollingImagePanel.See the code sample.

Back to Question Index

Convolve an image.A simple convolution example is here.

A example of a float image with a float kernel, converted to a PlanarImage for display may be found here.

Back to Question Index

Combine multiple separate images into one multibanded image.Use the "BandMerge" operation. An alternative is given by this code example.

Back to Question Index

Load an image, do something to every pixel, and display the result.Sample code can be found here.

Back to Question Index

Place one smaller image within a larger template image into a pre-defined area.In the following, assume that you already have two RenderedImages named bg and fg where the latter will be insetin the former. Then you could try something like this:

RenderedImage bg; // background imageRenderedImage fg; // foreground (inset) image

TiledImage ti =   new TiledImage(bg.getMinX(),                  bg.getMinY(),                  bg.getWidth(),                  bg.getHeight(),                  bg.getTileGridXOffset(),                  bg.getTileGridYOffset(),                  bg.getSampleModel(),

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

25 de 26 29-09-2009 13:46

Page 26: Java Advanced Imaging API

                  bg.getColorModel());ti.set(bg);

Rectangle r =    new Rectangle(fg.getMinX(),                  fg.getMinY(),                  fg.getWidth(),                  fg.getHeight());ROI roi = new ROIShape(r);ti.setData(fg.getData(), roi);

The preceding snippet assumes that the images fg and bg have compatible SampleModels and that the min X and Yof these images are set to give the correct relative positions. The translate operation can be used to set the min Xand Y of the images to the correct relative positions. The TiledImage ti should contain the desired result.

Back to Question Index

Display a collection of images.

public void display(Collection imgs) {    Frame window = new Frame(testName);    int n = imgs.size();    window.setLayout(new GridLayout(1, n));

    Iterator iter = imgs.iterator();    while (iter.hasNext()) {        RenderedImage img =            (RenderedImage)iter.next();        int w = img.getWidth();        int h = img.getHeight();        ScrollingImagePanel panel =            new ScrollingImagePanel(img, w, h);        window.add(panel);    }

    window.pack();    window.show();}

This assumes that the Collection object contains a number of RenderedImages. Of course you can a use differentlayout for the Frame. If you want to display images in separate windows, just create a new Frame for each image andput the panel in there.

copyright © Sun Microsystems, Inc

Java[tm] Advanced Imaging API http://java.sun.com/jsp_utils/PrintPage.jsp?url=htt...

26 de 26 29-09-2009 13:46