Yves Daoust Yves Daoust - 2 months ago 18
Java Question

Efficient access to image pixels in Java

I need to write a resampling function that takes an input image and generates an output image in Java.

The image type is TYPE_BYTE_GRAY.

As all pixels will be read and written, I need an efficient method to access the image buffer(s).

I don't trust that methods like getRGB/setRGB will be appropriate as they will perform conversions. I am after functions that will allow me the most direct access to the stored buffer, with efficient address computation, no image copy and minimum overhead.

Can you help me ? I have found examples of many kinds, for instance using a WritableRaster, but nothing sufficiently complete.




Update:

As suggested by @FiReTiTi, the trick is to get a
WritableRaster
from the image and get its associated buffer as a
DataBufferByte
object.

DataBufferByte SrcBuffer= (DataBufferByte)Src.getRaster().getDataBuffer();


Then you have the option to directly access the buffer using its
getElem
/
setElem
methods

SrcBuffer.setElem(i, getElem(i) + 1);


or to extract an array of bytes

byte [] SrcBytes= SrcBuffer.getData();
SrcBytes[i]= SrcBytes[i] + 1;


Both methods work. I don't know yet it there's a difference in performance...

Answer

The easiest way (but not the fastest) is to use the Raster my image.getRaster(), and then use the methods getSample(x,y,c) and setSample(x,y,c,v) to access and modify the pixels values.

The fastest way to do it is to access the DataBuffer (direct access to the array representing the image), so for a TYPE_BYTE_GRAY BufferedImage, it would be byte[] buffer = ((DataBufferByte)myimage.getRaster().getDataBuffer()).getData(). Just be careful that the pixels are encoded on byte and not unsigned byte, so every time you want to read a pixel value, you have to do buffer[x] & 0xFF.

Here is a simple test:

BufferedImage image = new BufferedImage(256, 256, BufferedImage.TYPE_BYTE_GRAY) ;
byte[] buffer = ((DataBufferByte)image.getRaster().getDataBuffer()).getData() ;
System.out.println("buffer[0] = " + (buffer[0] & 0xFF)) ;
buffer[0] = 1 ;
System.out.println("buffer[0] = " + (buffer[0] & 0xFF)) ;

And here is the outputs:

buffer[0] = 0
buffer[0] = 1