Confused with BufferedImage

I have googled and youtubed. But, I learn much easier from this forum so here we go…

My last post I asked about animation which I’ve near enough cracked to the point I can code from scratch a JFrame and do some bouncing balls etc…

I’ve been struggling and confused for a while now with this BufferedImage thing, I’ve been watching tutorials and there is many on java game programming on youtube as you may all know. But when it gets passed setting up the fps counter loop, basic setup engine, screen etc and gets onto the bufferedImage and pixel thing I’m lost and like I say I have to been googling but still dont get it. Things like:

var = ((DataBufferByte) m_displayImage.getRaster().getDataBuffer()).getData();

and…

private BufferedImage image = new BufferedImage(WIDTH, HEIGHT,
			BufferedImage.TYPE_INT_RGB);

At the moment Im guessing it creates a blank image onto the canvas but obviously theres more to it? Why do they setup a pixel array when you could add sprites with Image? Eventually though I’ll be wanting to draw sprites with code like they do on Java4K I’m always mentioning on my posts, I’m in no competion about this I just find it fasinating using pure Java so no replys on other game engines please.

If you could enlighten me on this subject so I can understand it better that would be excellent…

The second block of code does indeed create a BufferedImage, but actually painting it to the canvas is handled elsewhere. Taking a stab in the dark here, I’d say they’re setting up a back buffer to draw to which will later be drawn to the canvas via the canvas’ Graphics object.

As for the pixel array, it’s useful for per pixel manipulation. Some things can be handled perfectly well by blitting sprites to the back buffer, but some effects require access to the individual pixels of the buffer. Both are valid approaches depending on your needs, although you risk de-accelerating your graphics objects when working on a per pixel level.

You may want to do some reading about the BufferStrategy class which dovetails nicely into these types of topics and overall may be a more straightforward approach to what you’re working on.

Accessing the pixel array allows one to use something like this


public void setPixel(int x, int y, Color c) {
    dataBuffer[x + y * image.getWidth()] = c.getRGB();
}

instead of [icode]image.setRGB(x, y, c.getRGB());[/icode] or [icode]g.drawLine(x, y, x, y);[/icode] which do the same thing, but are a good bit slower.

It’s a trick that only really ever needs used if you need to be drawing lots of individual pixels as fast as possible.
To copy whole images it is still preferred to use [icode]g.drawImage(…);[/icode]

Ahhh, thanks peeps! I love this forum… Hit the nail on the head here…

So if I’m correct, working with pixel arrays, per pixel as in for example… this.setSize(800,600); in a constructor(obviously) <— You would have access per pixels? 800 * 600 is 480000 pixels, so using the setPixel method BurntPizza mentioned you could add a red pixel after you have created a BufferedImage object on the empty canvas?

And going a bit far here… lets say in the future I’d be able to create effects destructable terrain working with pixel arrays?

I like and prefer the idea of working at a pixel array level rather than what you call ‘blitting’ so you 2 have mentioned it quiet well so thanks

I’m not sure what you think you mean… a BI doesn’t exist “on a canvas,” it simply exists.

Well, you can do anything, whether or not it is a good way to do it is completely different.

How does a BufferedImage compare to a Canvas? Isn’t this to do with flickering, are they simular classes with simular methods but a does better than b? Cheers

A BufferedImage is an image, represented under the hood by an array of pixels. That is all.
A Canvas is a GUI widget that can display images. It is however outdated and you should probably use JComponent instead.* (they can also display images)
(* unless you are using a BufferStrategy, which is a whole different thing)

Flickering is often mentioned along with a technique called double buffering, double buffering is the act of drawing to an intermediate image (like a BufferedImage), and then blitting the image to a GUI component all at once, instead of drawing whatever is was you were drawing directly to the GUI component, because if you’re drawing is slow, the user will be able to see the drawing as it is happening, this can show up as flicker. Drawing to an intermediate and then blitting (copying) it is slower overall, but appears faster to the user, as the blit itself happens all at once.

One nice thing about JComponent(s) is that they can handle double buffering for you:


component.setDoubleBuffered(true);

Thanks, I think this will be the last question regarding the subject…

If the BufferedImage is an array of pixels of 800x600, then how would you print out the values out of interest to the log/console/sysout… I tried this before but gave me some hex number which I’m guessing is some kind of memory address for the VM

Well if you have the pixel array, then the values in the array are whatever is specified by the image type:

BufferedImage.TYPE_INT_RGB, TYPE_INT_ARGB : ARGB packed integers

Easy to understand way to extract the individual color channels:

Color c = new Color(argb);
System.out.println(c);

For example:


int argb = Color.magenta.getRGB();
System.out.println(argb);
System.out.println(new Color(argb));

[quote]-65281
java.awt.Color[r=255,g=0,b=255]
[/quote]
For how it’s done, either look at the Color.java source, or look at some of the answers here: http://stackoverflow.com/questions/2615522/java-bufferedimage-getting-red-green-and-blue-individually?rq=1