1

In this question ("get pixel array from image") the answer was to get the data of the raster:

int[] pixels = ((DataBufferInt) bufferedImage.getRaster().getDataBuffer()).getData();

However, when you use this for sub images it will return the data array of the base image:

Returns a subimage defined by a specified rectangular region. The returned BufferedImage shares the same data array as the original image.

The methods getTileGridXOffset() and getTileGridYOffset() return the offset despite being described as

Returns the x offset of the tile grid relative to the origin, For example, the x coordinate of the location of tile (0, 0). This is always zero.

but it looks like the field scanlineStride of the raster which would be required to get the index in the array cannot be accessed.


Other solutions

Would it be faster and easier then to use getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize)?


Concrete example

BufferedImage baseBufferedImage = new BufferedImage(2048, 2048, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics = baseBufferedImage.createGraphics();
graphics.setColor(Color.BLUE);
graphics.fillRect(512, 512, 100, 100);
graphics.dispose();

BufferedImage subBufferedImage = baseBufferedImage.getSubimage(512, 512, 100, 100);
int[] subBufferedImageData = ((DataBufferInt) subBufferedImage.getRaster().getDataBuffer()).getData();
// This is not 255 despite the pixel at 0,0 in subBufferedImage being blue
System.out.print(subBufferedImageData[0] & 0xFF);
Community
  • 1
  • 1
Marcono1234
  • 5,856
  • 1
  • 25
  • 43
  • why dont you time these?? you got all the info what's your point of contention?? you want us to repeat the same answers over and over ?? – gpasch Sep 09 '16 at 01:34
  • 1
    @gpasch If you feel this question is a duplicate, why don't you flag is as such? The OP's problem is clearly stated, and thus possible to answer. If you are unhappy with the question, don't downvote the answer. – Harald K Sep 10 '16 at 17:43

1 Answers1

1

If you need the sub image (as a BufferedImage), you can do:

BufferedImage subBufferedImage = baseBufferedImage.getSubimage(512, 512, 100, 100);
// NOTE: getData() creates a copy of the raster/databuffer in contrast to getRaster()
int[] subBufferedImageData = ((DataBufferInt) subBufferedImage.getData(new Rectangle(0, 0, 100, 100)).getDataBuffer()).getData();
System.out.print(subBufferedImageData[0] & 0xFF);

Otherwise, you can simply skip the sub image, and create a copy of the requested region of the raster directly, like this:

// Creates a copy of the sub region from the raster/databuffer
int[] subBufferedImageData = ((DataBufferInt) baseBufferedImage.getData(new Rectangle(512, 512, 100, 100)).getDataBuffer()).getData();
System.out.print(subBufferedImageData[0] & 0xFF);

Both examples will print 255, and have arrays containing all blue pixels.

Wether or not you find using getRGB easier to use is completely subjective and up to you. The above code is likely to be faster, or worst case as fast (I'm leaving the actual testing to you).

Harald K
  • 26,314
  • 7
  • 65
  • 111
  • 1
    Thank you very much, I did not know about the `getData()` method, but I think you have call it with a [`Rectangle`](https://docs.oracle.com/javase/8/docs/api/java/awt/image/BufferedImage.html#getData-java.awt.Rectangle-) with the arguments you used. Do you know if this is faster than calling `getRGB(int startX, int startY, int w, int h, int[] rgbArray, int offset, int scansize)`? – Marcono1234 Sep 13 '16 at 13:52
  • Nevermind, it looks like `getRGB()` is at least four times slower – Marcono1234 Sep 13 '16 at 14:18
  • 1
    @Marcono1234 Thanks, for the heads up, and sorry about the missing `new Rectangle(...)`! Fixed the code examples now. And yes, `getData(..)` will be at least as fast as `getRGB(...)` as a *worst case* (or rather, as a best case for `getRGB(...)`), normally it's several times faster. – Harald K Sep 13 '16 at 15:50