分享颜色判断之RGB值转颜色字符串方法-RGB2Name by C#

背景:RGB值(R,G,B)转颜色简单,直接用Color.FromArgb(R,G,B)即可实现,但是本文要讲的是,给定一个(R,G,B),要求不转换成Color也能直观的知道它是属于哪一种颜色(比如LED灯颜色自动判断是否OK)。RGB2Name就是这样一种实现的方法。

C#中已分类的颜色种类从AliceBlue(240,248,255)到YellowGreen(154,205,50)一共有140种,实际上颜色有256*256*256=1600多万种,所以随便给定一个(R,G,B),只靠系统中已定义的颜色种类来匹配显然不够。

但是可不可以用这140种颜色来模糊匹配呢,答案是可以的,但是模糊匹配的算法我不再行,有好的模糊匹配的算法也请跟我说一下。本文用的是另外一种算法更简单的方法,只设定有28种颜色:

红(深中浅),绿(深中浅),蓝(深中浅),黄(深中浅),青(深中浅),紫(深中浅),橙,黄绿,青绿,青蓝,紫蓝,紫红,黑,灰,浅灰,白

枚举如下:

 public enum RGBName
        {
            [Description("红")]
            Red = 1,
            [Description("绿")]
            Green,
            [Description("蓝")]
            Blue,
            [Description("深红")]
            DarkRed,
            [Description("深绿")]
            DarkGreen,
            [Description("深蓝")]
            DarkBlue,
            [Description("浅红")]
            LightRed,
            [Description("浅绿")]
            LightGreen,
            [Description("浅蓝")]
            LightBlue,
            [Description("黄")]
            Yellow,
            [Description("青")]
            Cyan,
            [Description("紫")]
            Purple,
            [Description("深黄")]
            DarkYellow,
            [Description("深青")]
            DarkCyan,
            [Description("深紫")]
            DarkPurple,
            [Description("浅黄")]
            LightYellow,
            [Description("浅青")]
            LightCyan,
            [Description("浅紫")]
            LightPurple,
            [Description("橙")]
            Orange,
            [Description("黄绿")]
            YellowGreen,
            [Description("青绿")]
            CyanGreen,
            [Description("青蓝")]
            CyanBlue,
            [Description("紫蓝")]
            PurpleBlue,
            [Description("紫红")]
            PurpleRed,
            [Description("黑")]
            Black,
            [Description("白")]
            White,
            [Description("灰")]
            Gray,
            [Description("浅灰")]
            LightGray,
        }

然后将255分成4个等级,x/83整除四舍五入取整~0,1,2,3
排列组合:(r,g,b)=4*4*4=64种情况

针对这64种情况,规律如下:

 public static string CLRToName(Color Clr)
        {
            double d_r = (double)Clr.R / 83;
            double d_g = (double)Clr.G / 83;
            double d_b = (double)Clr.B / 83;
            int r = (int)Math.Round(d_r);
            int g = (int)Math.Round(d_g);
            int b = (int)Math.Round(d_b);
            string rgb = r.ToString() + "," + g.ToString() + "," + b.ToString();           
            #region "switch (rgb)"
            switch (rgb)
            {
                case "0,0,0":
                case "1,1,1":
                case "2,2,2":
                case "3,3,3":
                    if (r == 0) return RGBName.Black.GetDescription();
                    if (r == 1) return RGBName.Gray.GetDescription();
                    if (r == 2) return RGBName.LightGray.GetDescription();
                    if (r == 3) return RGBName.White.GetDescription();
                    break;
                case "0,0,3":
                case "0,3,0":
                case "3,0,0":
                case "1,1,3":
                case "1,3,1":
                case "3,1,1":
                case "0,1,3":
                case "0,3,1":
                case "3,0,1":
                case "1,0,3":
                case "1,3,0":
                case "3,1,0":
                case "0,0,2":
                case "0,2,0":
                case "2,0,0":
                case "1,1,2":
                case "1,2,1":
                case "2,1,1":
                case "0,1,2":
                case "0,2,1":
                case "2,0,1":
                case "1,0,2":
                case "1,2,0":
                case "2,1,0":
                    if (r == 2) return RGBName.DarkRed.GetDescription();
                    if (g == 2) return RGBName.DarkGreen.GetDescription();
                    if (b == 2) return RGBName.DarkBlue.GetDescription();
                    if (r == 3) return RGBName.Red.GetDescription();
                    if (g == 3) return RGBName.Green.GetDescription();
                    if (b == 3) return RGBName.Blue.GetDescription();
                    break;
                case "0,0,1":
                case "0,1,0":
                case "1,0,0":                  
                case "2,2,3":
                case "2,3,2":
                case "3,2,2":
                    if (r == 1) return RGBName.DarkRed.GetDescription();
                    if (g == 1) return RGBName.DarkGreen.GetDescription();
                    if (b == 1) return RGBName.DarkBlue.GetDescription();
                    if (r == 3) return RGBName.LightRed.GetDescription();
                    if (g == 3) return RGBName.LightGreen.GetDescription();
                    if (b == 3) return RGBName.LightBlue.GetDescription();
                    break;
                case "1,1,0":
                case "0,1,1":
                case "1,0,1":
                case "2,2,0":
                case "0,2,2":
                case "2,0,2":
                case "2,2,1":
                case "1,2,2":
                case "2,1,2":
                case "3,3,0":
                case "0,3,3":
                case "3,0,3":
                case "3,3,1":
                case "1,3,3":
                case "3,1,3":
                case "3,3,2":
                case "2,3,3":
                case "3,2,3":
                    if (r == 1 && g == 1) return RGBName.DarkYellow.GetDescription();
                    if (g == 1 && b == 1) return RGBName.DarkCyan.GetDescription();
                    if (r == 1 && b == 1) return RGBName.DarkPurple.GetDescription();
                    if (r == 2 && g == 2) return RGBName.Yellow.GetDescription();
                    if (g == 2 && b == 2) return RGBName.Cyan.GetDescription();
                    if (r == 2 && b == 2) return RGBName.Purple.GetDescription();
                    if (r == 3 && g == 3) return RGBName.LightYellow.GetDescription();
                    if (g == 3 && b == 3) return RGBName.LightCyan.GetDescription();
                    if (r == 3 && b == 3) return RGBName.LightPurple.GetDescription();
                    break;
                case "3,2,0":
                case "3,2,1":
                    return RGBName.Orange.GetDescription();
                case "2,3,0":
                case "2,3,1":
                    return RGBName.YellowGreen.GetDescription();
                case "0,3,2":
                case "1,3,2":
                    return RGBName.CyanGreen.GetDescription();
                case "0,2,3":
                case "1,2,3":
                    return RGBName.CyanBlue.GetDescription();
                case "3,0,2":
                case "3,1,2":
                    return RGBName.PurpleRed.GetDescription();
                case "2,0,3":
                case "2,1,3":
                    return RGBName.PurpleBlue.GetDescription();
                default:
                    return "Error";
            }
            #endregion
            return "Error";
        }

