C#查找相似颜色

8
我想调用一个带有颜色参数的方法。但是有很多颜色只是略有不同。我该如何找到与我的颜色仅略有不同的颜色,例如AntiqueWhite和Bisque。 是颜色调色板。
Bitmap LogoImg = new Bitmap("file1.jpeg");//the extension can be some other
System.Drawing.Color x = LogoImg.GetPixel(LogoImg.Width-1, LogoImg.Height-1);
LogoImg.MakeTransparent(x);
image1.Source = GetBitmapSource(LogoImg);

使用最大变化的阈值来限制R、G或B(或三者均)的变化。 - RvdK
你想对你的结果做什么? - alexn
@Erno 我看到了,但是对我没有帮助。 - petko_stankoski
@alexn 这个方法接收一个颜色参数,将该颜色设置为透明。 - petko_stankoski
6个回答

16

你可以尝试使用这样的方法:

 public bool AreColorsSimilar(Color c1, Color c2, int tolerance)
 {
     return Math.Abs(c1.R - c2.R) < tolerance &&
            Math.Abs(c1.G - c2.G) < tolerance &&
            Math.Abs(c1.B - c2.B) < tolerance;
 }

这个方法需要两种颜色和一个容差值,根据它们的RGB值返回这两种颜色是否相近。我认为这应该能解决问题,但你可能需要扩展其功能以包括亮度和饱和度。


3
另一个需要考虑的是,在HSV颜色空间中做同样的事情。 - George Duckett

7

我在这里找到了这个程序

Color nearest_color = Color.Empty;
foreach (object o in WebColors)
{
    // compute the Euclidean distance between the two colors
    // note, that the alpha-component is not used in this example
    dbl_test_red = Math.Pow(Convert.ToDouble(((Color)o).R) - dbl_input_red, 2.0);
    dbl_test_green = Math.Pow(Convert.ToDouble
        (((Color)o).G) - dbl_input_green, 2.0);
    dbl_test_blue = Math.Pow(Convert.ToDouble
        (((Color)o).B) - dbl_input_blue, 2.0);

    temp = Math.Sqrt(dbl_test_blue + dbl_test_green + dbl_test_red);
    // explore the result and store the nearest color
    if(temp == 0.0)
    {
        nearest_color = (Color)o;
        break;
    }
    else if (temp < distance)
    {
        distance = temp;
        nearest_color = (Color)o;
    }
}

这是一个颜色板。点击这里,将其转换为不同的格式。 - Marco
没有真正的理由去求平方根,即使不进行这个计算量大的操作,最接近的值也将是最接近的值。 - Nyerguds

4
您可以从KnownColors枚举中获取最接近的颜色。
// A color very close to Rosy Brown
var color = Color.FromArgb(188, 143, 142);

var colors = Enum.GetValues(typeof (KnownColor))
                .Cast<KnownColor>()
                .Select(Color.FromKnownColor);

var closest = colors.Aggregate(Color.Black, 
                (accu, curr) =>
                ColorDiff(color, curr) < ColorDiff(color, accu) ? curr : accu);

支持方法

private int ColorDiff(Color color, Color curr)
{
    return Math.Abs(color.R - curr.R) + Math.Abs(color.G - curr.G) + Math.Abs(color.B - curr.B);
}

2
分析这个例子 使用 C# 查找最近的颜色。希望能给你一个想法。

enter image description here

Color nearest_color = Color.Empty;
foreach (object o in WebColors)
{
    // compute the Euclidean distance between the two colors
    // note, that the alpha-component is not used in this example
    dbl_test_red = Math.Pow(Convert.ToDouble(((Color)o).R) - dbl_input_red, 2.0);
    dbl_test_green = Math.Pow(Convert.ToDouble
        (((Color)o).G) - dbl_input_green, 2.0);
    dbl_test_blue = Math.Pow(Convert.ToDouble
        (((Color)o).B) - dbl_input_blue, 2.0);
    // it is not necessary to compute the square root
    // it should be sufficient to use:
    // temp = dbl_test_blue + dbl_test_green + dbl_test_red;
    // if you plan to do so, the distance should be initialized by 250000.0
    temp = Math.Sqrt(dbl_test_blue + dbl_test_green + dbl_test_red);
    // explore the result and store the nearest color
    if(temp == 0.0)
    {
        // the lowest possible distance is - of course - zero
        // so I can break the loop (thanks to Willie Deutschmann)
        // here I could return the input_color itself
        // but in this example I am using a list with named colors
        // and I want to return the Name-property too
        nearest_color = (Color)o;
        break;
    }
    else if (temp < distance)
    {
        distance = temp;
        nearest_color = (Color)o;
    }
}

你刚刚发布了从同一个网站获取的相同例程 :) - Marco
正如您可以在时间戳工具提示中看到的那样,这两个答案的创建时间非常接近。 - Soner Gönül
@user966638在解决方案中可以找到WebColors = GetWebColors(); - Soner Gönül

2

我使用了Keven Holditch的下面答案。但我修改了它以适应我的目的。这个版本使用异或,所以只有一个值可以在公差范围内,仍然返回true。(公差也是<=而不仅仅是<。)

private bool AreColorsSimilar(Color c1, Color c2, int tolerance)
{
    return Math.Abs(c1.R - c2.R) <= tolerance ^
           Math.Abs(c1.G - c2.G) <= tolerance ^
           Math.Abs(c1.B - c2.B) <= tolerance;
}

2
我认为要寻找相似的颜色,你应该查看HSL或HSB颜色空间,而不是RGB颜色空间,因为使用前者更容易找到相似的颜色。
在.Net中,你可以调用GetHue()、GetSaturation()和GetBrightness()方法从给定的颜色获取这些值,并比较这些值以找到相似的颜色。
如果你需要从HSB值返回到颜色,也可以使用这个方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接