Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Layer multiple BufferedImages on top of one another?

I have multiple transparent BufferedImage instances which I'd like to layer on top of each other (aka Photoshop layers) and bake into one BufferedImage output. How do I do this?

like image 861
Naftuli Kay Avatar asked Dec 07 '22 13:12

Naftuli Kay


2 Answers

I would say the best bet would be to take the buffered images, and create an additional one in order to have an object to append to. Then simply use the Graphics.drawImage() to place them on top of each other.

So something along these lines:

BufferedImage a = ImageIO.read(new File(filePath, "a.png"));
BufferedImage b = ImageIO.read(new File(filePath, "b.png"));
BufferedImage c = new BufferedImage(a.getWidth(), a.getHeight(), BufferedImage.TYPE_INT_ARGB);

Graphics g = c.getGraphics();
g.drawImage(a, 0, 0, null);
g.drawImage(b, 0, 0, null);
like image 75
Jeff LaJoie Avatar answered Dec 24 '22 00:12

Jeff LaJoie


Let's pretend that the first BufferedImage is named bi1 and the second bi2, while the image you want to layer them onto is target.

BufferedImage target=new BufferedImage(width,height,BufferedImage.TYPE_INT_ARGB);
Graphics2D targetGraphics=target.createImage();
targetGraphics.drawImage(bi1,0,0,null);//draws the first image onto it

int[] pixels2=((DataBufferInt) bi2.getRaster().getDataBuffer()).getData();
int[] pixelsTgt=((DataBufferInt) target.getRaster().getDataBuffer()).getData();
for(int a=0;a<pixels2.length;a++)
{
     pixelsTgt[a]+=pixels2[a];//this adds the pixels together
}

Make sure that all three BufferedImage objects are of TYPE_INT_ARGB so that alpha is turned on. This may not give you the exact results that you had wanted if the two added together are more than the max integer, so you might want to add in something to help fix that. Pixels use bit shifts to add to colors with the integer ordered as AARRGGBB.

like image 35
Indeed Avatar answered Dec 24 '22 00:12

Indeed