I'm trying to convert a Buffered image into a ByteBuffer but i get this exception
java.awt.image.DataBufferInt cannot be cast to java.awt.image.DataBufferByte
can someone please help me out and suggest a good method of conversion.
Source:
public static ByteBuffer convertImageData(BufferedImage bi)
{
byte[] pixelData = ((DataBufferByte) bi.getRaster().getDataBuffer()).getData();
// return ByteBuffer.wrap(pixelData);
ByteBuffer buf = ByteBuffer.allocateDirect(pixelData.length);
buf.order(ByteOrder.nativeOrder());
buf.put(pixelData);
buf.flip();
return buf;
}
this is my object
ByteBuffer buf = convertImageData(image);
A BufferedImage is comprised of a ColorModel and a Raster of image data. The number and types of bands in the SampleModel of the Raster must match the number and types required by the ColorModel to represent its color and alpha components. All BufferedImage objects have an upper left corner coordinate of (0, 0).
A BufferedImage is essentially an Image with an accessible data buffer. It is therefore more efficient to work directly with BufferedImage. A BufferedImage has a ColorModel and a Raster of image data. The ColorModel provides a color interpretation of the image's pixel data.
BufferedImage buffer = ImageIO. read(new File(file)); to Image i.e in the format something like : Image image = ImageIO.
You can't just cast an arbitrary databuffer to DataBufferByte
, you need to make sure it actually is the right type:
ByteBuffer byteBuffer;
DataBuffer dataBuffer = bi.getRaster().getDataBuffer();
if (dataBuffer instanceof DataBufferByte) {
byte[] pixelData = ((DataBufferByte) dataBuffer).getData();
byteBuffer = ByteBuffer.wrap(pixelData);
}
else if (dataBuffer instanceof DataBufferUShort) {
short[] pixelData = ((DataBufferUShort) dataBuffer).getData();
byteBuffer = ByteBuffer.allocate(pixelData.length * 2);
byteBuffer.asShortBuffer().put(ShortBuffer.wrap(pixelData));
}
else if (dataBuffer instanceof DataBufferShort) {
short[] pixelData = ((DataBufferShort) dataBuffer).getData();
byteBuffer = ByteBuffer.allocate(pixelData.length * 2);
byteBuffer.asShortBuffer().put(ShortBuffer.wrap(pixelData));
}
else if (dataBuffer instanceof DataBufferInt) {
int[] pixelData = ((DataBufferInt) dataBuffer).getData();
byteBuffer = ByteBuffer.allocate(pixelData.length * 4);
byteBuffer.asIntBuffer().put(IntBuffer.wrap(pixelData));
}
else {
throw new IllegalArgumentException("Not implemented for data buffer type: " + dataBuffer.getClass());
}
If your BufferedImage
is one of the standard types (BufferedImage.TYPE_*
other than TYPE_CUSTOM
) the above should work.
Note that special DatBuffer
subclasses may exist, and may store pixels in multiple banks, with different byte order, might be channel interleaved (rather than the standard pixel interleaved) etc. So the above code is still not completely general.
If you are to pass these ByteBuffer
s to native code, using allocateDirect(..)
and copying the pixels over might be faster, otherwise I think using wrap(..)
will make for both simpler code and be more efficient.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With