Convert a White/Grayscale image to a Color and vice-versa

There are many examples out there on how to convert a picture to gray-scale in C#, but what about doing the right opposite?

Read my article on how to convert HTML color code to System.Drawing.Color and System.Drawing.Imaging.ColorMatrix in C#.

The HTML color code used in the examples are #DFD29B and #04CEFF respectively.

Before After

Color Shading

This method is fast and uses a ColorMatrix to perform the conversion. A ColorMatrix is a 5×5 matrix that can make just about any modifications to the colors of an image. I call this technique, Color Shading.

Have said that, if you want to change only some of the colors of a picture, you must have the rest in full Transparency. In my example, the goal is to change the colors of a shirt, therefore the background is transparent.

Partially change the color of an image in C#

If your intention is to change the color of a particular part of an image only, please refer to this other article for a solution.

 

public static System.IO.MemoryStream ShadeColor(byte[] imageContent, System.Drawing.Color newColor)
{
    if (imageContent == null || imageContent.Length == 0)
        return null;

    //convert bytes to bitmap
    var bitmap = new System.Drawing.Bitmap(new System.IO.MemoryStream(imageContent));

    //create the Graphics object
    var g = System.Drawing.Graphics.FromImage(bitmap);

    g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
    g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;

    var colorMatrix = ToColorMatrix(newColor); //refer to my other article for this method

    //create the image attributes
    var attributes = new System.Drawing.Imaging.ImageAttributes();

    //set the color matrix attribute
    attributes.SetColorMatrix(colorMatrix);

    g.DrawImage(bitmap,
        new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height),
        0, 0, bitmap.Width, bitmap.Height,
        System.Drawing.GraphicsUnit.Pixel, attributes);

    //save bitmap
    var imageResult = new System.IO.MemoryStream(bitmap.Width * bitmap.Height);
    bitmap.Save(imageResult, System.Drawing.Imaging.ImageFormat.Png);

    return imageResult;

}

public static System.IO.MemoryStream ShadeColor(byte[] imageContent, string htmlColorCode)
{
    return ShadeColor(imageContent, ToColor(htmlColorCode));
}

public static System.Drawing.Color ToColor(string newColorInHtml)
{
    var newColor = System.Drawing.Color.Transparent;
    if (!string.IsNullOrWhiteSpace(newColorInHtml))
    {
        if (newColorInHtml[0] != '#')
            newColorInHtml = "#" + newColorInHtml;

        newColor = System.Drawing.ColorTranslator.FromHtml(newColorInHtml);
    }

    return newColor;
}

public static System.Drawing.Imaging.ColorMatrix ToColorMatrix(System.Drawing.Color color)
{
    //convert the RGB values to scale of 0-1
    float r = (1.0f / 255) * color.R;
    float b = (1.0f / 255) * color.B;
    float g = (1.0f / 255) * color.G;

    var colorMatrix = new System.Drawing.Imaging.ColorMatrix(
        new float[][]
{
    new float[] {r, g, b, 0, 0},
    new float[] {0,  0,  0,  0, 0},
    new float[] {0,  0, 0,  0, 0},
    new float[] {0,  0,  0,  1, 0},
    new float[] {0, 0, 0, 0, 1}
});

    return colorMatrix;
}

You can also convert the image to grayscale by switching the colorMatrix variable to:

var colorMatrix = new System.Drawing.Imaging.ColorMatrix(
    new float[][]
        {
            new float[] {.3f, .3f, .3f, 0, 0},
            new float[] {.59f, .59f, .59f, 0, 0},
            new float[] {.11f, .11f, .11f, 0, 0},
            new float[] {0, 0, 0, 1, 0},
            new float[] {0, 0, 0, 0, 1}
        });

 

 
You can download the entire source code for this here: http://bit.ly/XhZ0qx (zip file)

 

Advertisements

5 thoughts on “Convert a White/Grayscale image to a Color and vice-versa

  1. Hi
    the code is not working for transparent images. I tried with your hoodie images but the blue one’s background became black.

    For jpgs half of the picture color is changing. the rest remains old color.

    Could you explain why i faced this problem. Thanks

  2. Hi
    I set image type jpg so the background is black. Its not your fault but you must change the line:

    g.DrawImage(bitmap, new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), 0, 0, bitmap.Width, bitmap.Height, System.Drawing.GraphicsUnit.Pixel, attributes);

    You write bitmap.Width twice.

    take care.

    PS: You can delete my comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s