Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clear a transparent BufferedImage as fast as possible

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.

like image 925
adrian.tarau Avatar asked Mar 02 '10 22:03

adrian.tarau


2 Answers

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());
like image 162
adrian.tarau Avatar answered Oct 17 '22 18:10

adrian.tarau


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 ;)

like image 9
SyntaxT3rr0r Avatar answered Oct 17 '22 17:10

SyntaxT3rr0r