2011-10-21 6 views
6

Je souhaite appeler une méthode avec une couleur d'argument. Mais il y a beaucoup de couleurs qui ne diffèrent que par une nuance. Comment puis-je trouver les couleurs qui diffèrent peu de ma couleur, par exemple AntiqueWhite et Bisque. Here's la palette de couleurs.C# trouver des couleurs similaires

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

Utilisez un changement d'un seuil maximum de R, G ou B (ou les trois) – RvdK

+0

Que voulez-vous faire avec vos résultats? – alexn

+0

duplication possible de [trouver des couleurs similaires par programme] (http://stackoverflow.com/questions/1725505/finding-similar-colors-programatically) –

Répondre

6

Je trouve cette here routine:

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

Qu'est-ce que WebColors? –

+0

C'est une palette de couleurs. Jetez un coup d'oeil [ici] (http://pietschsoft.com/post/2006/06/29/C-NET-Convert-SystemDrawingColor-to-HTML-color.aspx) pour le convertir en quelque chose de différent – Marco

+0

Il n'y a pas de vraie raison prendre la racine carrée, cependant. la valeur la plus proche sera la valeur la plus proche, même sans ajouter cette opération lourde de CPU. – Nyerguds

11

Pouvez-vous utiliser une méthode comme ceci:

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

Cette méthode prend deux couleurs et une tolérance et retourne si ces deux couleurs sont proches ou non en fonction de leurs valeurs RVB. Je pense que cela devrait faire l'affaire, mais vous devrez peut-être étendre pour inclure la luminosité et la saturation.

+3

Quelque chose d'autre à considérer, fait la même chose, mais dans l'espace de couleur HSV. –

2

Analyze cet exemple Find the Nearest Color with C#. L'espoir vous donne une idée.

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

Vous venez de publier la même routine provenant du même site :) – Marco

+0

Qu'est-ce que WebColors? –

+0

Comme vous pouvez le voir dans l'info-bulle d'horodatage, les deux réponses sont créées à des moments proches. –

0

Je pense trouver des couleurs similaires, vous devriez jeter un oeil à la HSL or HSB color space au lieu du RGB une, cause avec cela, il est beaucoup plus facile de trouver des couleurs similaires.

Dans .Net, vous pouvez appeler la méthode GetHue(), GetSaturation() et GetBrightness() pour obtenir ces valeurs à partir d'une couleur donnée et comparer ces valeurs pour trouver des valeurs similaires.

Si vous avez besoin du retour d'une valeur HSB vers une couleur, vous pouvez également utiliser this method.

3

Vous pouvez obtenir la couleur la plus proche de l'énumération 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); 

Et la méthode de soutien

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

Excellente solution! Pouvez-vous le mettre à jour pour utiliser Windows.UI.Color et Windows.UI.Colors, lors de la programmation Universal Windows Apps? Je vous remercie. – AnAurelian

1

J'utilise la réponse de Keven Holditch ci-dessous. Mais je l'ai modifié pour mes propres fins. Cette version utilise exclusive-ou alors qu'une seule valeur peut être désactivée par la tolérance et toujours retourner vrai. (La tolérance est également < = au lieu de simplement <.)

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