0

I have a program that requires going through BufferedImages pixel by pixel quite often. Normally efficiency wouldn't matter enough for me to care, but I really want every millisecond I can get.

As an example, right now, the fastest way I've found of isolating the red channel in an image looks like this:

    int[] rgb = image.getRGB(0, 0, img.getWidth(), img.getHeight(), null, 0, img.getWidth());


    for(int i = 0; i < rgb.length; i ++)
        rgb[i] = rgb[i] & 0xFFFF0000;

    image.setRGB(0, 0, img.getWidth(), img.getHeight(), rgb, 0, img.getWidth());        

Which means it's going through the image once to populate the array, again to apply the filter, and finally a third time to update the pixels. Also considering that any pixel with an alpha channel of 0 gets completely zeroed out, It must be going through it at least one more time as well.

I've also tried using the individual pixel versions of getRGB() and setRGB() in a more traditional nested for loop, but that's even slower (though probably takes far less RAM since it doesn't have the int[]).

This is the kind of problem that Iterable types solve, but I can't find any way of applying that principle to images. For this project, I'm okay with total hacks that aren't "best practices" if it works.

Is there any way of iterating over the raw data of a buffered image?

user3236716
  • 189
  • 1
  • 11
  • this question has already been answered. start from here http://stackoverflow.com/questions/1975824/fastest-way-to-compare-pixel-values-between-two-bufferedimages?rq=1 and go – gpasch Apr 14 '16 at 20:03
  • 1
    So I'm already doing the integer color part of that, the only thing that is really anything new is "but overall you should probably just peek into the Raster and DataBuffer for performance." Could you be a bit more specific? – user3236716 Apr 14 '16 at 20:09

1 Answers1

2

The fastest way is to access the DataBuffer because you have a direct access to the pixels value, but you have to handle all the cases/types:

public void Test(BufferedImage img)
    {
    switch ( img.getType() )
        {
        case BufferedImage.TYPE_BYTE_GRAY :
        case BufferedImage.TYPE_3BYTE_BGR :
            byte[] bufferbyte = ((DataBufferByte)img.getRaster().getDataBuffer()).getData() ;
            //...
            break ;
        case BufferedImage.TYPE_USHORT_GRAY :
            short[] buffershort = ((DataBuffer)img.getRaster().getDataBuffer()).getData() ;
            //...
            break ;
        //Other cases
        }
    }
FiReTiTi
  • 5,597
  • 12
  • 30
  • 58