I got all of my info from: AlphaComposite
, Compositing Graphics, Concatenating Images.
The following program is improved. It uses two methods: joinHorizontal
and joinVertical
to join the images. Inside the methods, the following happens
- the second image is copied, but only the part that overlaps
- the copied image is set at half alpha (transparency)
- on the canvas of the 'return image', the first image is painted, followed by the second without the overlapping part
- the copied image is painted onto the canvas.
- the image is returned
Why do I only set one image at half alpha and not both?
Picture a clear, glass window:

Paint random points red so that half of the window is covered with red. Now, treat the window with the red dots as your new canvas.
Paint random points blue so that the new "canvas" is half covered with blue. The window won't be completely covered; you will still be able to see through it.

But let's imagine that we first painted the window red, and then painted half of it blue. Now, it will be half blue and half red, but not transparent at all.
public class ImageMerger {
/**
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
BufferedImage img1 = //some code here
BufferedImage img2 = //some code here
BufferedImage img3 = //some code here
BufferedImage img4 = //some code here
int mergeWidth = 20; // pixels to merge.
BufferedImage merge = ImageMerger.joinVertical(
ImageMerger.joinHorizontal(img1, img2, mergeWidth),
ImageMerger.joinHorizontal(img3, img4, mergeWidth),mergeWidth);
//do whatever you want with merge. gets here in about 75 milliseconds
}
public static BufferedImage joinHorizontal(BufferedImage i1, BufferedImage i2, int mergeWidth){
if (i1.getHeight() != i2.getHeight()) throw new IllegalArgumentException("Images i1 and i2 are not the same height");
BufferedImage imgClone = new BufferedImage(mergeWidth, i2.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D cloneG = imgClone.createGraphics();
cloneG.drawImage(i2, 0, 0, null);
cloneG.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, 0.5f));
cloneG.drawImage(i2, 0, 0, null);
BufferedImage result = new BufferedImage(i1.getWidth() + i2.getWidth()
- mergeWidth, i1.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.drawImage(i1, 0, 0, null);
g.drawImage(i2.getSubimage(mergeWidth, 0, i2.getWidth() - mergeWidth,
i2.getHeight()), i1.getWidth(), 0, null);
g.drawImage(imgClone, i1.getWidth() - mergeWidth, 0, null);
return result;
}
public static BufferedImage joinVertical(BufferedImage i1, BufferedImage i2, int mergeWidth){
if (i1.getWidth() != i2.getWidth()) throw new IllegalArgumentException("Images i1 and i2 are not the same width");
BufferedImage imgClone = new BufferedImage(i2.getWidth(), mergeWidth, BufferedImage.TYPE_INT_ARGB);
Graphics2D cloneG = imgClone.createGraphics();
cloneG.drawImage(i2, 0, 0, null);
cloneG.setComposite(AlphaComposite.getInstance(AlphaComposite.DST_IN, 0.5f));
cloneG.drawImage(i2, 0, 0, null);
BufferedImage result = new BufferedImage(i1.getWidth(),
i1.getHeight() + i2.getHeight() - mergeWidth, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.drawImage(i1, 0, 0, null);
g.drawImage(i2.getSubimage(0, mergeWidth, i2.getWidth(),
i2.getHeight() - mergeWidth), 0, i1.getHeight(), null);
g.drawImage(imgClone, 0, i1.getHeight() - mergeWidth, null);
return result;
}
}