Click here to Skip to main content
15,895,746 members
Articles / Desktop Programming / WPF

WPF Color Conversions

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
30 Dec 2009CPOL4 min read 61.9K   2.1K   21  
Convert from RGB to HLS and HSB.
using System;
using System.Globalization;
using System.Text;
using System.Windows.Media;

namespace WpfRgbHslConversions
{
    class Program
    {
        /* Color conversion algorithms are tasken from
         * http://130.113.54.154/~monger/hsl-rgb.html. */

        #region Structs

        struct ColorHls
        {
            public double H;
            public double L;
            public double S;
            public double A;
        }

        #endregion

        #region Main Program

        static void Main(string[] args)
        {
            var hexIn = "#FF7E188C";
            var rgbColor = HexToRgb(hexIn);

            Console.WriteLine("Hex in = {0}", hexIn);
            Console.WriteLine();

            Console.WriteLine("*** RGB IN ***");
            Console.WriteLine("R={0}", rgbColor.R);
            Console.WriteLine("G={0}", rgbColor.G);
            Console.WriteLine("B={0}", rgbColor.B);
            Console.WriteLine("A={0}", rgbColor.A);
            Console.WriteLine();

            var hlsColor = RgbToHls(rgbColor);

            Console.WriteLine("*** HLS OUT ***");
            Console.WriteLine("H={0}", hlsColor.H.ToString("#"));
            Console.WriteLine("L={0}", hlsColor.L.ToString("P0"));
            Console.WriteLine("S={0}", hlsColor.S.ToString("P0"));
            Console.WriteLine("A={0}", hlsColor.A.ToString("P0"));
            Console.WriteLine();

            rgbColor = HlsToRgb(hlsColor);

            Console.WriteLine("*** RGB OUT ***");
            Console.WriteLine("R={0}", rgbColor.R);
            Console.WriteLine("G={0}", rgbColor.G);
            Console.WriteLine("B={0}", rgbColor.B);
            Console.WriteLine("A={0}", rgbColor.A);
            Console.WriteLine();

            var hexOut = RgbToHex(rgbColor);

            Console.WriteLine("Hex out = {0}", hexOut);
            Console.WriteLine();

            bool b = (hexOut == hexIn);
            Console.WriteLine("Hex out = hex in: {0}", b.ToString());

            Console.ReadLine();
        }

        #endregion

        #region RGB-Hex Conversions

        /// <summary>
        /// Converts a hex-string representation of an RGB color to a WPF Color object.
        /// </summary>
        /// <param name="hexRgbColor">A hex-string representation of an RGB color.</param>
        /// <returns>A WPF Color object.</returns>
        public static Color HexToRgb(string hexRgbColor)
        {
            var rgbColor = new Color();

            var s = hexRgbColor.Substring(1, 2);
            var i = Int32.Parse(s, NumberStyles.HexNumber);
            rgbColor.A = Convert.ToByte(i);

            s = hexRgbColor.Substring(3, 2);
            i = Int32.Parse(s, NumberStyles.HexNumber);
            rgbColor.R = Convert.ToByte(i);

            s = hexRgbColor.Substring(5, 2);
            i = Int32.Parse(s, NumberStyles.HexNumber);
            rgbColor.G = Convert.ToByte(i);

            s = hexRgbColor.Substring(7, 2);
            i = Int32.Parse(s, NumberStyles.HexNumber);
            rgbColor.B = Convert.ToByte(i);

            return rgbColor;
        }

        /// <summary>
        /// Converts an RGB value to a hex-string equivalent.
        /// </summary>
        /// <param name="rgbColor">The WPF Color object to convert.</param>
        /// <returns>A hex string that represents the RGB value.</returns>
        public static string RgbToHex(Color rgbColor)
        {
            StringBuilder sb = new StringBuilder("#");
            sb.Append(rgbColor.A.ToString("X"));
            sb.Append(rgbColor.R.ToString("X"));
            sb.Append(rgbColor.G.ToString("X"));
            sb.Append(rgbColor.B.ToString("X"));
            return sb.ToString();
        }

        #endregion

        #region RGB-HLS Conversions

