2013-01-19 19 views
5

Ich mache mit der Robot Klasse ein printscreen und ich konvertiere das BufferedImage in ein int-Array. Dann möchte ich das int-Array zurück in ein gepuffertes Bild konvertieren, aber das gibt einen Fehler. Dies ist mein Code:int-array zu BufferedImage

Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); 
BufferedImage printscreen = robot.createScreenCapture(new Rectangle(screen)); 
int[] pixels = ((DataBufferInt) printscreen.getRaster().getDataBuffer()).getData(); 

BufferedImage image = new BufferedImage(screen.width, screen.height, BufferedImage.TYPE_INT_RGB); 
WritableRaster raster = (WritableRaster) image.getRaster(); 
raster.setPixels(0, 0, screen.width, screen.height, pixels); 

Aber ich bekomme die Fehlermeldung: ArrayIndexOutOfBoundsException: 2073600 aber warum?

Ich erhalte die Ausnahme auf dieser Linie:

raster.setPixels(0, 0, screen.width, screen.height, pixels); 

EDIT: Es funktioniert, wenn ich den zweiten BufferedImage Typen TYPE_BYTE_GRAY ändern.

+2

Können Sie den StackTrace teilen? Auf welcher Linie bekommst du es? – Swapnil

+0

Edited in der Post. –

+0

Ich empfehle, alle Ihre Abmessungen auf die Größe von "Bildschirm" zu basieren. Um schneller Hilfe zu bekommen, schreiben Sie eine [SSCCE] (http://sscce.org/). Es scheint auch, dass dieses Problem für einige grundlegende Verfolgung von Codezeilen und Anzeige von Größen schreit. –

Antwort

1

geändert:

getRaster().getPixels(0, 0, screen.width, screen.height, pixels) 

und es funktioniert! Vielen Dank für die Hilfe sowieso

0

Die Ausnahme ArrayIndexOutOfBounds tritt auf, wenn Sie versuchen, auf ein Element im Index zuzugreifen, das die Größe des Arrays überschreitet. In diesem Fall übergeben Sie das Array an die Methode setPixels, die entsprechend ihren javadocs nicht explizit nach den Grenzen oder der Größe des Arrays sucht. Sie sollten das also explizit tun, bevor Sie diese Methode aufrufen. z.B.

if(x >= 0 && x < arr.length) { 
     // some code 
    } 

Dies ist der entsprechende Code aus SampleModel Klasse von WritableRaster verwendet.

public int[] getPixels(int x, int y, int w, int h, 
          int iArray[], DataBuffer data) { 

     int pixels[]; 
     int Offset=0; 

     if (iArray != null) 
      pixels = iArray; 
     else 
      pixels = new int[numBands * w * h]; 

     for (int i=y; i<(h+y); i++) { 
      for (int j=x; j<(w+x); j++) { 
       for(int k=0; k<numBands; k++) { 
        pixels[Offset++] = getSample(j, i, k, data); 
       } 
      } 
     } 

    return pixels; 
} 
+0

Danke für Ihre Antwort, aber beide BufferedImage haben die gleiche Höhe und Breite. Warum benötigt es mehr Elemente im Array, wenn es die gleiche Anzahl an Pixeln hat? –

+0

Ich würde empfehlen, eine IDE wie Eclipse JDK-Quelle hinzuzufügen und den Debugger zu verwenden, um die Variablenwerte zu überprüfen. Das ist viel schneller. – Swapnil

+0

Ich benutze Eclipse. Ich sehe in Ihrem Beispiel: 'numBands * w * h' was bedeutet numBands? Mein Pixel-Array hat 2073600 Elemente, was 1920 * 1080 ist. –

12
int[] bitMasks = new int[]{0xFF0000, 0xFF00, 0xFF, 0xFF000000}; 
SinglePixelPackedSampleModel sm = new SinglePixelPackedSampleModel(
     DataBuffer.TYPE_INT, width, height, bitMasks); 
DataBufferInt db = new DataBufferInt(pixels, pixels.length); 
WritableRaster wr = Raster.createWritableRaster(sm, db, new Point()); 
BufferedImage image = new BufferedImage(ColorModel.getRGBdefault(), wr, false, null); 
+0

Sehr gute Lösung. Für die Aufzeichnung war dies auch die einzige Lösung auf der Seite, die für mich funktionierte. Der Teil, der nicht in der WriteRaster-setPixels() -Dokumentation angegeben ist, ist, dass das an setPixels() übergebene int-Array nicht als ein-gepacktes-int-pro-Pixel aufgerufen wird, sondern scheinbar ein int pro Kanal (dh RGB würde benötigt) ein Temp-Array 3-mal so groß wie sein gepackter, ARGB 4 mal - offensichtlich keine elegante Lösung, aber ich habe es getestet und es hat funktioniert. –

0

Die Größe pixels in raster.setPixels(0, 0, screen.width, screen.height, pixels); sollte width*height*3 sein, wenn Sie BufferedImage.TYPE_INT_RGB gesetzt.

0
BufferedImage image = new BufferedImage(screen.width*3, screen.height,BufferedImage.TYPE_INT_RGB); 
WritableRaster raster = (WritableRaster) image.getRaster(); 

raster.setPixels(0, 0, screen.width*3, screen.height, pixels); 
+1

Bitte fügen Sie eine Erklärung hinzu. –

+0

Wie @SamirChen erwähnt, haben Sie rote, grüne, blaue Pixel in der Breite. Die tatsächliche Breite beträgt also 3 mal die Bildbreite. – ayman