2010-11-20 8 views
9

que estoy tratando de conseguir un BufferedImage a partir de muestras crudas, pero me da excepciones en tratar de leer más allá del rango de datos disponibles que yo simplemente no entiendo. Lo que estoy tratando de hacer es:Como crear un BufferedImage de datos en bruto

val datasize = image.width * image.height 
val imgbytes = image.data.getIntArray(0, datasize) 
val datamodel = new SinglePixelPackedSampleModel(DataBuffer.TYPE_INT, image.width, image.height, Array(image.red_mask.intValue, image.green_mask.intValue, image.blue_mask.intValue)) 
val buffer = datamodel.createDataBuffer 
val raster = Raster.createRaster(datamodel, buffer, new Point(0,0)) 
datamodel.setPixels(0, 0, image.width, image.height, imgbytes, buffer) 
val newimage = new BufferedImage(image.width, image.height, BufferedImage.TYPE_INT_RGB) 
newimage.setData(raster) 

Desafortunadamente me sale:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 32784 
    at java.awt.image.SinglePixelPackedSampleModel.setPixels(SinglePixelPackedSampleModel.java:689) 
    at screenplayer.Main$.ximage_to_swt(Main.scala:40) 
    at screenplayer.Main$.main(Main.scala:31) 
    at screenplayer.Main.main(Main.scala) 

Los datos son RGB estándar con 1 byte de relleno (de modo que 1 píxel == 4 bytes) y el tamaño de la imagen es 1366x24 px.


Finalmente obtuve el código para ejecutar con la sugerencia a continuación. El código final es:

val datasize = image.width * image.height 
val imgbytes = image.data.getIntArray(0, datasize) 

val raster = Raster.createPackedRaster(DataBuffer.TYPE_INT, image.width, image.height, 3, 8, null) 
raster.setDataElements(0, 0, image.width, image.height, imgbytes) 

val newimage = new BufferedImage(image.width, image.height, BufferedImage.TYPE_INT_RGB) 
newimage.setData(raster) 

Si se puede mejorar, estoy abierto a sugerencias, por supuesto, pero en general funciona como se esperaba.

Respuesta

10

setPixels supone que los datos de imagen son no embalados. Por lo tanto, está buscando una entrada de longitud image.width * image.height * 3 y ejecutándose al final de la matriz.

Aquí hay tres opciones para la forma de solucionar el problema.

(1) Descomprimir imgbytes por lo que es 3 veces más tiempo, y hacerlo de la misma manera que el anterior.

(2) cargar manualmente el tampón de imgbytes en lugar de utilizar setPixels:

var i=0 
while (i < imgbytes.length) { 
    buffer.setElem(i, imgbytes(i)) 
    i += 1 
} 

(3) No utilice createDataBuffer; si ya sabe que sus datos tiene el formato correcto puede crear el tampón apropiado a sí mismo (en este caso, un DataBufferInt):

val buffer = new DataBufferInt(imgbytes, imgbytes.length) 

(es posible que tenga que hacer imgbytes.clone si su copia original podría conseguir mutado por algo más).

+0

me trataron esas soluciones, pero tampoco me sale basura no relacionado, o una pantalla en negro. Los datos son correctos si miro el volcado hexadecimal. ¿Podría proporcionar un pequeño fragmento que realmente pase de imgbytes a BufferedImage? Sería muy apreciado :) – viraptor

+0

Si puede proporcionar el código que crea 'imagen' en su ejemplo, seguro. O si no le importa cómo ingresan los datos, crearé un ejemplo que no sea de una imagen. –

+0

Ese es un objeto personalizado que recibo directamente de Xorg. Si puede hacerlo cuando se conoce la altura característica '' width' y una serie de componentes bien 4 byte (orden RGB + 1 byte de relleno), o int única (el mismo formato) por cada píxel, puedo imaginar el resto. La parte donde fallo es probablemente la interacción de trama <-> de buffer (ni siquiera estoy seguro de si se necesitan ambas). Muchas gracias. – viraptor

Cuestiones relacionadas