37

I am trying to convert color image into grayscale using the average of red, green, blue. But it comes out with errors.

Here is my code

imgWidth = myBitmap.getWidth();
imgHeight = myBitmap.getHeight();
                    
for(int i =0;i<imgWidth;i++) {
    for(int j=0;j<imgHeight;j++) {
     int s = myBitmap.getPixel(i, j)/3;
     myBitmap.setPixel(i, j, s);
    }
}
                    
ImageView img = (ImageView)findViewById(R.id.image1);
img.setImageBitmap(myBitmap);

But when I run my application on Emulator, it's force close. Any idea?

I have solved my problem use the following code:

for(int x = 0; x < width; ++x) {
            for(int y = 0; y < height; ++y) {
                // get one pixel color
                pixel = src.getPixel(x, y);
                // retrieve color of all channels
                A = Color.alpha(pixel);
                R = Color.red(pixel);
                G = Color.green(pixel);
                B = Color.blue(pixel);
                // take conversion up to one single value
                R = G = B = (int)(0.299 * R + 0.587 * G + 0.114 * B);
                // set new pixel color to output bitmap
                bmOut.setPixel(x, y, Color.argb(A, R, G, B));
            }
        }
peterh
  • 9,698
  • 15
  • 68
  • 87
Priska Aprilia
  • 1,109
  • 1
  • 12
  • 30

3 Answers3

90

You can do this too :

    ColorMatrix matrix = new ColorMatrix();
    matrix.setSaturation(0); 
    imageview.setColorFilter(new ColorMatrixColorFilter(matrix));
Sachin
  • 3,815
  • 2
  • 13
  • 26
E Player Plus
  • 1,676
  • 15
  • 19
32

Try the solution from this previous answer by leparlon:

public Bitmap toGrayscale(Bitmap bmpOriginal)
    {        
        int width, height;
        height = bmpOriginal.getHeight();
        width = bmpOriginal.getWidth();    

        Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
        Canvas c = new Canvas(bmpGrayscale);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
        paint.setColorFilter(f);
        c.drawBitmap(bmpOriginal, 0, 0, paint);
        return bmpGrayscale;
    }
Community
  • 1
  • 1
Lalit Poptani
  • 65,659
  • 21
  • 155
  • 238
14

Lalit has the most practical answer. However, you wanted the resulting grey to be the average of the red, green and blue and should set up your matrix like so:

    float oneThird = 1/3f;
    float[] mat = new float[]{
            oneThird, oneThird, oneThird, 0, 0, 
            oneThird, oneThird, oneThird, 0, 0, 
            oneThird, oneThird, oneThird, 0, 0, 
            0, 0, 0, 1, 0,};
    ColorMatrixColorFilter filter = new ColorMatrixColorFilter(mat);
    paint.setColorFilter(filter);
    c.drawBitmap(original, 0, 0, paint);

And finally, as I have faced the problem of converting an image to grayscale before - the most visually pleasing result in all cases is achieved by not taking the average, but through giving each colour different weight depending on its percieved brightness, I tend to use these values:

    float[] mat = new float[]{
            0.3f, 0.59f, 0.11f, 0, 0, 
            0.3f, 0.59f, 0.11f, 0, 0, 
            0.3f, 0.59f, 0.11f, 0, 0, 
            0, 0, 0, 1, 0,};
Jave
  • 30,389
  • 14
  • 74
  • 90