Un algoritmo simple para probar el color: recorra la imagen píxel por píxel en un bucle anidado (ancho y alto) y pruebe para ver si los valores RGB del píxel son iguales. Si no lo están, la imagen tiene información de color. Si recorre todos los píxeles sin encontrar esta condición, entonces tiene una imagen en escala de grises.
Revisión con un algoritmo más complejo:
En el primer rev de este post me propuso un algoritmo simple que asume que los píxeles son escala de grises si RGB de cada píxel son valores son iguales. Por lo tanto, los valores RGB de 0,0,0 o 128,128,128 o 230,230,230 serían todos de color gris, mientras que 123,90,78 no. Sencillo.
Aquí hay un fragmento de código que prueba una variación del gris. Los dos métodos son una pequeña subsección de un proceso más complejo pero deberían proporcionar suficiente código sin formato para ayudar con la pregunta original.
/// <summary>
/// This function accepts a bitmap and then performs a delta
/// comparison on all the pixels to find the highest delta
/// color in the image. This calculation only works for images
/// which have a field of similar color and some grayscale or
/// near-grayscale outlines. The result ought to be that the
/// calculated color is a sample of the "field". From this we
/// can infer which color in the image actualy represents a
/// contiguous field in which we're interested.
/// See the documentation of GetRgbDelta for more information.
/// </summary>
/// <param name="bmp">A bitmap for sampling</param>
/// <returns>The highest delta color</returns>
public static Color CalculateColorKey(Bitmap bmp)
{
Color keyColor = Color.Empty;
int highestRgbDelta = 0;
for (int x = 0; x < bmp.Width; x++)
{
for (int y = 0; y < bmp.Height; y++)
{
if (GetRgbDelta(bmp.GetPixel(x, y)) <= highestRgbDelta) continue;
highestRgbDelta = GetRgbDelta(bmp.GetPixel(x, y));
keyColor = bmp.GetPixel(x, y);
}
}
return keyColor;
}
/// <summary>
/// Utility method that encapsulates the RGB Delta calculation:
/// delta = abs(R-G) + abs(G-B) + abs(B-R)
/// So, between the color RGB(50,100,50) and RGB(128,128,128)
/// The first would be the higher delta with a value of 100 as compared
/// to the secong color which, being grayscale, would have a delta of 0
/// </summary>
/// <param name="color">The color for which to calculate the delta</param>
/// <returns>An integer in the range 0 to 510 indicating the difference
/// in the RGB values that comprise the color</returns>
private static int GetRgbDelta(Color color)
{
return
Math.Abs(color.R - color.G) +
Math.Abs(color.G - color.B) +
Math.Abs(color.B - color.R);
}
La comprobación del tipo de imagen no va a cortar, ya que se configurará para 24 o 32 bits (ya que está escaneando en color). Probablemente tendrá que verificar cada píxel; si R == G == B en todos los píxeles, se trata de una imagen en escala de grises; de lo contrario, probablemente sea el color. –
Una idea: a pesar de que el escáner en teoría proporciona R == G == B, ¿es posible que durante la compresión JPEG haya algunos píxeles en los que eso sea casi cierto? Considere, JPEG es un algoritmo de compresión con pérdida. Quizás JPEG se tome algunas libertades con los colores de píxel cercanos. Pero lo confieso, no soy un experto en JPEG. Pero me gustaría saber cómo funcionó antes de confiar en R == G == B. –
Sí, odiaría confiar exactamente en r == g == b, porque incluso si jpg no hace ningún truco (y apuesto a que sí), su escáner y original también deberían ser perfectos, lo que me parece poco probable en muchos casos. – Beska