        /// <summary>
        /// Converts a WPF RGB color to an HSL color
        /// </summary>
        /// <param name="rgbColor">The RGB color to convert.</param>
        /// <returns>An HSL color object equivalent to the RGB color object passed in.</returns>
        static ColorHls RgbToHls(Color rgbColor)
        {
            // Initialize result
            var hlsColor = new ColorHls();

            // Convert RGB values to percentages
            double r = (double)rgbColor.R / 255;
            var g = (double)rgbColor.G / 255;
            var b = (double)rgbColor.B / 255;
            var a = (double)rgbColor.A / 255;

            // Find min and max RGB values
            var min = Math.Min(r, Math.Min(g, b));
            var max = Math.Max(r, Math.Max(g, b));
            var delta = max - min;

            /* If max and min are equal, that means we are dealing with 
             * a shade of gray. So we set H and S to zero, and L to either
             * max or min (it doesn't matter which), and  then we exit. */

            //Special case: Gray
            if (max == min)
            {
                hlsColor.H = 0;
                hlsColor.S = 0;
                hlsColor.L = max;
                return hlsColor;
            }

            /* If we get to this point, we know we don't have a shade of gray. */

            // Set L
            hlsColor.L = (min + max) / 2;

            // Set S
            if(hlsColor.L < 0.5)
            {
                hlsColor.S = delta / (max + min);
            }
            else
            {
                hlsColor.S = delta / (2.0 - max - min);
            }

            // Set H
            if (r == max) hlsColor.H = (g - b) / delta;
            if (g == max) hlsColor.H = 2.0 + (b - r) / delta;
            if (b == max) hlsColor.H = 4.0 + (r - g) / delta;
            hlsColor.H *= 60;
            if (hlsColor.H < 0) hlsColor.H += 360;

            // Set A
            hlsColor.A = a;

            // Set return value
            return hlsColor;

        }

        /// <summary>
        /// Converts a WPF HSL color to an RGB color
        /// </summary>
        /// <param name="hslColor">The HSL color to convert.</param>
        /// <returns>An RGB color object equivalent to the HSL color object passed in.</returns>
        static Color HlsToRgb(ColorHls hlsColor)
        {
            // Initialize result
            var rgbColor = new Color();

            /* If S = 0, that means we are dealing with a shade 
             * of gray. So, we set R, G, and B to L and exit. */

            // Special case: Gray
            if (hlsColor.S == 0)
            {
                rgbColor.R = (byte)(hlsColor.L  * 255);
                rgbColor.G = (byte)(hlsColor.L * 255);
                rgbColor.B = (byte)(hlsColor.L * 255);
                rgbColor.A = (byte)(hlsColor.A * 255);
                return rgbColor;
            }

            double t1;
            if (hlsColor.L < 0.5)
            {
                t1 = hlsColor.L*(1.0 + hlsColor.S);
            }
            else
            {
                t1 = hlsColor.L + hlsColor.S - (hlsColor.L * hlsColor.S);
            }

            var t2 = 2.0*hlsColor.L - t1;

            // Convert H from degrees to a percentage
            var h = hlsColor.H / 360;

            // Set colors as percentage values
            var tR = h + (1.0/3.0);
            var r = SetColor(t1, t2, tR);

            var tG = h;
            var g = SetColor(t1, t2, tG);

            var tB = h - (1.0 / 3.0);
            var b = SetColor(t1, t2, tB);

            // Assign colors to Color object
            rgbColor.R = (byte)(r * 255);
            rgbColor.G = (byte)(g * 255);
            rgbColor.B = (byte)(b * 255);
            rgbColor.A = (byte)(hlsColor.A * 255);

            // Set return value
            return rgbColor;
        }

        #endregion

        #region Utility Methods

        /// <summary>
        /// Used by the HSL-to-RGB converter.
        /// </summary>
        /// <param name="t1">A temporary variable.</param>
        /// <param name="t2">A temporary variable.</param>
        /// <param name="t3">A temporary variable.</param>
        /// <returns>An RGB color value, in decimal format.</returns>
        private static double SetColor(double t1, double t2, double t3)
        {
            if (t3 < 0) t3 += 1.0;
            if (t3 > 1) t3 -= 1.0;

            double color;
            if (6.0 * t3 < 1)
            {
                color = t2 + (t1 - t2) * 6.0 * t3;
            }
            else if(2.0 * t3 < 1)
            {
                color = t1;
            }
            else if(3.0*t3 < 2)
            {
                color = t2 + (t1 - t2) * ((2.0/3.0) - t3) * 6.0;
            }
            else
            {
                color = t2;
            }

            // Set return value
            return color;
        }

        #endregion
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Foresight Systems
United States United States
David Veeneman is a financial planner and software developer. He is the author of "The Fortune in Your Future" (McGraw-Hill 1998). His company, Foresight Systems, develops planning and financial software.

Comments and Discussions