简体   繁体   中英

How can I effectively clear part of the Graphics layer in Java?

I'm developing a rendering engine using Swing. Now I have run into a very odd problem.

Imagine we must draw something on our Graphics2D context, and then clear it. Should notice here that I'm drawing on a BufferedImages 's context, but it shouldn't matter, as paintComponent() method later simply outputs that image to the screen.

So I should draw something, then apply some custom blurring code, then repaint my area partly (I'm making a box-shadow). And I need to use the alpha channel so that my layer must be able to be partly transparent.

Now I am using this code for repainting a custom image area:

private void repaintRegion(Graphics2D g2d, int x, int y, int w, int h, BufferedImage img) {

    g2d.clearRect(x, y, w, h);
    composite = AlphaComposite.getInstance(AlphaComposite.SRC_OUT, 1f);
    g2d.setComposite(composite);
    g2d.drawImage(img, x, y, this);

    composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f);
    g2d.setComposite(composite);

    g2d.drawImage(img, x, y, this);
}

After that it is just fine. But if I remove painting in SRC_OUT mode, I get a black rectangle.

But this way it also works fine:

private void repaintRegion(Graphics2D g2d, int x, int y, int w, int h, BufferedImage img) {

    AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.CLEAR, 1f);
    g2d.setComposite(composite);

    g2d.fillRect(x, y, w, h);

    composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f);
    g2d.setComposite(composite);

    g2d.drawImage(img, x, y, this);
}

Can someone explain me, why it is so, and what is happening when I am using clearRect()?

I use clearRect() in my applications and it works fine. However, I don't mess with the composite property of the context.

Keep in mind you also might need to make sure the background color is transparent (I believe the default is black) as clearRect() uses that as the fill color for what it clears (see https://docs.oracle.com/javase/7/docs/api/java/awt/Graphics.html#clearRect(int,%20int,%20int,%20int) )

Also make sure that the BufferedImage you are drawing on has an alpha channel (use an image type with an alpha channel when calling the constructor) see https://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html#field_summary for options.

To be totally proper, you could use the GraphisEnvironment to construct the BufferedImage :

BufferedImage bufferedImage = GraphicsEnvironment.getLocalGraphicsEnvironment()
                .getDefaultScreenDevice().getDefaultConfiguration()
                .createCompatibleImage(w, h, BufferedImage.TRANSLUCENT);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM