6

I am working with Bitmap C# and wondering how to convert a color png image to only one color. I want all the visible colors in the image to become white. The parts that are transparent should remain transparent. I am going to display these agains a grey background.

Cloudanger
  • 9,194
  • 2
  • 22
  • 18
jesperlind
  • 2,092
  • 2
  • 20
  • 22
  • possible duplicate of [GDI+: Set all pixels to given color while retaining existing alpha value](http://stackoverflow.com/questions/2510013/gdi-set-all-pixels-to-given-color-while-retaining-existing-alpha-value) – Hans Passant Aug 01 '10 at 17:10
  • Is there anything I could add to my answer, since you haven't accepted any answer? – Cloudanger Aug 13 '10 at 19:33
  • Hi and sorry for late reply. I tried out the code right now and I can't make it work. All my pixels turns white and it doesn't leave the transparent pixels of the png's intact. – jesperlind Aug 16 '10 at 22:07

4 Answers4

7

If the image doesn't use alpha channel for transparency then the following will do:

Bitmap image;

for (int x = 0; x < image.Width; x++)
{
    for (int y = 0; y < image.Height; y++)
    {
        if (image.GetPixel(x, y) != Color.Transparent)
        {
            image.SetPixel(x, y, Color.White);
        }
    }
}
Cloudanger
  • 9,194
  • 2
  • 22
  • 18
7

The other answers was helpful and got me going, thanks a lot. I couldn't make them work though, not sure why. But I also found out that I wanted to keep the original alpha value of the pixels, rendering the edges smooth. This is what I came up with.

for (int x = 0; x < bitmap.Width; x++)
{
    for (int y = 0; y < bitmap.Height; y++)
    {
        Color bitColor = bitmap.GetPixel(x, y);
        //Sets all the pixels to white but with the original alpha value
        bitmap.SetPixel(x, y, Color.FromArgb(bitColor.A, 255, 255, 255));
    }
}

Here is a screen dump of the result magnified a few times (original on top): alt text
(source: codeodyssey.se)

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
jesperlind
  • 2,092
  • 2
  • 20
  • 22
4

SetPixel is just about the slowest possible way to do that. You can use a ColorMatrix instead:

var newImage = new Bitmap(original.Width, original.Height,
                          original.PixelFormat);

using (var g = Graphics.FromImage(newImage)) {
    var matrix = new ColorMatrix(new[] {
        new float[] { 1.0f, 0.0f, 0.0f, 0.0f, 0.0f },
        new float[] { 0.0f, 1.0f, 0.0f, 0.0f, 0.0f },
        new float[] { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f },
        new float[] { 0.0f, 0.0f, 0.0f, 1.0f, 0.0f },
        new float[] { 1.0f, 1.0f, 1.0f, 0.0f, 1.0f }
    });

    var attributes = new ImageAttributes();

    attributes.SetColorMatrix(matrix);

    g.DrawImage(original,
                new Rectangle(0, 0, original.Width, original.Height),
                0, 0, original.Width, original.Height,
                GraphicsUnit.Pixel, attributes);
}
Ry-
  • 218,210
  • 55
  • 464
  • 476
  • Certainly more elegant, with the added benefit of requiring one learn an entire new Color Space, a new concept of color manipulation, and using that new knowledge to understand what you just did. :) I love it! – Jesse Chisholm Feb 23 '15 at 19:02
  • PS: Your C# syntax is fine, as long as `using System.Drawing;` and `using System.Drawing.Imaging;` are in place. – Jesse Chisholm Feb 23 '15 at 19:14
1

try following code:

    void Test()
    {
        Bitmap bmp = new Bitmap(50, 50);//you will load it from file or resource

        Color c = Color.Green;//transparent color

        //loop height and width. 
        // YOU MAY HAVE TO CONVERT IT TO Height X VerticalResolution and
        // Width X HorizontalResolution
        for (int i = 0; i < bmp.Height; i++)
        {
            for (int j = 0; j < bmp.Width; j++)
            {
                var p = bmp.GetPixel(j, i);//get pixle at point

                //if pixle color not equals transparent
                if(!c.Equals(Color.FromArgb(p.ToArgb())))
                {
                    //set it to white
                    bmp.SetPixel(j,i,Color.White);
                }
            }
        }
    }

PS: this is not tested and in no way optimized

TheVillageIdiot
  • 40,053
  • 20
  • 133
  • 188