上面的GetDescription()是扩展类自定义函数,获取枚举的描述信息。完整代码文件链接为:Github,感兴趣的可以下载。

为了方便集成:用List存储RGBN信息

 public static List <string> CLR2RGBN(Color Clr)
        {
            List<string> list = new List<string>();
            list.Add(Clr.R.ToString());
            list.Add(Clr.G.ToString());
            list.Add(Clr.B.ToString());
            list.Add(CLRToName(Clr));
            return list;
        }

然后写了一个测试函数:

     private static void Test()
        {
            foreach (var item in typeof(Color).GetMembers())
            {
                if (item.MemberType == System.Reflection.MemberTypes.Property && System.Drawing.Color.FromName(item.Name).IsKnownColor == true)
                //只取属性且为属性中的已知Color,剔除byte属性以及一些布尔属性等(A B G R IsKnownColor Name等)
                {
                    Color Clr = Color.FromName(item.Name);
                    List<string> list = CLR2RGBN(Clr);
                    string rgbn = item.Name + "(" + list[0] + "," + list[1] + "," + list[2] + "):" + list[3];
                    Console.WriteLine(rgbn);
                }
            }
        }

这个测试函数会把系统分类的140种颜色输入到CLR2RGBN()函数中,最后输出形如:

AliceBlue(240,248,255):白
AntiqueWhite(250,235,215):白
Aqua(0,255,255):浅青
Aquamarine(127,255,212):浅青
Azure(240,255,255):白
Beige(245,245,220):白
Bisque(255,228,196):浅黄
Black(0,0,0):黑
BlanchedAlmond(255,235,205):浅黄
Blue(0,0,255):蓝
BlueViolet(138,43,226):紫蓝
Brown(165,42,42):深红
BurlyWood(222,184,135):浅红
CadetBlue(95,158,160):青
Chartreuse(127,255,0):黄绿
Chocolate(210,105,30):红
Coral(255,127,80):橙
CornflowerBlue(100,149,237):青蓝
Cornsilk(255,248,220):白
Crimson(220,20,60):红
Cyan(0,255,255):浅青

。。。

Tan(210,180,140):浅红
Teal(0,128,128):青
Thistle(216,191,216):浅紫
Tomato(255,99,71):红
Turquoise(64,224,208):浅青
Violet(238,130,238):浅紫
Wheat(245,222,179):浅黄
White(255,255,255):白
WhiteSmoke(245,245,245):白
Yellow(255,255,0):浅黄
YellowGreen(154,205,50):黄

通过对比发现,系统分类的颜色,和匹配的中文描述,相识度90%以上。没有达到100%,还有优化的空间。

但是对于一般的应用而言已经足够了,如通过颜色分析测试仪读LED灯读出来的RGB可以算出它属于28个颜色中的哪一个,从而进一步自动判断待测物颜色是否符合要求。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值