locked
Know if a Color is dark or light RRS feed

  • Question

  • Hi all. I'm building a WPF app, where my Windows have a title bar, and my user can select their color.

    What I want to do now is to automatically set the title bar's text color according to the user selected background color. I though about setting the text color to black if the background is light, and to white if the background is dark. Is there any way to "know" if a color is dark or light? What are your suggestions on how to implement this?

    I also though about inverting the color (substracting #FFFFFF from it), but the if the user selects a color about in the middle, the inverted color would be about the same.

    Any other ideas?

    Thanks in advance.
    :. HUGONNE .: Please mark as answer if the post helps. Coding tips - http://hugonne.blogspot.com/
    Friday, March 5, 2010 1:32 PM

Answers

  • If bright > .5 then bright = 0: Else bright = 1
    If sat > .5 then sat = 0: Else sat = 1
    hue = 360 - hue
    • Marked as answer by Hugonne Friday, March 5, 2010 7:34 PM
    Friday, March 5, 2010 3:46 PM
  • System.Windows.Media.Color doesn't have the handy GetSaturation, GetHue, GetBrightness methods that System.Drawing.Color does. So I stole the code and implemented them as extension methods for you.

    if (color.GetBrightness() > 0.1)
       // use dark color like black
    else
       // use bright color like white

    namespace System.Windows.Media
    {
        internal static class ColorExtensions
        {
            public static float GetBrightness(this Color color)
            {
                float num = ((float)color.R) / 255f;
                float num2 = ((float)color.G) / 255f;
                float num3 = ((float)color.B) / 255f;
                float num4 = num;
                float num5 = num;
                if (num2 > num4)
                    num4 = num2;
                if (num3 > num4)
                    num4 = num3;
                if (num2 < num5)
                    num5 = num2;
                if (num3 < num5)
                    num5 = num3;
                return ((num4 + num5) / 2f);
            }
    
            public static float GetHue(this Color color)
            {
                if ((color.R == color.G) && (color.G == color.B))
                    return 0f;
                float num = ((float)color.R) / 255f;
                float num2 = ((float)color.G) / 255f;
                float num3 = ((float)color.B) / 255f;
                float num7 = 0f;
                float num4 = num;
                float num5 = num;
                if (num2 > num4)
                    num4 = num2;
                if (num3 > num4)
                    num4 = num3;
                if (num2 < num5)
                    num5 = num2;
                if (num3 < num5)
                    num5 = num3;
                float num6 = num4 - num5;
                if (num == num4)
                    num7 = (num2 - num3) / num6;
                else if (num2 == num4)
                    num7 = 2f + ((num3 - num) / num6);
                else if (num3 == num4)
                    num7 = 4f + ((num - num2) / num6);
                num7 *= 60f;
                if (num7 < 0f)
                    num7 += 360f;
                return num7;
            }
    
            public static float GetSaturation(this Color color)
            {
                float num = ((float)color.R) / 255f;
                float num2 = ((float)color.G) / 255f;
                float num3 = ((float)color.B) / 255f;
                float num7 = 0f;
                float num4 = num;
                float num5 = num;
                if (num2 > num4)
                    num4 = num2;
                if (num3 > num4)
                    num4 = num3;
                if (num2 < num5)
                    num5 = num2;
                if (num3 < num5)
                    num5 = num3;
                if (num4 == num5)
                    return num7;
                float num6 = (num4 + num5) / 2f;
                if (num6 <= 0.5)
                    return ((num4 - num5) / (num4 + num5));
                return ((num4 - num5) / ((2f - num4) - num5));
            }
        }
    }
    
    • Marked as answer by Hugonne Friday, March 5, 2010 7:33 PM
    Friday, March 5, 2010 4:07 PM

All replies

  • public static Color AntonymColor(Color c){    return  Color.FromArgb(255 - c.R, 255 - c.G, 255 - c.B);}

    My Blog - MSDN Complement by providing Visual C# Walkthroughs and Sample Codes - Founded In February 24, 2010
    Friday, March 5, 2010 2:12 PM
  • Thanks. That code would get me the opposite color, but it wouldn't work fine on "intermediate" colors, like RGB (176, 176, 176), because the difference would result in a very similar color.
    :. HUGONNE .: Please mark as answer if the post helps. Coding tips - http://hugonne.blogspot.com/
    Friday, March 5, 2010 3:22 PM
  • If bright > .5 then bright = 0: Else bright = 1
    If sat > .5 then sat = 0: Else sat = 1
    hue = 360 - hue
    • Marked as answer by Hugonne Friday, March 5, 2010 7:34 PM
    Friday, March 5, 2010 3:46 PM
  • System.Windows.Media.Color doesn't have the handy GetSaturation, GetHue, GetBrightness methods that System.Drawing.Color does. So I stole the code and implemented them as extension methods for you.

    if (color.GetBrightness() > 0.1)
       // use dark color like black
    else
       // use bright color like white

    namespace System.Windows.Media
    {
        internal static class ColorExtensions
        {
            public static float GetBrightness(this Color color)
            {
                float num = ((float)color.R) / 255f;
                float num2 = ((float)color.G) / 255f;
                float num3 = ((float)color.B) / 255f;
                float num4 = num;
                float num5 = num;
                if (num2 > num4)
                    num4 = num2;
                if (num3 > num4)
                    num4 = num3;
                if (num2 < num5)
                    num5 = num2;
                if (num3 < num5)
                    num5 = num3;
                return ((num4 + num5) / 2f);
            }
    
            public static float GetHue(this Color color)
            {
                if ((color.R == color.G) && (color.G == color.B))
                    return 0f;
                float num = ((float)color.R) / 255f;
                float num2 = ((float)color.G) / 255f;
                float num3 = ((float)color.B) / 255f;
                float num7 = 0f;
                float num4 = num;
                float num5 = num;
                if (num2 > num4)
                    num4 = num2;
                if (num3 > num4)
                    num4 = num3;
                if (num2 < num5)
                    num5 = num2;
                if (num3 < num5)
                    num5 = num3;
                float num6 = num4 - num5;
                if (num == num4)
                    num7 = (num2 - num3) / num6;
                else if (num2 == num4)
                    num7 = 2f + ((num3 - num) / num6);
                else if (num3 == num4)
                    num7 = 4f + ((num - num2) / num6);
                num7 *= 60f;
                if (num7 < 0f)
                    num7 += 360f;
                return num7;
            }
    
            public static float GetSaturation(this Color color)
            {
                float num = ((float)color.R) / 255f;
                float num2 = ((float)color.G) / 255f;
                float num3 = ((float)color.B) / 255f;
                float num7 = 0f;
                float num4 = num;
                float num5 = num;
                if (num2 > num4)
                    num4 = num2;
                if (num3 > num4)
                    num4 = num3;
                if (num2 < num5)
                    num5 = num2;
                if (num3 < num5)
                    num5 = num3;
                if (num4 == num5)
                    return num7;
                float num6 = (num4 + num5) / 2f;
                if (num6 <= 0.5)
                    return ((num4 - num5) / (num4 + num5));
                return ((num4 - num5) / ((2f - num4) - num5));
            }
        }
    }
    
    • Marked as answer by Hugonne Friday, March 5, 2010 7:33 PM
    Friday, March 5, 2010 4:07 PM
  • Thaks a lot. That's really helpful. What I had done was to determine if the color was dark or light based on telling if it was closer to white or black, that is, closer to #000000 or #FFFFFF. Of course, it's a lot more accurate if I use brightness.

    Thanks again.
    :. HUGONNE .: Please mark as answer if the post helps. Coding tips - http://hugonne.blogspot.com/
    Friday, March 5, 2010 7:40 PM
  • What I had done was to determine if the color was dark or light based on telling if it was closer to white or black, that is, closer to #000000 or #FFFFFF.
    To use only white or black, that should be adequate:

    Color
     cComp = (384 - c.R - c.G - c.B) > 0 ? Color.White : Color.Black;
    Friday, March 5, 2010 9:16 PM