简体   繁体   中英

Why does System.Drawing.Color add 'ff' to hex code?

I have a color #cccc00 that I retrieve from a database, and use to paint the background of a control.

Since I don't know if the string will be hex or the name of the color (ie. Yellow or #cccc00 ), I check the string, like so:

string color = "#cccc00";
if (color.IndexOf('#') >= 0)
{
    Color _color = System.Drawing.ColorTranslator.FromHtml(color);
    buttonSelector.BackColor = _color;
    // _color.Name now equals ffcccc00
}

This works fine. The problem is that I also use that string (the color) to search a sql table. The issue is that _color.Name returns ffcccc00 , so the search will not return anything because the sql table has it as #cccc00 .

So, without having to alter the string by removing/replacing the ff , is there a way to retrieve the value in the same format I used to set the control's backcolor? I prefer not removing/replacing because it can use hex or the actual color name.

Thanks.

First byte (in your case FF) indicates color transparency . Other three bytes describes color, depending on encoding it could be RGB for example.

So code FF FFFFFF, shows FFFFFF color's transparency .

Where FF stands for most intensive color, while 00 indicates complete transparency.

This is the alpha component, ie transparency, of the colour. If you need a consistent format, you can create it yourself from the R, G, and B components that you convert into hexadecimal.

So, without having to alter the string by removing/replacing the ff, is there a way to retrieve the value in the same format I used to set the control's backcolor?

Well, you used ColorTranslator.FromHtm method to get the color value from string. To do the opposite, you can use ColorTranslator.ToHtml .

Just make sure you use case insensitive search, because ToHtml method does uppercase the hex value.

For instance:

string colorA = "#cccc00";
Color color = ColorTranslator.FromHtml(colorA);
string colorB = ColorTranslator.ToHtml(color); // "#CCCC00"

but

string colorA = "AliceBlue";
Color color = ColorTranslator.FromHtml(colorA);
string colorB = ColorTranslator.ToHtml(color); // "AliceBlue"

This is the color's alpha channel. It is stored in 8 bits, just like the red, green, and blue component values. Just as red, green, and blue range from 0 (0x00) to 255 (0xFF), so can the alpha channel.

Color values with an alpha channel are actually 32 bits long (4 bytes × 8 bits/byte), instead of the normal 24-bit colors that you're probably used to from the web.

An alpha channel allows transparency effects. In other words, it controls how the color blends with its background. An alpha-channel value of 0 (0x00) means the color is completely transparent—basically, there is no color. An alpha-channel value of 255 (0xFF) means the color is fully opaque. 24-bit colors are always fully opaque because they have no alpha channel.

That means #224466 is exactly the same color as #FF224466.

I understand, but I can't use #cccc00ff as the color because it's a completely different color to #cccc00.

Yes, those are different colors because you've mixed up the byte position. The alpha-channel is always stored in the high byte (that's the doublet that comes first when written out in hex notation).

The order is #AARRGGBB. The alpha-channel value is stored in the high byte, red comes next, then green, and finally blue in the low byte. There is nothing sacred about this order, but it has become the de facto standard. (You also occasionally find #AABBGGRR.)

If you don't need alpha channel information and want to simply work with 24-bit colors, you can trim off the high byte, which contains the alpha-channel value. Or you can just store this in the database. It does not matter, as they represent the same color.

You can parse the values yourself, ignoring the alpha-channel value(s), if necessary:

String RgbColorToHexString(Color clr)
{
    return string.Format("#{0:X2}{1:X2}{2:X2}",
                         clr.R,
                         clr.G,
                         clr.B);
}

Color HexStringToRgbColor(String str)
{
    int argb = Int32.Parse(str.Replace("#", ""), NumberStyles.HexNumber);
    return Color.FromArgb((argb & 0x00FF0000) >> 16,  /* red component   */
                          (argb & 0x0000FF00) >>  8,  /* green component */
                          (argb & 0x000000FF));       /* blue component  */
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM