- Applying Rendering Hints
- Managing Memory
- Scheduling Tiles
- Reformatting an Image
- Extending the Border
- A Rendering Example
- A Closer Look at the PlanarImage Class
- Using the RenderedOp Class
- Working with Tiles
- A Tiled-Image Viewer
- Writing to Pixels
- Creating an Aggregate Image
- A JAI Image Browser
- The Renderable Layer
- Conclusion
Creating an Aggregate Image
Often it is necessary to create a single image from a set of images. You can use the TiledImage class to do this. As mentioned earlier, you can populate a TiledImage object in two different ways:
Drawing over its graphical context
Writing to tiles
Let's explore the first approach. This approach may not be very accurate, but it serves the purpose in most cases. The idea here is to first construct a skeleton tiled image as big as the target image, and then draw images from the set one by one, each time translating and scaling the image appropriately. Listing 11.9 shows the relevant code.
LISTING 11.9 A method that aggregates images
public static TiledImage aggregateImages(PlanarImage[] imageset, Dimension celldim, int cols, int rows) { int imWid = cols*celldim.width; int imHt = rows*celldim.height; PlanarImage img = imageset[0]; TiledImage ti = new TiledImage(0,0,(int)imWid,(int)(imHt), 0,0, img.getSampleModel(), img.getColorModel()); Graphics2D tg2d = ti.createGraphics(); int x = 0; int y=0; for(int i=0; i< rows; i++) { for(int j=0;j<cols; j++) { if(i*cols+j >= imageset.length) break; img = imageset[i*cols+j]; if(img != null){ double magx = celldim.width/(double)img.getWidth() ; double magy = celldim.height/(double)img.getHeight() ; AffineTransform atx = new AffineTransform(); atx.setToTranslation((double)x,(double)y); atx.scale(magx, magy); tg2d.drawRenderedImage(img,atx); x += celldim.width; } } x =0; y += celldim.height; } return ti; }
The aggregateImages() method takes an array of planar images and converts it into a single planar image. It also has parameters to determine the size and layout of the target image. The cellDim parameter represents the size of an image to be drawn, which is assumed to be the same for all images. The rows and cols parameters specify how the input images are to be laid outthat is, in a rows-by-columns grid. It is expected that rows 3 cols = imageset.length.
This method assumes that all the images in imageset have the same sample model and color model. So it gets these parameters from the first image and then creates a skeleton tiled image. It then gets a Graphics2D context from this TiledImage object.
The next step is to draw the images from the imageset array one by one. There are two for loops, which create a single image by drawing the input images in a grid. Each time, the image is translated and then scaled so that the images fit closely. If you need a gap between the images, add the border to each image before passing to this method (see the section titled Using the Border Operator earlier in this chapter).
NOTE
The source code for the JAI image browser application is available on the book's Web page in the directory src/chapter11/imagebrowser.