问题
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);
回答1:
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.
回答2:
If you want to encode the image data, you may want to use the ImageIO here. Something like this:
public static ByteBuffer convertImageData(BufferedImage bi) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
ImageIO.write(bi, "png", out);
return ByteBuffer.wrap(out.toByteArray());
} catch (IOException ex) {
//TODO
}
return null;
}
Here is the list of supported formats.
来源:https://stackoverflow.com/questions/29301838/converting-bufferedimage-to-bytebuffer