2010-11-20 16 views
9

Sto cercando di ottenere un BufferedImage dai campioni grezzi, ma ottengo eccezioni sul tentativo di leggere oltre l'intervallo di dati disponibili che non riesco a capire. Quello che sto cercando di fare è:Come creare un BufferedImage dai dati grezzi

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) 

Purtroppo ottengo:

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) 

I dati sono RGB standard con 1 chilo di byte (in modo che 1 pixel == 4 byte) e le dimensioni dell'immagine è 1366x24 px.


Ho finalmente ottenuto il codice per eseguire con il suggerimento di seguito. Il codice finale è:

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) 

Se può essere migliorato, io sono aperto a suggerimenti, naturalmente, ma in generale funziona come previsto.

risposta

10

setPixels presuppone che i dati dell'immagine siano non imballati. Quindi sta cercando un input di lunghezza image.width * image.height * 3, e in esecuzione fuori dalla fine dell'array.

Ecco tre opzioni su come risolvere il problema.

(1) Disimballare imgbytes quindi è 3 volte più lungo, e farlo allo stesso modo come sopra.

(2) caricare manualmente il buffer dalla imgbytes anziché utilizzare setPixels:

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

(3) Non usare createDataBuffer; se si sa già che i dati con la formattazione corretta è possibile creare il tampone appropriato te stesso (in questo caso, un DataBufferInt):

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

(potrebbe essere necessario fare imgbytes.clone se la copia originale potrebbe ottenere mutato da qualcosa altro).

+0

Ho provato quelle soluzioni, ma o ottengo spazzatura non correlata, o uno schermo nero. I dati sono corretti se guardo il dump esadecimale di esso. Potresti fornire un breve frammento che vada effettivamente da imgbytes a BufferedImage? Sarebbe molto apprezzato :) – viraptor

+0

Se è possibile fornire il codice che crea 'image' nel proprio esempio, sicuro. O se non ti interessa come arrivano i dati, creerò un esempio che non proviene da un'immagine. –

+0

Questo è un oggetto personalizzato che ottengo direttamente da Xorg. Se riesci a farlo con 'height',' width' e una matrice di componenti da 4 byte (ordine RGB + 1byte padding) o single int (stesso formato) per ogni pixel, posso capire il resto. La parte in cui non riesco è probabilmente il buffer dell'interazione raster <-> (non sono nemmeno sicuro se entrambi sono necessari). Molte grazie. – viraptor

Problemi correlati