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.

2
  • 2
    Can you share the stacktrace? On which line are you getting it? Commented Jan 19, 2013 at 16:05
  • I recommend basing all your dimensions on the size of screen. For better help sooner, post an SSCCE. It also seems this problem is screaming out for some basic tracing of code lines and display of sizes. Commented Jan 20, 2013 at 0:25

5 Answers 5

16
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);
Sign up to request clarification or add additional context in comments.

1 Comment

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).
1

Changed to:

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

and it works! Thanks for help anyway

Comments

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

4 Comments

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?
I would recommend adding JDK source to an IDE like eclipse and using the debugger to check the variable values. That's much faster.
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.
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.

Comments

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

2 Comments

Please add an explanation.
As @SamirChen mentioned, you have red, green, blue, pixels in width. so actual width is 3 times the image width.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.