Can't draw into BufferedImage

So here we go, my first ever post on a forum. And I’m really embarrassed about it because it is a very simple one still I can’t get my stupid head around it. I haven’t really worked with Java2D so far, let alone bufferedImages. So:

I’ve got an ever-changing buffered image, it represents the screen. This buffered image is drawn into the screen directly. There are many other buffered images that are drawn into this first big one. My problem is that when you try to move these smaller buffered images the screen behind doesn’t get cleared as it is a bufferedImage itself. I found one solution to this problem:

screenBuffer. setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
Rectangle2D.Double rect = new Rectangle2D.Double(0, 0, screen.width, screen.height);
screenBuffer. fill (rect);

So far so good, the main bufferedImage in the background gets cleared up, but I can’t draw ANYTHING into it anymore, can someone please tell me why?

Naively I tried to add one more line after the above code:

screenBuffer. setComposite(AlphaComposite.getInstance(AlphaComposite.BITMASK, 1.0f));

…and it didn’t work obviously. What I tried to do here is to clear all the pixels of the bufferedImage, then set the alpha back to normal so that anything added to screenBuffer after this line would get drawn.

Any solution for this? Thanks in advance.
Greg

To draw to a BufferedImage do the following:

//setup
Graphics2D g2d = screenBuffer.createGraphics();

//clear the entire buffer
g2d.setColor(Color.black);
g2d.fillRect(0, 0, screenBuffer.getWidth(), screenBuffer.getHeight());

//TODO: draw whatever you're going to draw here

//free up resources
g2d.dispose();

Your composite code looks to me like it’s making the whole buffer permanently blank, though I don’t really know. I’ve never used the setComposite method and aren’t going to look it up.

Really, you should probably be drawing to a BufferStrategy for the JFrame (or whatever) that you’re using, not a BufferedImage. If you wanted to do some kind of effects on the whole screen or create a screenshot, it might make sense to draw to a BufferedImage.

Hey greg.
You have to save the composite before, clear the rect, then restore the composite . something like :


Composite originalComposite = screenBuffer.getComposite();

screenBuffer. setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0.0f));
    Rectangle2D.Double rect = new Rectangle2D.Double(0, 0, screen.width, screen.height);
    screenBuffer. fill (rect);

screenBuffer. setComposite(originalComposite);

I am not sure if those are the correct calls, since I am at work and I cant compile now, but that’s the idea. Save the composite first , then restore it later. Otherwise all your other draw calls will only draw “CLEAR”

edit : but fletchergames is right, you should use bufferedStrategy for double buffering, it’s really faster and it wont change your logic at all (you will keep drawing to a Graphics2D)

Wow lads, I looked up BufferStrategy and although I haven’t had the chance to try it out I like it already :)) I think once I’ve heard of it somewhere but never knew exactly what it was. I’ll defo give it a go!

I still can’t draw into my buffered images though, but I think I know how I should work around it (leave 'em out of the program :)).

Thanks for your help guys!
Greg

You can manually set all the pixels to an alpha of 0 every repaint. That will definitely work, and if your image isn’t huge it should probably be plenty fast enough.


for (int i = 0; i < image.getRaster().getWidth(); i++)
{
    for (int j = 0; j < image.getRaster().getHeight(); j++)
    {
        image.getRaster().setPixel(i,j,new int[]{0,0,0,0});
    }
}

I think that’s the right syntax. Granted this is for if your BufferedImage is a TYPE_INT_ARGB.

+1 on this one. AlphaComposite.CLEAR means always zero the color and alpha channel on the destination. Drop your call to setComposite() and use setColor() + fillRect() to clear either the image or buffer strategy.