Need Faster way to get RGB value for each Pixel of a Buffered Image

给你一囗甜甜゛ 提交于 2019-12-01 04:40:29

I don't know if this might help and I haven't tested it yet but you can get the rgb values this way:

BufferedImage bi=ImageIO.read(new File("C:\\images\\Sunset.jpg"));
int[] pixel;

for (int y = 0; y < bi.getHeight(); y++) {
    for (int x = 0; x < bi.getWidth(); x++) {
        pixel = bi.getRaster().getPixel(x, y, new int[3]);
        System.out.println(pixel[0] + " - " + pixel[1] + " - " + pixel[2] + " - " + (bi.getWidth() * y + x));
    }
}

As you can see you don't have to initialize a new Color inside the loop. I also inverted the width/height loops as suggested by onemasse to retrieve the counter from data I already have.

By changing from a bunch of in individual getRGB's to one big getRGB to copy the entire image into an array, the execution time dropped by an order of magnitude from 33,000 milliseconds to 3,200 milliseconds, while the time create the array was only 31 milliseconds.

No doubt about it, one big read into an array and direct indexing of the array is much faster than many individual reads.

Performance difference appears related to the use of a breakpoint statement at the end of the class. While the breakpoint was outside the loop, every line of code within the class appears to be tested for the breakpoint. Changing to individual gets does NOT improve speed.

Since the code is still correct, the remainder of the answer may still be of use.

Old read statement

colorRed=new Color(bi.getRGB(x,y)).getRed();

Read statement to copy an bit image into an array

int[] rgbData = bi.getRGB(0,0, bi.getWidth(), bi.getHeight(), 
                null, 0,bi.getWidth());        

The getRGB into an array puts all 3 color values into a single array element, so individual colors must be extracted by rotating and an "and". The y coordinate must be multiplied by the width of the image.

Code to read individual colors out of the array

colorRed=(rgbData[(y*bi.getWidth())+x] >> 16) & 0xFF; 

colorGreen=(rgbData[(y*bi.getWidth())+x] >> 8) & 0xFF; 

colorBlue=(rgbData[(y*bi.getWidth())+x]) & 0xFF; 

You should loop the rows in the outer loop and the columns in the inner. That way you'll avoid cache misses.

Did you try BufferedImage.getRGB(int, int ,int ,int, int[] , int , int)?

Something like:

int[] rgb = bi.getRGB(0,0, bi.getWidth(), bi.getHeight(), new int[bi.getWidth() * bi.getHeight(), bi.getWidth()])

Didn't try, so not sure if it's faster.

edit Having looked @ the code, it probably isn't, but worth a shot.

I found a solution here https://alvinalexander.com/blog/post/java/getting-rgb-values-for-each-pixel-in-image-using-java-bufferedi

BufferedImage bi = ImageIO.read(new File("C:\\images\\Sunset.jpg"));

for (int x = 0; x < bi.getWidth(); x++) {
    for (int y = 0; y < bi.getHeight(); y++) {
        int pixel = bi.getRGB(x, y);
        int red = (pixel >> 16) & 0xff;
        int green = (pixel >> 8) & 0xff;
        int blue = (pixel) & 0xff;
        System.out.println("red: " + red + ", green: " + green + ", blue: " + blue);                                                                                                                                                  
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!