Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

replace color in an image in c#

What is the way in C# to replace a color for some parts of an image without affecting its texture?

You can see good example of the result here
Thanks

like image 738
Oren Avatar asked Mar 26 '12 11:03

Oren


4 Answers

One way to efficiently replace a color is to use a remap table. In the following example, an image is drawn inside a picture box. In the Paint event, the color Color.Black is changed to Color.Blue:

private void pictureBox_Paint(object sender, PaintEventArgs e)
{
    Graphics g = e.Graphics;
    using (Bitmap bmp = new Bitmap("myImage.png"))
    {

        // Set the image attribute's color mappings
        ColorMap[] colorMap = new ColorMap[1];
        colorMap[0] = new ColorMap();
        colorMap[0].OldColor = Color.Black;
        colorMap[0].NewColor = Color.Blue;
        ImageAttributes attr = new ImageAttributes();
        attr.SetRemapTable(colorMap);
        // Draw using the color map
        Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);
        g.DrawImage(bmp, rect, 0, 0, rect.Width, rect.Height, GraphicsUnit.Pixel, attr);
    }
}

More information: http://msdn.microsoft.com/en-us/library/4b4dc1kz%28v=vs.110%29.aspx

like image 114
jcibar Avatar answered Oct 21 '22 07:10

jcibar


Upon doing research i found no efficient/smoothe way of doing this, so i dont it myself, the code could be cleaned up ALOT but it gets the job done, its not efficient but it is smoother and allows you to set a tolerance.

public static Image ColorReplace(this Image inputImage, int tolerance, Color oldColor, Color NewColor)
    {
        Bitmap outputImage = new Bitmap(inputImage.Width, inputImage.Height);
        Graphics G = Graphics.FromImage(outputImage);
        G.DrawImage(inputImage, 0, 0);
        for (Int32 y = 0; y < outputImage.Height; y++)
            for (Int32 x = 0; x < outputImage.Width; x++)
            {
                Color PixelColor = outputImage.GetPixel(x, y);
                if (PixelColor.R > oldColor.R - tolerance && PixelColor.R < oldColor.R + tolerance && PixelColor.G > oldColor.G - tolerance && PixelColor.G < oldColor.G + tolerance && PixelColor.B > oldColor.B - tolerance && PixelColor.B < oldColor.B + tolerance)
                {
                    int RColorDiff = oldColor.R - PixelColor.R;
                    int GColorDiff = oldColor.G - PixelColor.G;
                    int BColorDiff = oldColor.B - PixelColor.B;

                    if (PixelColor.R > oldColor.R) RColorDiff = NewColor.R + RColorDiff;
                    else RColorDiff = NewColor.R - RColorDiff;
                    if (RColorDiff > 255) RColorDiff = 255;
                    if (RColorDiff < 0) RColorDiff = 0;
                    if (PixelColor.G > oldColor.G) GColorDiff = NewColor.G + GColorDiff;
                    else GColorDiff = NewColor.G - GColorDiff;
                    if (GColorDiff > 255) GColorDiff = 255;
                    if (GColorDiff < 0) GColorDiff = 0;
                    if (PixelColor.B > oldColor.B) BColorDiff = NewColor.B + BColorDiff;
                    else BColorDiff = NewColor.B - BColorDiff;
                    if (BColorDiff > 255) BColorDiff = 255;
                    if (BColorDiff < 0) BColorDiff = 0;

                    outputImage.SetPixel(x, y, Color.FromArgb(RColorDiff, GColorDiff, BColorDiff));
                }
            }
        return outputImage;
    }
like image 6
Ricky Divjakovski Avatar answered Oct 21 '22 05:10

Ricky Divjakovski


try this:

Color color = Color.Black; //Your desired colour

byte r = color.R; //For Red colour

Bitmap bmp = new Bitmap(this.BackgroundImage);
for (int x = 0; x < bmp.Width; x++)
{
    for (int y = 0; y < bmp.Height; y++)
    {
        Color gotColor = bmp.GetPixel(x, y);
        gotColor = Color.FromArgb(r, gotColor.G, gotColor.B);
        bmp.SetPixel(x, y, gotColor);
    }
}
like image 5
Alex Avatar answered Oct 21 '22 06:10

Alex


Found the way to do that, this requires RGB<->HSL conversions (good class for HSL color can be found here)
1. Get a reference value (in hsl) representing the color you want to replace
2. Get the hsl value for your target color
3. Get image pixels and for each pixel:
4. calculate the hsl value of the pixel, and replace it with (pixelHsl / refHsl) * targetHsl

This did the job for me, thanks for all who helped

like image 2
Oren Avatar answered Oct 21 '22 06:10

Oren