2013-01-19 16 views
5

Robię z klasy Robot printscreen i konwertuję BufferedImage na tablicę int. Następnie chcę przekonwertować tablicę int z powrotem na buforowany obrazek, ale to daje błąd. To jest mój kod:int array na 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); 

Ale pojawia się błąd: ArrayIndexOutOfBoundsException: 2073600, ale dlaczego?

Dostaję wyjątek na tej linii:

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

EDIT: To jest działanie, jeśli zmienię drugi typ BufferedImage do TYPE_BYTE_GRAY.

+2

Czy możesz udostępnić stacktrace? Na której linii się znajdujesz? – Swapnil

+0

Eddited we wpisie. –

+0

Polecam opierając wszystkie wymiary na rozmiarze 'ekranu'. Aby uzyskać lepszą pomoc wcześniej, opublikuj [SSCCE] (http://sscce.org/). Wydaje się również, że ten problem krzyczy za podstawowe wykrywanie linii kodu i wyświetlanie rozmiarów. –

Odpowiedz

1

zmienione na:

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

i to działa! Dzięki za pomoc i tak

0

Wyjątek ArrayIndexOutOfBounds pojawia się podczas próby uzyskania dostępu do elementu o indeksie przekraczającego rozmiar tablicy. W takim przypadku przekazujesz tablicę do metody setPixels, która odpowiednio do jej javadoców nie sprawdza wprost granic ani wielkości tablicy. Powinieneś to zrobić wyraźnie przed wywołaniem tej metody. na przykład

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

To jest odpowiedni kod z SampleModel klasy używanej przez WritableRaster.

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

Dziękujemy za odpowiedź, ale oba obrazy BufferedImage mają tę samą wysokość i szerokość. Dlaczego więc potrzebuje więcej elementów w tablicy, jeśli ma taką samą ilość pikseli? –

+0

Polecam dodanie źródła JDK do IDE, takiego jak eclipse i użycie debuggera do sprawdzenia wartości zmiennych. To znacznie szybciej. – Swapnil

+0

Używam zaćmienia. Widzę w twoim przykładzie: 'numBands * w * h' co oznacza numBands? Moja macierz pikseli ma 2073600 elementów, czyli 1920 * 1080. –

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

Bardzo dobre rozwiązanie. Dla przypomnienia było to również jedyne rozwiązanie na stronie, które działało dla mnie. Część nie podana w dokumentach piszących w zestawie WritableRaster setPixels() polega na tym, że tablica int przekazana do setPixels() nie jest dostępna jako zapakowana w jeden piksel, ale najwyraźniej jedna int na kanał (tzn. RGB będzie potrzebować tablica temp 3 razy większa od jego spakowanej, ARGB 4 razy - oczywiście nie jest to eleganckie rozwiązanie, ale testowałem i działało). –

0

Wielkość pixels w raster.setPixels(0, 0, screen.width, screen.height, pixels); powinny być width*height*3 po ustawieniu BufferedImage.TYPE_INT_RGB.

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

Proszę dodać wyjaśnienie. –

+0

Jak wspomniałem @SamirChen, szerokość ma szerokość czerwoną, zieloną i niebieską. więc rzeczywista szerokość jest 3 razy większa niż szerokość obrazu. – ayman