2011-10-21 18 views
6

Voglio chiamare un metodo con argomento colore. Ma ci sono molti colori che differiscono solo da un'ombra. Come posso trovare i colori che differiscono dal mio colore solo di poco, ad esempio AntiqueWhite e Bisque. Here's la tavolozza dei colori.C# trovare colori simili

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

utilizzare una soglia di un cambiamento massimo di R, G o B (o tutti e tre) – RvdK

+0

Cosa vuoi fare con i vostri risultati? – alexn

+0

possibile duplicato di [trovare colori simili a livello di programmazione] (http://stackoverflow.com/questions/1725505/finding-similar-colors-programatically) –

risposta

6

Ho trovato questa routine 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

Che cos'è WebColors? –

+0

È una tavolozza di colori. Date un'occhiata [qui] (http://pietschsoft.com/post/2006/06/29/C-NET-Convert-SystemDrawingColor-to-HTML-color.aspx) per convertirlo in qualcosa di diverso – Marco

+0

Non c'è una vera ragione per prendere la radice quadrata, però. il valore più vicino sarà il valore più vicino, anche senza aggiungere quell'operazione pesante alla CPU. – Nyerguds

11

Hai bisogno di un metodo come questo:

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

Questo metodo richiede due colori e una tolleranza e restituisce se queste due colori sono vicini o meno in base ai loro valori RGB. Penso che dovrebbe fare il trucco, ma potrebbe essere necessario estendere per includere la luminosità e la saturazione.

+3

Qualcos'altro da considerare, sta facendo la stessa cosa, ma nello spazio colore HSV. –

2

analizzare questo esempio Find the Nearest Color with C#. La speranza ti dà un'idea.

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

Hai appena pubblicato la stessa routine tratta dallo stesso sito :) – Marco

+0

Che cos'è WebColors? –

+0

Come puoi vedere nel suggerimento timestamp, entrambe le risposte vengono create in tempi ravvicinati. –

0

penso di trovare colori simili si dovrebbe dare uno sguardo alla HSL or HSB color space al posto del RGB uno, causa con questo è molto più facile trovare colori simili.

All'interno di .Net è possibile chiamare il metodo GetHue(), GetSaturation() e GetBrightness() per ottenere questi valori da un determinato colore e confrontare questi valori per trovare quelli simili.

Se è necessario tornare da un valore HSB a un colore, è possibile utilizzare anche this method.

3

È possibile ottenere il colore più vicino dall'enum 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); 

E il metodo di supporto

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

Ottima soluzione! È possibile aggiornarlo per utilizzare Windows.UI.Color e Windows.UI.Colors durante la programmazione di Universal Windows Apps? Grazie. – AnAurelian

1

ho usato la risposta di Keven Holditch sotto. Ma l'ho modificato per i miei scopi. Questa versione utilizza l'esclusiva o in modo che solo un valore può essere disattivato dalla tolleranza e restituire comunque true. (La tolleranza è anche < = invece di <.)

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