尝试将rgb从.net颜色转换为字符串,如“red”或“blue”

lrpiutwd  于 2022-12-20  发布在  .NET
关注(0)|答案(6)|浏览(208)

我所有的方法都在不同的方面让我失望。不同的灯光也会把一切搞砸。
有没有人试图返回一个给定rgb值的名称?“红”“绿色”“蓝”将足以满足我今天的需要。
我有不安全的字节处理图像从我的网络摄像头。

n9vozmp4

n9vozmp41#

如果你有一个已知颜色的列表,你可以看到给定的目标颜色是“最接近”的那些已知颜色,使用一个“接近度”函数沿着如下所示(F#代码):

let Diff (c1:Color) (c2:Color) =
    let dr = (c1.R - c2.R) |> int
    let dg = (c1.G - c2.G) |> int
    let db = (c1.B - c2.B) |> int
    dr*dr + dg*dg + db*db

无论哪种已知颜色与要命名的目标颜色的差异最小,都使用该名称。

ztyzrc3y

ztyzrc3y2#

你可以试试这个代码

static char[] hexDigits = {
         '0', '1', '2', '3', '4', '5', '6', '7',
         '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};


public static string ColorToHexString(Color color)
        {
            byte[] bytes = new byte[4];
            bytes[0] = color.A;
            bytes[1] = color.R;
            bytes[2] = color.G;
            bytes[3] = color.B;
            char[] chars = new char[bytes.Length * 2];
            for (int i = 0; i < bytes.Length; i++)
            {
                int b = bytes[i];
                chars[i * 2] = hexDigits[b >> 4];
                chars[i * 2 + 1] = hexDigits[b & 0xF];
            }
            return new string(chars);
        }
7fyelxc5

7fyelxc53#

我个人觉得用hue/saturation/brightness来考虑颜色比用RGB值来考虑颜色更自然,我认为在这种情况下,这会很适合你。
给光谱的某个范围指定一个你认为合适的颜色名称。例如,红色是0-39,橙子是40-79,等等。(这些都是任意的数字--我不知道它们是否适合任何一种尺度)。然后从你的RGB值计算色调(你可以在这里找到一个公式,尽管可能还有其他公式)。一旦你知道了色调,你就知道了它在光谱的哪个范围,你就可以给予它一个名字。

neekobn8

neekobn84#

下面是使用两个限定符和一个颜色名称的简单命名方案:

string ColorName(Color c)
{
    List<float> hues = new List<float>()
    { 0, 15, 35, 44, 54, 63, 80, 160, 180, 200, 244, 280, 350, 360};
    List<string> hueNames = new List<string>()
        { "red", "orange-red", "orange", "yellow-orange", "yellow",
          "yellow-green",   "green"  , "blue-green" , "cyan", "blue", 
          "violet", "purple", "red" };

    float h = c.GetHue();
    float s = c.GetSaturation();
    float b = (c.R * 0.299f + c.G * 0.587f + c.B *0.114f) / 256f;

    string name = s < 0.35f ? "pale " : s > 0.8f ? "vivid " : "";
    name += b < 0.35f ? "dark " : b > 0.8f ? "light " : "";
    for (int i = 0; i < hues.Count - 1; i++)
        if (h >= hues[i] && h <= hues[i+1] )
        {
            name += hueNames[i];
            break;
        }
    return name;
}

你可以很容易地适应它,如果你想蓝调更有区别等。

tp5buhyn

tp5buhyn5#

嗯,红/绿色/蓝是很容易通过检查来识别的;您需要支持哪些范围的值?
问题是,除非你从一个命名的颜色开始,否则很难把它变回原来的颜色;即使您通过FromArgb创建了明显的颜色,IsNamedColor也将返回false。
如果你只需要实际期望的标准颜色,你可以通过反射枚举已知的颜色?

Color test = Color.FromArgb(255,0,0);
        Color known = (
                   from prop in typeof(Color)
                       .GetProperties(BindingFlags.Public | BindingFlags.Static)
                   where prop.PropertyType == typeof(Color)
                   let color = (Color)prop.GetValue(null, null)
                   where color.A == test.A && color.R == test.R
                     && color.G == test.G && color.B == test.B
                   select color)
                   .FirstOrDefault();

        Console.WriteLine(known.Name);

您还可以将此方法用作更复杂算法的已知颜色源。

93ze6v8z

93ze6v8z6#

下面的内容可能会有所帮助:

using System;
using System.Drawing;
                    
public class Program
{
    public static void Main()
    {
        Color color = Color.FromArgb(230, 250, 230);
        Console.WriteLine(GetDescription(color));
    }
    
    public static string GetDescription(Color color)
    {
        var hue = color.GetHue();
        var brightness = color.GetBrightness();
        var saturation = color.GetSaturation();
        
        Console.WriteLine($"H:{hue} B:{brightness} S:{saturation}");
        
        if (brightness > 95)
            return "White";
        if (brightness < 0.1 && saturation < 5)
            return "Black";
        if (hue == 0 && brightness > 0.1 && saturation < 5)
            return "Grey";
        
        if (hue > 330)
            return "Red";
        if (hue < 30)
            return "Red";
        if (hue > 30 && hue < 90)
            return "Yellow";
        if (hue > 90 && hue < 150)
            return "Green";
        if (hue > 150 && hue < 210)
            return "Cyan";
        if (hue > 210 && hue < 270)
            return "Blue";
        if (hue > 270 && hue < 330)
            return "Magenta";
        return "ND";
    }   
}

其思想是将描述符与hue范围相关联。
为了涵盖黑色、白色和灰色的情况,还需要考虑饱和度和亮度(可能需要对限值进行一些调整)。

相关问题