| CompositeExample.java |
/*
* Example of using the Java Advanced Imaging library to composite two
* images that are the same size.
*
* Written by Sean R. Owens, sean at guild dot net, released to the
* public domain. Share and enjoy. Since some people argue that it is
* impossible to release software to the public domain, you are also free
* to use this code under any version of the GPL, LPGL, or BSD licenses,
* or contact me for use of another license.
* http://darksleep.com/player
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.renderable.ParameterBlock;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import javax.media.jai.operator.CompositeDescriptor;
/**
*
* @author Sean Owens
*/
public class CompositeExample {
final static private int IMG_WIDTH = 1024;
final static private int IMG_HEIGHT = 1024;
final static private int BLOCK_WIDTH = 400;
final static private int BLOCK_HEIGHT = 200;
public BufferedImage createImage(String filename, int x, int y, Color foreColor, Color backColor) {
BufferedImage image = null;
image = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = image.createGraphics();
g2.setColor(backColor);
g2.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);
g2.setColor(foreColor);
g2.fillRect(x, y, BLOCK_WIDTH, BLOCK_HEIGHT);
g2.dispose();
return image;
}
// Note that when you run this with the images generated by this code, there is an alpha
// channel on each image and the 'background' color of the foreground image has a 0 alpha
// channel, otherwise the 'background' on the foreground image will entirely overwrite the
// background image.
public RenderedOp composite(String backFilename, String foreFilename) {
// First let's load both the foreground and background images from file
RenderedOp backImage = JAI.create("fileload", backFilename);
RenderedOp foreImage = JAI.create("fileload", foreFilename);
// Now for each image we need to get the RGB layers, and the Alpha layer.
//
// Note that there is some redundancy in the code below, we could easily
// refactor these into methods but in the interest of clarity we'll
// leave it in.
int[] bands;
ParameterBlock params;
bands = new int[]{0, 1, 2};
params = new ParameterBlock();
params.addSource(backImage);
params.add(bands);
RenderedOp backRGB = JAI.create("bandSelect", params);
bands = new int[]{3};
params = new ParameterBlock();
params.addSource(backImage);
params.add(bands);
RenderedOp backAlpha = JAI.create("bandSelect", params);
bands = new int[]{0, 1, 2};
params = new ParameterBlock();
params.addSource(foreImage);
params.add(bands);
RenderedOp foreRGB = JAI.create("bandSelect", params);
bands = new int[]{3};
params = new ParameterBlock();
params.addSource(foreImage);
params.add(bands);
RenderedOp foreAlpha = JAI.create("bandSelect", params);
// Now we perform the composite operation!
params = new ParameterBlock();
params.addSource(foreRGB);
params.addSource(backRGB);
params.add(foreAlpha);
params.add(backAlpha);
params.add(Boolean.FALSE);
params.add(CompositeDescriptor.DESTINATION_ALPHA_LAST);
// params.add(CompositeDescriptor.NO_DESTINATION_ALPHA);
RenderedOp result = JAI.create("composite", params, null);
return result;
}
// NOTE THAT ALL FILES will be written to the "current directory" when you compile and run this file.
// If you can't figure out where that is after you run this, try changing the file names below
// to include the full path to a location, i.e. "C:/background1.png" rather than just "bacground1.png".
//
// Also note that it is not necessary to write files out and read them back in in order to perform
// the composite, but think it might make things a little easier to follow and anyway it's hard enough
// finding examples of how to read and write image files using JAI that why not include it.
public CompositeExample() {
// background image colors - we generate a red rectangle on a white background
Color white = new Color(1.0f, 1.0f, 1.0f, 1.0f);
Color red = new Color(1.0f, 0f, 0f, 1.0f);
// Note that we set the 'background' color of the foreground image to transparent.
Color transparent = new Color(1.0f, 1.0f, 1.0f, 0.0f);
// and the 'foreground' of the foreground image is half blue - i.e. 50% alpha.
Color halfBlue = new Color(0f, 0f, 1.0f, .5f);
// Create and save to file background image
BufferedImage backgroundImage = createImage("background1.png", 200, 400, red, white);
RenderedOp op1 = JAI.create("filestore", backgroundImage, "background1.png", "png");
// Create and save to file foreground image
BufferedImage foregroundImage = createImage("foreground1.png", 400, 350, halfBlue, transparent);
RenderedOp op2 = JAI.create("filestore", foregroundImage, "foreground1.png", "png");
// Composite foreground onto background and save to file
RenderedOp compositeImage = composite("background1.png", "foreground1.png");
RenderedOp op3 = JAI.create("filestore", compositeImage, "composite.png", "png");
}
public static void main(String[] argv) {
CompositeExample test = new CompositeExample();
}
}