Search code examples
javatransparencybufferedimagegraphics2d

Combine multiple graphics2d composites?


How can i combine 2 composites in to one? Let me explain:

BufferedImage copy = new BufferedImage(img.getWidth(), img.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = copy.createGraphics();
g2d.setComposite(AlphaComposite.Clear);
g2d.fillRect(0, 0, img.getWidth(), img.getHeight());

Now we have a transparent image.

g2d.setComposite(AlphaComposite.Src);
g2d.drawImage(img, 0, 0, null);

Now we have an exact copy of the "img" including the transparent areas.

g2d.setComposite(BlendComposite.getInstance(BlendingMode.MULTIPLY));
g2d.setColor(overlayColor);
g2d.fillRect(0, 0, img.getWidth(), img.getHeight());

(BlendComposite from http://www.curious-creature.com/2006/09/20/new-blendings-modes-for-java2d/) At this point the the multiply composite has given the image a nice color (overlayColor).

But the transparent areas now have the same color as overlayColor.

How can i prevent the transparent area's from getting the overlayColor?


Solution

  • @haraldK point me to a nice working solution:

    Paint the original (img) over the copy (using the existing g2d) with DstIn AlphaComposite?

    I gave it a try just after the multiply step:

    g2d.setComposite(AlphaComposite.DstIn);
    g2d.drawImage(img, 0, 0,    null);
    

    And it now works, i have my transparency back!

    For anyone with the same problem:

    AlphaComposite.DstIn:

    If pixels in the source and the destination overlap, the alpha from the source is applied to the destination pixels in the overlapping area. If the alpha = 1.0, the pixels in the overlapping area are unchanged; if the alpha is 0.0, pixels in the overlapping area are cleared.

    http://docs.oracle.com/javase/tutorial/2d/advanced/compositing.html