今天碰到一个这样的问题。我在修改以前用VB写的一个功能,这个功能中有一个部分是使用着色器给一段文字上色。然后这个颜色值存入数据库中的值是一个十进制数。新项目用C#,在Winform中需要读取这个数据给文字画上颜色。
通过上网找资料以及结合个人理解,该转换过程主要有以下几个步骤:
1、十进制数转成十六进制字符串。
2、十六进制字符串转成RGB码。
3、RGB码转成Color类型的值,给控件文字颜色属性赋值。
在研究这个功能实现的过程中需要先了解一些关键点。
首先,就是colorEdit等选颜色的控件都是通过设置RGB值来设置颜色的。而且R、G、B的范围都是0~255。转成十六进制就是0~FF。因此十六进制字符串为6位字符的字符串,范围为000000~FFFFFF。
其次,就是十进制转成十六进制字符串时,字符串的字符个数可能没有6位,这种情况需要在字符串前补0。如果超过6位,说明这个十进制不是用来转颜色码的。
最后,通过测试发现这个6位字符的十六进制字符串,前两个字符对应这RGB码的B位,中间两位对应G位,后面两位对应R位。
一、十进制转十六进制
/// <summary> /// 十进制转换到十六进制 /// </summary> /// <param name="strDecimal">十进制数的字符串</param> /// <returns>十六进制字符串</returns> public static string Decimal2Hexadecimal(string strDecimal) { //十进制数 ulong Decimal = Convert.ToUInt64(strDecimal); //十六的倍数 ulong HexadecimalMultiple; //十六进制数取余16 ulong HexadecimalChar; //十六进制字符串 string Hexadecimal = ""; do { HexadecimalMultiple = (ulong)Math.Floor((decimal)(Decimal / 16)); HexadecimalChar = Decimal % 16; Hexadecimal = Number2Char(HexadecimalChar) + Hexadecimal; Decimal = HexadecimalMultiple; } while (Decimal >= 16); if (Decimal != 0) Hexadecimal = Number2Char(Decimal) + Hexadecimal; return Hexadecimal; } /// <summary> /// 数字转字符串 /// </summary> /// <param name="number">数字</param> /// <returns>字符串</returns> public static string Number2Char(ulong number) { switch (number) { case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: return number.ToString(); case 10: return "A"; case 11: return "B"; case 12: return "C"; case 13: return "D"; case 14: return "E"; case 15: return "F"; default: return ""; } }
二、十六进制转RGB编码以及转Color
/// <summary> /// 十六进制转Color /// </summary> /// <param name="strHexadecimal">十六进制字符串</param> /// <returns>颜色值</returns> public static Color Hexadecimal2Color(string strHexadecimal) { try { if (strHexadecimal.Length == 0) { return System.Drawing.Color.FromArgb(0, 0, 0);//设为黑色 } else { //十六进制颜色码为6个字符,补全6位字符 if (strHexadecimal.Length < 6) { strHexadecimal = strHexadecimal.PadLeft(6, '0'); } string strB = strHexadecimal.Substring(0, 2); string strG = strHexadecimal.Substring(2, 2); string strR = strHexadecimal.Substring(4, 2); int B = int.Parse(strB, System.Globalization.NumberStyles.AllowHexSpecifier); int G = int.Parse(strG, System.Globalization.NumberStyles.AllowHexSpecifier); int R = int.Parse(strR, System.Globalization.NumberStyles.AllowHexSpecifier); //RGB转Color Color color = Color.FromArgb(R, G, B); return color; } } catch { //设为黑色 return System.Drawing.Color.FromArgb(0, 0, 0); } }
三、封装了前面几个方法后面,就可以封装一个十进制转Color的方法了
/// <summary> /// 十进制转Color /// </summary> /// <param name="Decimal">十进制数</param> /// <returns>颜色值</returns> public static Color Decimal2Color(string Decimal) { return Hexadecimal2Color(Decimal2Hexadecimal(Decimal)); }
以上是没有考虑微软已经封装好的方法,自己去思考的步骤写出来的。接下来使用微软封装好的一些方法能够使代码更优。
private static Color Decimal2Color(ulong Decimal) { string Hexadecimal = Decimal.ToString("X6"); string strB = Hexadecimal.Substring(0, 2); string strG = Hexadecimal.Substring(2, 2); string strR = Hexadecimal.Substring(4, 2); int B = Convert.ToInt32(strB, 16); int G = Convert.ToInt32(strG, 16); int R = Convert.ToInt32(strR, 16); return Color.FromArgb(R, G, B); }
ulong类型的十进制数字.ToString("X6");会转成十六进制的6位字符串,并且不足6位时会在原来基础的前面补0。
接下来就是拆分出R、G、B分别对应的字符。
接着,通过Convert.ToInt32("",16),能够把16进制字符转成R、G、B的32位整形数值。
最后使用Color对象的FromArgb()方法,对应放入R、G、B参数值就可以得出颜色。