2011-10-21 25 views
6

Quiero llamar a un método con color de argumento. Pero hay muchos colores que difieren solo en un tono. ¿Cómo puedo encontrar los colores que difieren de mi color solo por poco, por ejemplo AntiqueWhite y Bisque? Here's la paleta de colores.C# buscando colores similares

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

Utilice un umbral de un cambio máximo de R, G o B (o los tres) – RvdK

+0

¿Qué desea hacer con los resultados? – alexn

+0

posible duplicado de [encontrar colores similares programáticamente] (http://stackoverflow.com/questions/1725505/finding-similar-colors-programatically) –

Respuesta

6

me encontré con esta rutina 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

¿Qué es WebColors? –

+0

Es una paleta de colores. Eche un vistazo [aquí] (http://pietschsoft.com/post/2006/06/29/C-NET-Convert-SystemDrawingColor-to-HTML-color.aspx) para convertirlo a algo diferente – Marco

+0

No hay una razón real para tomar la raíz cuadrada, sin embargo. el valor más cercano será el valor más cercano, incluso sin agregar esa operación pesada de CPU. – Nyerguds

11

Podría utilizar un método como este:

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

Este método tiene dos colores y una tolerancia y devuelve si esos dos colores están cerca o no en función de sus valores RGB. Creo que debería hacer el truco, pero es posible que deba extender para incluir el brillo y la saturación.

+3

Algo más que considerar, es hacer lo mismo, pero en el espacio de color HSV. –

2

analizar este ejemplo Find the Nearest Color with C#. Hope te da una 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

Acaba de publicar la misma rutina tomada desde el mismo sitio :) – Marco

+0

¿Qué es WebColors? –

+0

Como puede ver en la información sobre herramientas de marca de tiempo, ambas respuestas se crean tiempos cercanos. –

0

pienso para encontrar colores similares usted debe echar un vistazo a la HSL or HSB color space en lugar del RGB uno, causa con esto, es mucho más fácil de encontrar los colores similares.

Dentro de .Net puede llamar al método GetHue(), GetSaturation() y GetBrightness() para obtener estos valores de un color determinado y comparar estos valores para encontrar otros similares.

Si necesita retroceder desde un valor de HSB a un color, también puede usar this method.

3

Puede obtener el color más cercano a la enum de 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); 

y el método de soporte

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

¡Gran solución! ¿Se puede actualizar para usar Windows.UI.Color y Windows.UI.Colors, cuando se programan las aplicaciones de Universal Windows? Gracias. – AnAurelian

1

que utilizan la respuesta de Keven Holditch a continuación. Pero lo modifiqué para mis propios fines. Esta versión usa exclusiva, o de manera que solo un valor puede estar desactivado por la tolerancia y aún así devolver verdadero. (La tolerancia es también < = en lugar de sólo <.)

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