views:

267

answers:

2

I have a transparent BufferedImage created with the following code(not relevant how it is created, I think):

            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            GraphicsDevice gs = ge.getDefaultScreenDevice();
            GraphicsConfiguration gc = gs.getDefaultConfiguration();

            Rectangle screen = transformationContext.getScreen();

            // Create an image that supports transparent pixels
            return gc.createCompatibleImage((int) screen.getWidth(), (int) screen.getHeight(),
                    Transparency.BITMASK);

How do I clear the image(empty image in the same state as it was created) in the fastest way possible without recreating the image? Recreating the image puts a burden on GC, pausing the VM and freezing the UI.

+2  A: 

One relatively fast way, but I don't know if it's the fastest (and I'd like to see other answers) is to have another picture that you never modify and that is always "fully cleared" / "fully transparent" and then you do a raster copy, say you named that copy CLEAR:

imageYouWantToClear.setData( CLEAR.getRaster() );

Note that working with graphics can be very tricky when it comes to performances because there are a lot of not-very-well-documented behavior. For example your images (say the CLEAR one) may be hardware-accelerated but you'd then lose hardware-acceleration as soon as you'd use a mutating method (like say a setRgb()) and it would prove very difficult to realize that you just lost the benefit of hardware acceleration.

I think that the best place to find infos on the subject of performant BufferedImage would be in the Java game-programmers and Java game-API-programmers community/forums.

Btw make sure that both your BufferedImage are using the 'compatible' mode: TYPE_INT_ARGB may be fine on Windows but not on OS X, etc. so you want to create them doing something like:

GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);

Ouch the Law-of-Demeter hurts, thanks Java ;)

Webinator
Thanks WizardOfOdds but keeping another image(which needs to be recreated when the "active" image is recreated because the bounds change) will increase memory usage(think of 1600x1200 screen resolution). clearRect does the trick and it seems pretty fast.
adrian.tarau
+1  A: 

Got it :) used clearRect instead of fill with a transparent color.

            graphics = (Graphics2D) offlineBuffer.getGraphics();
            graphics.setBackground(new Color(255, 255, 255, 0));
            Rectangle screen = transformationContext.getScreen();
            graphics.clearRect(0,0, (int)screen.getWidth(), (int)screen.getHeight());
adrian.tarau