2011-10-21 21 views
6

Chcę wywołać metodę z kolorem argumentu. Ale jest wiele kolorów, które różnią się tylko odcieniem. Jak mogę znaleźć kolory, które różnią się od mojego koloru tylko trochę, na przykład AntiqueWhite i Bisque. Here's paleta kolorów.C# znalezienie podobnych kolorów

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); 
+0

Użyj Próg max zmianą R, G lub B (lub wszystkie trzy) – RvdK

+0

Co chcesz zrobić z wynikami? – alexn

+0

możliwy duplikat [znalezienie podobnych kolorów programowo] (http://stackoverflow.com/questions/1725505/finding-similar-colors-programatically) –

Odpowiedz

6

znalazłem to rutynowe 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); 

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

Co to jest WebColors? –

+0

To paleta kolorów. Spójrz [tutaj] (http://pietschsoft.com/post/2006/06/29/C-NET-Convert-SystemDrawingColor-to-HTML-color.aspx), aby przekonwertować go na coś innego – Marco

+0

Nie ma prawdziwego powodu do zrobienia pierwiastka kwadratowego. najbliższa wartość będzie najbliższą wartością, nawet bez dodania dużej obciążenia procesora. – Nyerguds

11

można użyć metody tak:

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

Metoda ta przyjmuje dwa kolory i tolerancję i zwraca, czy te dwa kolory są zbliżone lub nie na podstawie ich wartości RGB. Myślę, że powinno to wystarczyć, ale być może trzeba rozszerzyć, aby włączyć jasność i nasycenie.

+3

Coś innego do rozważenia, robi to samo, ale w przestrzeni kolorów HSV. –

2

Analizować ten przykład Find the Nearest Color with C#. Hope daje ci pomysł.

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

Właśnie wysłałeś tę samą procedurę z tej samej witryny :) – Marco

+0

Co to jest WebColors? –

+0

Jak widać w etykiecie narzędzia sygnatury czasowej, obie odpowiedzi są tworzone w krótkich odstępach czasu. –

0

sądzę, aby znaleźć podobne kolory należy spojrzeć na HSL or HSB color space zamiast RGB jednego, bo z tym jest dużo łatwiej znaleźć podobne kolory.

ciągu .Net można wywołać metodę GetHue(), GetSaturation() i GetBrightness() aby te wartości z danego koloru i porównanie tych wartości, aby znaleźć podobne zdania.

Jeśli potrzebujesz drogi powrotnej od wartości HSB do koloru, możesz również użyć this method.

3

Możesz uzyskać najbliższy kolor z wyliczenia 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); 

A metoda wsparcie

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); 
} 
+0

Świetne rozwiązanie! Czy możesz zaktualizować go, aby korzystać z Windows.UI.Color i Windows.UI.Colors podczas programowania Uniwersalnych aplikacji Windows? Dziękuję Ci. – AnAurelian

1

Użyłem poniżej odpowiedź Keven Holditch użytkownika. Ale zmodyfikowałem go dla własnych celów. Ta wersja używa wyłączności - lub tak, że tylko jedna wartość może być wyłączona przez tolerancję i nadal zwracać wartość true. (Tolerancja jest również < = zamiast tylko <.)

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