2

I have an image loaded into a Bitmap object. What I then want to do is grayscale the image that is stored in the Bitmap object.

I do that with the following function:

public static Bitmap grayscale(Bitmap src)
{
    // constant factors
    final double GS_RED = 0.299;
    final double GS_GREEN = 0.587;
    final double GS_BLUE = 0.114;

    // create output bitmap
    Bitmap bmOut = Bitmap.createBitmap(src.getWidth(), src.getHeight(), src.getConfig());
    // pixel information
    int A, R, G, B;
    int pixel;

    // get image size
    int width = src.getWidth();
    int height = src.getHeight();

    // scan through every single pixel
    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)(GS_RED * R + GS_GREEN * G + GS_BLUE * B);

            // set new pixel color to output bitmap
            bmOut.setPixel(x, y, Color.argb(A, R, G, B));
        }
    }

    // return final image
    return bmOut;
}

It works fine, but it's incredibly slow. Not for "small" images like 640x480. But in my case images are 3264x2448. This literally takes a few seconds before the operation is complete...

So I'm wondering if scanning through each pixel like I do now is really the best way? Are there any better and faster methods to convert the colors of images?

Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110
Vivendi
  • 20,047
  • 25
  • 121
  • 196
  • possible duplicate of [Convert a Bitmap to GrayScale in Android](http://stackoverflow.com/questions/3373860/convert-a-bitmap-to-grayscale-in-android) – dabhaid Jun 01 '14 at 13:35

1 Answers1

0

I doubt that scanning through every pixel is the fastest way (it's probably the slowest).

A bit refactored code from here looks promising, since it's using Android API:

public Bitmap toGrayscale(Bitmap bmpOriginal) {     
    int height = bmpOriginal.getHeight();
    int width = bmpOriginal.getWidth();   
    Bitmap bmpGrayscale = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    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
Adam Stelmaszczyk
  • 19,665
  • 4
  • 70
  • 110