10

Possible Duplicate:
convert image to Black-White or Sepia in c#

I'm writing a C# application, that opens an image, and clicking on a button, displays it in only black and white! I was sure to find a lot of information on the net, but my searches didn't give me a lot of understandable and useful information.

I have no idea of how to proceed. Does any one have any advice ? Know a tutorial on the net?

Community
  • 1
  • 1
Flo
  • 251
  • 1
  • 3
  • 6

2 Answers2

26

I once found a function that converts a bitmap to grayscale

public void ToGrayScale(Bitmap Bmp)
{
    int rgb;
    Color c;

    for (int y = 0; y < Bmp.Height; y++)
    for (int x = 0; x < Bmp.Width; x++)
    {
        c = Bmp.GetPixel(x, y);
        rgb = (int)Math.Round(.299 * c.R + .587 * c.G + .114 * c.B);
        Bmp.SetPixel(x, y, Color.FromArgb(rgb, rgb, rgb));
    }
}

The function accepts a bitmap as a parameter, and changes it to its grayscale version.

I hope this helps.

Gaspa79
  • 4,404
  • 2
  • 34
  • 59
Jón Trausti Arason
  • 4,021
  • 1
  • 30
  • 45
  • 16
    (c.R + c.G + c.B) / 3 - makes picture gray but result bitmap is not correct. You should use: (c.R * .3) + (c.G * .59) + (c.B * .11). Or as in A_Nablsi answer: (.299 * c.R + .587 * c.G + .114 * c.B). – petro.sidlovskyy Jan 12 '11 at 13:42
  • 2
    Useful function, but just want to point out that it is misleading to return Bmp, as the contents of the Bmp parameter are modified anyway. Caught me out, as I assumed the function was returning a new bitmap. – Surfbutler Oct 27 '15 at 14:33
  • 1
    For literal black/white: rgb = (int)(Math.Round(((double)(c.R + c.G + c.B) / 3.0) / 255) * 255); – Zachary Canann Jul 18 '17 at 02:37
  • This worked but didn't maintain transparency - this one did though: https://stackoverflow.com/questions/3053889/how-to-convert-32-bit-rgba-image-to-grayscale-preserving-alpha#comment94710683_3054357 – Christopher D. Emerson Dec 26 '18 at 17:41
1

Edit See fuller answer here: convert image to Black-White or Sepia in c#.

There are many way to desaturate a color image. In fact, there is probably no one "true" or "correct" way to do it, though some way are more correct than others.
I assume that your image is in RGB (Red-Green-Blue) format (though BGR is also common).

The simplest way, which should work for most photos (but less so for synthetic images), is to just use the Green channel of the 3 RGB channels. Humans are most sensitive to variations in the green part of the spectrum, so the green channel covers most of the visible range and is a good approximation to the grayscale image you want.

A better way to generate a grayscale image is to use a weighted average of the 3 RGB channels. Choosing equal weights (0.33*R+0.33*G+0.33*B) will give a pretty good grayscale image. Other weight will give different results some of which may be considered more aesthetically pleasing, and some may take into consideration perceptual parameters.

You could always convert the image to another color space which has only a single grayscale channel (and 2 "color" channels), such as HSV (V is the grayscale), YUV (Y is the grayscale) or Lab (L is the grayscale). The differences should not be very big.

The term "de-saturation" comes from the HSV space. If you convert you image to HSV, set the S channel (Saturation) to be all zeros, and render the image, you will get a 3-channel desaturated "color" image.

Community
  • 1
  • 1
Adi Shavit
  • 15,030
  • 2
  • 55
  • 121
  • Thanks for the comment ! I used another way, more simple, but yours should be usable in other cases, so I keep it with me! – Flo Jan 12 '11 at 14:45