0

I go through a bitmap in android and i want to get a the color of each pixel and count it if it has a certain value i.e if it is brown.

I use the following code. The code works but it is extremely slow due to the big number of pixels in the image, which of course I need for correct results.

for(int i =  1; i <= 100; i++){
    for(int j = 1; j <= 100; j++) {
        int pixel =  bitmap.getPixel(i,j);

        R1 = Color.red(pixel);
        G1 = Color.green(pixel);
        B1 = Color.blue(pixel);

        if((R1 == 155) && (G1 == 155) && (B1 == 155)) {
            countthecolor = countthecolor + 1;
        }
    }    
}          
Bryan Herbst
  • 66,602
  • 10
  • 133
  • 120

2 Answers2

2

You can try to use getPixels which returns a large array of length = bitmap.width * bitmap.height.

Then you can loop through this array and perform your operation. This will be a little faster however, now you will have to manage your memory since you already have the bitmap and now this array in the memory. So I recommend to recycle the bitmap if you don't need it anymore.

int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), x, y, myBitmap.getHeight(), myBitmap.getWidth());

You can further optimize your loop using bitwise operations to get the individual RGB values (note for alpha may or may not be there):

            Alpha = (pixel & 0xff000000)  
            R1 = (pixel >> 16) & 0xff;
            G1 = (pixel >> 8) & 0xff;
            B1 = (pixel & 0xff);

May want to take a look at this!

Community
  • 1
  • 1
Amulya Khare
  • 7,718
  • 2
  • 23
  • 38
  • You can also use `getPixels` to grab a row at a time using the `height` and `offset` parameters. This won't be as fast as reading the whole thing in at once, but it will alleviate most memory concerns. – Geobits Oct 18 '13 at 16:50
  • I failed to mention this operation takes place on a frame preview. onPreviewFrame(byte[] data, Camera mCamera) So is this going to be fast enough? – user2068874 Oct 18 '13 at 16:51
  • It will be *much* faster than reading individuals pixels, either way. "Fast enough" depends on how fast you need it. Give a shot and see. – Geobits Oct 18 '13 at 16:52
  • I will try. i will need to use a loop to go through the array, right? – user2068874 Oct 18 '13 at 17:09
  • It works and it takes just the 1/3 of time. I guess i will use coding to get is with less time. Thanks a lot. – user2068874 Oct 18 '13 at 19:17
  • You should mark it `answered` if your problem is resolved and the answer helped you. – Amulya Khare Oct 19 '13 at 17:06
  • For the alpha value, use `pixel >>> 24` instead of `(pixel & 0xff000000)` (which by the way doesn't give you a value between 0 and 255). Also use the `>>>` logical shift operator here, otherwise you get `-1` for 255 alpha value – tonix Dec 10 '17 at 13:47
0

Calling getPixel for each each pixel will take a while. getPixels will let you perform calculations on a row of pixels at once.

f2prateek
  • 2,034
  • 2
  • 20
  • 26