根据亮度和饱和度,在颜色名称前添加苍白/鲜艳/亮/暗

时间:2016-12-11 13:48:07

标签: c# colors

我想获得与此列表最接近的颜色:

static List<Color> clist = new List<Color>()
    {
        Color.Black, Color.Brown, Color.Blue, Color.Green, Color.Red, Color.Yellow,
        Color.Gray, Color.Indigo, Color.Orange, Color.Pink, Color.Turquoise, Color.White
    };

我得到的最接近的颜色是这样但我想补充一下:苍白/黑暗/鲜艳/浅色取决于颜色的亮度和饱和度:

        static string closestColor2(List<Color> colors, Color target)
        {
            var colorDiffs = colors.Select(n => ColorDiff(n, target)).Min(n => n);
            int x = colors.FindIndex(n => ColorDiff(n, target) == colorDiffs);
            return colors[x].ToString();
        }

        static int ColorDiff(Color c1, Color c2)
        {
            return (int)Math.Sqrt((c1.R - c2.R) * (c1.R - c2.R)
                                   + (c1.G - c2.G) * (c1.G - c2.G)
                                   + (c1.B - c2.B) * (c1.B - c2.B));
        }

3 个答案:

答案 0 :(得分:2)

比较颜色时需要考虑很多事情。 但这个问题已经得到了回答。

您可以在这里找到解决方案:

How to compare Color object and get closest Color in an Color[]?

答案 1 :(得分:1)

我的建议是首先要有一份颜色列表。在你的答案中,你有一个小的颜色列表,但如果你以后愿意,你也可以添加所有141个颜色。

所以创建一个颜色列表:

java.util.Objects - java.util.Objects
[Ljava.lang.String; - java.lang.String[]
java.lang.String$CaseInsensitiveComparator - java.lang.String$CaseInsensitiveComparator
[Ljava.io.ObjectStreamField; - java.io.ObjectStreamField[]
java.io.ObjectStreamField - java.io.ObjectStreamField
[Ljava.lang.Object; - java.lang.Object[]
java.lang.StringBuilder - java.lang.StringBuilder
java.lang.StringBuffer - java.lang.StringBuffer
java.lang.AbstractStringBuilder - java.lang.AbstractStringBuilder
java.lang.reflect.AccessibleObject - java.lang.reflect.AccessibleObject
java.lang.String - java.lang.String
java.lang.Object - java.lang.Object

然后是另一个列表,其中包含您想要的颜色名称,&#34;生动&#34;,&#34;黑暗&#34;等。

    //List of Colors
    static List<Color> clist = new List<Color>{
        Color.Black, Color.Brown, Color.Blue, Color.LightSteelBlue, Color.Green, Color.Red, Color.Yellow,
        Color.Gray, Color.Indigo, Color.Orange, Color.Pink, Color.Turquoise, Color.White
    };

您可以使用这些方法找到最接近的颜色:

    //List of Color Names
    static List<string> cnlist = new List<string>{
        "Black", "Brown", "Blue", "Pale Light Blue", "Green", "Red", "Yellow",
        "Gray", "Indigo", "Orange", "Pink", "Turquoise", "White"
    };

上面的方法将返回列表中最接近颜色的索引,然后您可以获取相同的索引并获取您从颜色名称列表中指定的名称。这样你就可以在每种颜色上拥有你想要的名称,而不需要依赖不是100%的算法,因为它只有很少的颜色,所以只需要很少的时间来写出名字就像你提到的那样会按照你的意愿得到它们。

如果要添加Color。*中存在的所有颜色,可以使用此方法获取它们:

    int closestColor2(List<Color> colors, Color target) {
        var colorDiffs = colors.Select(n => ColorDiff(n, target)).Min(n => n);
        return colors.FindIndex(n => ColorDiff(n, target) == colorDiffs);
    }


    // distance in RGB space
    int ColorDiff(Color c1, Color c2) {
        return (int)Math.Sqrt((c1.R - c2.R) * (c1.R - c2.R)
                               + (c1.G - c2.G) * (c1.G - c2.G)
                               + (c1.B - c2.B) * (c1.B - c2.B));
    }

答案 2 :(得分:0)

我找到了这段代码:

    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;
}

Here

我尝试将它实现到你的代码中:

static string closestColor1(List<Color> colors, Color target)
    {
        var hue1 = target.GetHue();
        var diffs = colors.Select(n => getHueDistance(n.GetHue(), hue1));
        var diffMin = diffs.Min(n => n);
        var x = diffs.ToList().FindIndex(n => n == diffMin);

        Color c = colors[x];

        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 " : "";

        name += colors[x].ToString();

        return name;
    }

但是有些解决方案有时会显示两种情况,例如:“淡红色”/“浅蓝色”等......这真的令人困惑......而且你只想展示其中的一个......你应该尝试类似的东西..或者想想如何只放1 ..