Requires a faster way to get the RGB value for each pixel of the buffered image

What is the fastest way to get the RGB value for each pixel of a BufferedImage ?

I am currently getting RGB values ​​using two for , as shown in the code below, but it took too long to get these values, since the nested loop works a total of 479999 times for my image. If I use a 16-bit image, this number will be even higher!

I need a faster way to get pixel values.

Here is the code I'm trying to work with:

 BufferedImage bi=ImageIO.read(new File("C:\\images\\Sunset.jpg")); int countloop=0; for (int x = 0; x <bi.getWidth(); x++) { for (int y = 0; y < bi.getHeight(); y++) { Color c = new Color(bi.getRGB(x, y)); System.out.println("red=="+c.getRed()+" green=="+c.getGreen()+" blue=="+c.getBlue()+" countloop="+countloop++); } } 
+7
source share
5 answers

I don't know if this can help, and I have not tested it yet, but you can get the rgb values ​​as follows:

 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 do not need to initialize a new color inside the loop. I also inverted the width / height loops, as suggested by onemasse, to get a counter from the data that I already have.

+12
source

Moving from one getRGB group to one large getRGB to copy the entire image into an array, the execution time decreased by an order of 33,000 milliseconds to 3200 milliseconds, and the time it created an array was only 31 milliseconds. Del>

There is no doubt that one large read into the array and direct indexing of the array is much faster than many individual reads.

The performance difference is due to the use of the breakpoint operator at the end of the class. While the breakpoint was outside the loop, each line of code inside the class seems to be tested for a breakpoint. Switching to individual techniques DOES NOT improve speed.

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

Old reading instruction

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

Read instruction to copy bitmap to array

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

GetRGB into the array places all 3 color values ​​in one element of the array, so the individual colors must be extracted by rotation and "and". The y coordinate should be multiplied by the width of the image.

Code for reading individual colors from an array

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

You should loop the rows in the outer loop and the columns inside. This way you avoid cache misses.

+3
source

Have you tried 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()]) 

I didn’t try, so I’m not sure if it’s faster.

change Looking at @ code, it probably isn’t, but it's worth taking a picture.

+2
source

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); } } 
0
source

All Articles