Best API for low-level 2D pixel buffer access?

What’s the best JVM-friendly API for direct 2D pixel buffer access. I’m looking for development simplicity, elegance, and uninhibited rendering speed.

I’m loosely familiar with AWT, Swing, and JavaFX, but what specific control our class do I need to get a raw binary pixel buffer that I can write to?

Disclaimer: This isn’t low-level, but still may be useful to you

If you do all your pixel manipulation in an int array, you can update a BufferedImage with those pixel values via the setRGB(0,0,width,height,array,0,array.length) method.

This of course requires you to do pixel manipulation on a one-dimensional array, which is actually good practice as it avoids excessive bounds checking.

The only thing faster than that (though I haven’t tested in like 5 years) would be creating an Image via MemoryImageSource and updating the pixels via the newPixels() method. The only reason it would be faster is because Image has less overhead than BufferedImage. But on modern computers and newer JVMs, this difference may no longer be noticeable.

Better:

int[] rgba = ((DataBufferInt)new BufferedImage(w, h, type).getRaster().getDataBuffer()).getData();
byte[] rgba = ((DataBufferByte)new BufferedImage(w, h, type).getRaster().getDataBuffer()).getData();

You can read/write directly into the int[] (or byte[] for that matter) and the image will be updated with every draw. Naturally, you lose hardware acceleration, but it’s only positive to keep all data away from the GPU in this case. If you write once, draw many (sprite?), just blit the image into another (compatible) BufferedImage and use that to draw.

Very similar to MemorySourceImage, without the need to mess with Observers and Producers, the newPixels() call takes ages.

I use this method, and it’s darn fast.

Thanks for this, makes things more straightforward

I can see how to build a BufferedImage with pixel data. So far, that’s perfect.

What do I use to get that image into a window or screen? Should I use AWT, Swing, or JavaFX?

`
class Viewport extends Canvas
{
BufferedImage buf;

public void paint(Graphics g)
{
g.drawImage(buf, 0, 0, null);
}

public void update(Graphics g)
{
// override, to not clear, just paint the canvas
this.paint(g);
}

public Dimension getPreferredSize()
{
return new Dimension(buf.getWidth, buf.getHeight());
}
}
`

Then add it to a Frame, with a BorderLayout, and call frame.pack(), then frame.setVisible(true)

Whenever you updated your int[], call myViewport.repaint()

Removed…

So where would you grab hold of that int[] then? :-X

I think you got confused with implementing double buffering, when you saw my source code.

Thanks for the help. It actually took a few hours of futzing with JFrame, layouts, canvas/panels, to figure out exactly how to get them properly wired together, but it’s working perfectly!

BTW, I’m using a JPanel instead of a Canvas which people say is slightly better…

JPanel is another layer (level of abstraction, if you will) between the framebuffer and the ARGB int[]. It will do double buffering for you, and you really don’t want yet another copy in this case.

So if there is no reason to deal with Swing, don’t deal with Swing and work straight with AWT.