7

I'm making with the Robot class a printscreen and I convert the BufferedImage into an int array. Then I want to convert the int array back to a bufferedimage but that gives an error. This is my code:

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);

But I get the error: ArrayIndexOutOfBoundsException: 2073600 but why?

I'm getting the exception on this line:

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

EDIT: It is working if I change the second bufferedimage type to TYPE_BYTE_GRAY.

Jochem Gruter
  • 2,813
  • 5
  • 21
  • 43
  • 2
    Can you share the stacktrace? On which line are you getting it? – Swapnil Jan 19 '13 at 16:05
  • I recommend basing all your dimensions on the size of `screen`. For better help sooner, post an [SSCCE](http://sscce.org/). It also seems this problem is screaming out for some basic tracing of code lines and display of sizes. – Andrew Thompson Jan 20 '13 at 00:25

5 Answers5

15
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);
Yu Kobayashi
  • 386
  • 3
  • 6
  • Very good solution. For the record, this was also the only solution on the page that worked for me. The part not stated in the WritableRaster setPixels() docs is that the int array passed to setPixels() is not accessed as one-packed-int-per-pixel, but rather, apparently, one int per channel (i.e., RGB would need a temp array 3 times the size of his packed one, ARGB 4 times -- obviously not an elegant solution, but I tested it and it worked). – Gnaural Sep 09 '17 at 16:41
1

Changed to:

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

and it works! Thanks for help anyway

Jochem Gruter
  • 2,813
  • 5
  • 21
  • 43
0

The ArrayIndexOutOfBounds exception occurs as and when you try to access an element at index which is beyond the size of the array. In this case, you're passing the array to setPixels method, which accordingly to its javadocs doesn't explicitly check for the bounds or size of the array. So you should be doing that explicitly before calling that method. e.g.

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

This is the relevant code from SampleModel class used by 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;
}
Swapnil
  • 8,201
  • 4
  • 38
  • 57
  • Thanks for your answer but both BufferedImage have the same height and width. So why does it need more elements in the array if it has the same amount of pixels? – Jochem Gruter Jan 19 '13 at 16:14
  • I would recommend adding JDK source to an IDE like eclipse and using the debugger to check the variable values. That's much faster. – Swapnil Jan 19 '13 at 16:21
  • I'm using eclipse. I see in your example: `numBands * w * h` what does numBands mean? My pixel array has 2073600 elements which is 1920*1080. – Jochem Gruter Jan 19 '13 at 16:23
  • You can browse the source here - http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/awt/image/SampleModel.java#SampleModel.setPixels%28int%2Cint%2Cint%2Cint%2Cint%5B%5D%2Cjava.awt.image.DataBuffer%29 – Swapnil Jan 19 '13 at 16:28
0

The size of pixels in raster.setPixels(0, 0, screen.width, screen.height, pixels); should be width*height*3 when you set BufferedImage.TYPE_INT_RGB.

SamirChen
  • 1,209
  • 1
  • 12
  • 22
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);
ayman
  • 29
  • 4