2015-03-27 9 views
2

Я пытаюсь преобразовать Буферизированное изображение в ByteBuffer, но я получаю это исключениеПреобразования BufferedImage в ByteBuffer

java.awt.image.DataBufferInt cannot be cast to java.awt.image.DataBufferByte 

может кто-то пожалуйста, помогите мне и предложить хороший метод преобразования.

Источник:

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; 
} 

это мой объект

ByteBuffer buf = convertImageData(image); 
+0

Когда вы создаете буферное изображение, вы можете указать ему константу, которая определяет цветовое пространство изображения. Похоже, вы смешиваете изображения типа int и byte. Например, http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html#TYPE_BYTE_INDEXED. Вы также можете использовать http://docs.oracle.com/javase/7/docs/api/java/awt/image/BufferedImage.html#getType%28%29, чтобы узнать тип существующего изображения. – BretC

ответ

0

Если вы хотите, чтобы кодировать данные изображения, вы можете использовать ImageIO здесь. Что-то вроде этого:

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 поддерживаемых форматов.

+0

Пока ваш код будет компилироваться и выполняться, он действительно делает что-то совершенно иное, чем то, что OP пытался достичь в своем блоке кода. Кажется, что код ожидает байтового буфера, содержащего «сырые» пиксели, что он получит здесь, это буфер, содержащий файл PNG. – haraldK

4

Вы не можете просто бросить произвольное DataBuffer к DataBufferByte, вы должны убедиться, что это на самом деле правильный тип:

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()); 
} 

Если ваш BufferedImage является одним из стандартных типов (кроме BufferedImage.TYPE_*TYPE_CUSTOM) вышеуказанное должно работать.

Обратите внимание, что специальные подклассы DatBuffer могут существовать и могут хранить пиксели в нескольких банках с различным порядком байтов, может быть чередованием каналов (а не стандартным чередованием пикселей) и т. Д. Таким образом, приведенный выше код еще не является полностью общим.

Если вы передать эти ByteBuffer S в машинный код, используя allocateDirect(..) и копирование пикселов над может быть быстрее, в противном случае я думаю, с помощью wrap(..) будет делать как для простого кода и быть более эффективными.

+0

Возможно ли избежать копирования большого количества байтов с места на место? – Dims

+0

Поскольку мы, по-видимому, не можем избежать копирования, я использовал решение 'ImageIO', потому что оно является родным для изображений. – Dims

+0

@ Dims Если это работает для вашего случая использования, обязательно. Использование 'ImageIO' для кодирования данных в формате файла всегда будет медленнее, чем просто копирование байтов. – haraldK

Смежные вопросы