2010-11-20 18 views
9

Ich versuche, ein BufferedImage von Raw-Samples zu erhalten, aber ich bekomme Ausnahmen über das Lesen über den verfügbaren Datenbereich, die ich gerade nicht verstehe. Was ich versuche zu tun:So erstellen Sie ein BufferedImage aus Rohdaten

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) 

Leider erhalte ich:

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) 

Die Daten sind Standard-RGB mit 1 Byte padding (so dass 1 Pixel == 4 Bytes) und die Bildgröße ist 1366x24 px.


Ich habe endlich den Code mit dem Vorschlag unten ausgeführt. Der letzte Code ist:

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) 

Wenn es verbessert werden kann, ich Anregungen natürlich offen bin, aber im Allgemeinen funktioniert es wie erwartet.

Antwort

10

setPixels wird davon ausgegangen, dass die Bilddaten nicht verpackt sind. Es sucht also nach einer Eingabe der Länge image.width * image.height * 3 und läuft am Ende des Arrays ab.

Hier sind drei Optionen, wie Sie das Problem beheben können.

(1) Packen Sie imgbytes aus, so dass es 3x länger ist, und tun Sie es auf die gleiche Weise wie oben beschrieben.

(2) geladen werden manuell den Puffer aus imgbytessetPixels anstelle der Verwendung:

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

(3) nicht createDataBuffer verwenden; wenn Sie bereits wissen, dass Ihre Daten, um die richtige Formatierung hat, können Sie den entsprechenden Puffer selbst erstellen (in diesem Fall ein DataBufferInt):

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

(Sie müssen möglicherweise imgbytes.clone wenn Ihre ursprüngliche Kopie tun könnte durch etwas mutiert erhalten sonst).

+0

Ich habe diese Lösungen versucht, aber entweder bekomme ich nicht verwandten Müll oder einen schwarzen Bildschirm. Die Daten sind korrekt, wenn ich den Hex-Dump von ihm ansehe. Könnten Sie ein kurzes Fragment bereitstellen, das von imgbytes zu BufferedImage geht? Es würde wirklich geschätzt werden :) – viraptor

+0

Wenn Sie Code zur Verfügung stellen können, der 'image' in Ihrem Beispiel erstellt, sicher. Oder wenn es Ihnen egal ist, wie die Daten eingehen, erstelle ich ein Beispiel, das nicht aus einem Bild stammt. –

+0

Das ist ein benutzerdefiniertes Objekt, das ich direkt von Xorg bekomme. Wenn Sie es mit bekannten 'height',' width' und einem Array von entweder 4-Byte-Komponenten (RGB-Reihenfolge + 1-Byte-Füllung) oder single int (gleiches Format) pro Pixel machen können, kann ich den Rest herausfinden. Der Teil, bei dem ich scheitere, ist wahrscheinlich der Puffer <-> Raster-Interaktion (ich bin nicht einmal sicher, ob beide benötigt werden). Danke vielmals. – viraptor

Verwandte Themen