6

I want to change image to Black-White or Sepia. After converting the image i want to replace the existing image with the converted image.

Please give me some suggestion.

casperOne
  • 73,706
  • 19
  • 184
  • 253
munish
  • 61
  • 1
  • 1
  • 2

5 Answers5

11

There are many ways to desaturate a color image. In fact, there is probably no one "true" or "correct" way to do it, though some ways 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 convex weights (non-negative weights that sum to 1) will give different results some of which may be considered more aesthetically pleasing, and some may take into consideration perceptual parameters. (YUV uses these weights: Y = 0.299*R + 0.587*G + 0.114*B)

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.

Duplicating these grayscale channels into RGB will give you a 3-channel desaturated "color" image - where all 3 RGB channels are identical.

Once you have this 3-channel (RGB) desaturated image, you can multiply each channel by a seprate weight to colorize the image - a sepia image.

Given a gray pixel [v,v,v], colorize it like so: [v*a, v*b, v*c], such that 0 <= a,b,c <=1.

Adi Shavit
  • 16,743
  • 5
  • 67
  • 137
3

Here I found good answer: https://social.msdn.microsoft.com/Forums/vstudio/en-US/1d6b5960-c509-433c-b000-c885b8c727c4/how-to-convert-an-image-to-black-and-white-not-grayscale?forum=csharpgeneral&prof=required

var color = new Bitmap("file.jpg");
var bw = color.Clone(new Rectangle(0, 0, color.Width, color.Height), 
      PixelFormat.Format1bppIndexed);
Danil
  • 701
  • 8
  • 7
  • This conversion is good, fast (the methods `GetPixel`/`SetPixel` are wery slow), and simple, but has two major problems. The black/white (1 pixel) conversion has terrible results and when you have a transparent background in the source image, this will turn to black. The second problem is that the file (`file.jpg` in this case) will be locked even when the `Dispose` method was already called on ˙color˙ image. It is better to use the `DrawImage` method in graphics. (This comment is not for Serov Danil, but for other fellow programmers) – Julo Oct 28 '19 at 10:04
2
// Loop through the images pixels to reset color.
for(x=0; x<image1.Width; x++)
{
    for(y=0; y<image1.Height; y++)
    {
        Color pixelColor = image1.GetPixel(x, y);
        int grayScale = (int)((originalColor.R * .3) + 
            (originalColor.G * .59) + (originalColor.B * .11));

        //create the color object
        Color newColor =  Color.FromArgb(grayScale, grayScale, grayScale);
            image1.SetPixel(x, y, newColor);
    }
}

Convert color pixel to grayscale using this

Gray = Green * 0.59 + Blue * 0.11 + Red * 0.30;
casperOne
  • 73,706
  • 19
  • 184
  • 253
hungryMind
  • 6,931
  • 4
  • 29
  • 45
  • Why those values to multiply the components? Does that give sepia? I suspect it does, but an explanation would be useful. – ChrisF Jan 07 '11 at 12:10
  • Red (255,0,0) Green (0,255,0) Blue (0,0,255) Together they make white color which is 255,255,255. If you calculate using above formula using pure RGB, it results close to 255. – hungryMind Jan 07 '11 at 14:07
2

For sepia you want to convert to greyscale first. Then simply multiply each pixel by a set scaling triplet such as [1, 0.95, 0.82] you can play around with this triplet to get the right look... so the code might be...

for(x=0; x<image1.Width; x++)     
{         
    for(y=0; y<image1.Height; y++)         
    {             
        Color pixelColor = image1.GetPixel(x, y);             

        int grayScale = (int)((originalColor.R * .3) + (originalColor.G * .59) + (originalColor.B * .11));              
        //create the color object             
        Color newColor =  Color.FromArgb(grayScale, grayScale, grayScale);             

        //now apply a sepia filter
        pixelColor.R = newColor.R*1;
        pixelColor.G = newColor.G*0.95;
        pixelColor.B = newColor.B*0.82;

        image1.SetPixel(x, y, pixelColor);
     }
 }
nawfal
  • 70,104
  • 56
  • 326
  • 368
Rob McFeely
  • 2,823
  • 8
  • 33
  • 50
1
private Bitmap grayscale(Image image)
{
    Bitmap btm = new Bitmap(image);
    for (int i = 0; i < btm.Width; i++)
    {
        for (int j = 0; j < btm.Height; j++)
        {
            int ser = (btm.GetPixel(i, j).R + btm.GetPixel(i, j).G + btm.GetPixel(i, j).B) / 3;
            btm.SetPixel(i, j, Color.FromArgb(ser, ser, ser));
        }
    }
    return btm;
}
Artless
  • 4,522
  • 1
  • 25
  • 40
Sultan
  • 319
  • 3
  • 11