chobo2
chobo2

Reputation: 85715

How to convert Hex to RGB?

I am trying to use this to figure out if a color is light or dark

Evaluate whether a HEX value is dark or light

Now. It takes in a int

 float calcLuminance(int rgb)
 {
      int r = (rgb & 0xff0000) >> 16;
      int g = (rgb & 0xff00) >> 8;
      int b = (rgb & 0xff);

      return (r*0.299f + g*0.587f + b*0.114f) / 256;
 }

I have a hex color though.

I tried to do this

  var color = System.Drawing.ColorTranslator.FromHtml("#FFFFFF");
  int rgb = color.R + color.G + color.B;
   var a = calcLuminance(rgb);

I got 0.11725 I thought it would have to be in the range of 0-256 or something like that.

What am I doing wrong? Do I have to covert R to an int? Or am I just way off?

Upvotes: 25

Views: 59086

Answers (10)

Nil0
Nil0

Reputation: 11

When you first translated from hex to rgb one way or other...

You know the total value of rgb 3 * 256 = 768. Half of that (384) would be the turning point between white or black text color. And you do not have to complicate it more because the closer the color is at the center the less it would matter if the text is white or black.

private static string GetTextColor(string backgroundColor)
{
    string color = "000000";

    Color bg = ColorTranslator.FromHtml("#" + backgroundColor);

    if (bg.R + bg.G + bg.B < 384)
    {
        color = "FFFFFF";
    }

    return color;
}

Note that the method uses hex color without the hashtag.

Upvotes: 0

SioGabx
SioGabx

Reputation: 706

You can also convert HEX to RGB without using System.Drawing with this :

 int RGBint = Convert.ToInt32("FFD700", 16);
 byte Red = (byte)((RGBint >> 16) & 255);
 byte Green = (byte)((RGBint >> 8) & 255);
 byte Blue = (byte)(RGBint & 255);
 //Color.FromRgb(Red, Green, Blue);

Upvotes: 2

Milind Anantwar
Milind Anantwar

Reputation: 82231

You can use:

public string GenerateRgba(string backgroundColor, decimal backgroundOpacity)
{
 Color color = ColorTranslator.FromHtml(hexBackgroundColor);
 int r = Convert.ToInt16(color.R);
 int g = Convert.ToInt16(color.G);
 int b = Convert.ToInt16(color.B);
 return string.Format("rgba({0}, {1}, {2}, {3});", r, g, b, backgroundOpacity);
}

Link To original Post by jeremy clifton on git

Upvotes: 22

Xiaohuan ZHOU
Xiaohuan ZHOU

Reputation: 586

Your idea is OK, but your function is wrong, correct one is here:

int rgb = Convert.ToInt32("#FFFFFF", 16);
var a = calcLuminance(rgb);

float calcLuminance(int rgb)
{
    int r = (rgb & 0xff0000) >> 16;
    int g = (rgb & 0xff00) >> 8;
    int b = (rgb & 0xff);
    return (r*0.299f + g*0.587f + b*0.114f) / 256;
}

Upvotes: 2

Magnus
Magnus

Reputation: 46909

A little of topic, but here is an extension method to the Color struct I've created to calculate Luminance with different algorithms. Hope it helps you.

public static class ColorExtensions
{
    /// <summary>
    /// Gets the luminance of the color. A value between 0 (black) and 1 (white)
    /// </summary>
    /// <param name="color">The color.</param>
    /// <param name="algorithm">The type of luminance alg to use.</param>
    /// <returns>A value between 0 (black) and 1 (white)</returns>
    public static double GetLuminance(this Color color, LuminanceAlgorithm algorithm = LuminanceAlgorithm.Photometric)
    {
        switch (algorithm)
        {
            case LuminanceAlgorithm.CCIR601:
                return (0.2126 * color.R + 0.7152 * color.G + 0.0722 * color.B) / 255;

            case LuminanceAlgorithm.Perceived:
                return (Math.Sqrt(0.241 * Math.Pow(color.R, 2) + 0.691 * Math.Pow(color.G, 2) + 0.068 * Math.Pow(color.B, 2)) / 255);

            case LuminanceAlgorithm.Photometric:
                return (0.299 * color.R + 0.587 * color.G + 0.114 * color.B) / 255;
        }

    }

   /// <summary>
   /// The luminances
   /// </summary>
   public enum LuminanceAlgorithm
   {
       /// <summary>
       /// Photometric/digital ITU-R
       /// </summary>
       Photometric,

       /// <summary>
       /// Digital CCIR601 (gives more weight to the R and B components, as preciev by the human eye)
       /// </summary>
       CCIR601,

       /// <summary>
       /// A perceived luminance
       /// </summary>
       Perceived
   }
}

Upvotes: 4

I am trying to use this to figure out if a color is light or dark

Just use Color.GetBrightness()


[Edit]

I want to determine if I should use white or black for my text. So anything ≤ .5 I should use white and > .5 black?

There are a number of ways to determine what color to use on a given background, none of which are perfect.

That last link actually recommends using black/white only, but choosing a cutoff point of 0.73 instead of 0.5. I think you should just go with that, and change it if you find it doesn't work for you.

Upvotes: 9

Chris Haas
Chris Haas

Reputation: 55417

Just convert the hex string to an integer:

int color = Convert.ToInt32("FFFFFF", 16);

Upvotes: 28

Daniel A. White
Daniel A. White

Reputation: 190907

calcLuminance only returns a percentage.

Upvotes: 1

Lasse Espeholt
Lasse Espeholt

Reputation: 17782

The problem, as I see it, is your calculation of rgb. You add the values together which gives you a number between 0 and 3*255 which clearly isn't the value your method expect. You will have to calculate it like this

int rgb = (int)color.R << 16 + (int)color.G << 8 + color.B;

which should be equivalent to this (except for the alpha-value you don't use)

int rgb = color.ToArgb();

Lastly, as you can see in Chris Haas answer, you can skip this step by converting directly to an int.

Upvotes: 2

Oded
Oded

Reputation: 498914

The ranges of the R, G and B from the Color struct are 0-255.

To get the rgb value you expect in your function, you will need to left shift accordingly:

int rgb = (int)color.R << 16 + (int)color.G << 8 + color.B;

Upvotes: 1

Related Questions