2010-02-02 6 views
7

¿Cómo puedo comprobar si dos estructuras System.Drawing.Color representan el mismo color en una profundidad de color de 16 bits (o generalmente se basa en el valor de Screen.PrimaryScreen.BitsPerPixel)?¿Cómo comprobar si dos estructuras System.Drawing.Color representan el mismo color en una profundidad de color de 16 bits?

Digamos que establezco Form.TransparencyKey en Value1 (del tipo Color), quiero comprobar que cuando el usuario selecciona un nuevo color de fondo para el formulario (Value2), no establezco el formulario completo como transparente.

En las pantallas de color de 32 bits de profundidad simplemente comparar los dos valores:

si (Valor1 == Valor2)

Sin embargo, esto no funciona en las pantallas de profundidad de color de 16 bits, a medida que más valores de color para el Valor2 representaría el mismo color real de 16 bits que Value1, como descubrí por el camino difícil.

Respuesta

1

Prueba el siguiente código:

void MyTestMethod() { 
    TransparencyKey = Color.FromArgb(128, 128, 64); 
    BackColor = Color.FromArgb(128, 128, 71); 

    byte tR = ConvertR(TransparencyKey.R); 
    byte tG = ConvertG(TransparencyKey.G); 
    byte tB = ConvertB(TransparencyKey.B); 

    byte bR = ConvertR(BackColor.R); 
    byte bG = ConvertG(BackColor.G); 
    byte bB = ConvertB(BackColor.B); 

    if (tR == bR && 
     tG == bG && 
     tB == bB) { 
     MessageBox.Show("Equal: " + tR + "," + tG + "," + tB + "\r\n" + 
      bR + "," + bG + "," + bB); 
    } 
    else { 
     MessageBox.Show("NOT Equal: " + tR + "," + tG + "," + tB + "\r\n" + 
      bR + "," + bG + "," + bB); 
    } 
} 

byte ConvertR(byte colorByte) { 
    return (byte)(((double)colorByte/256.0) * 32.0); 
} 

byte ConvertG(byte colorByte) { 
    return (byte)(((double)colorByte/256.0) * 64.0); 
} 

byte ConvertB(byte colorByte) { 
    return (byte)(((double)colorByte/256.0) * 32.0); 
} 

Sólo jugar con la TransparancyKey y BackColor para ver si funciona para usted. Para mí lo hizo. Y sí, sé que es un código hinchado y feo, simplemente se entiende como ejemplo, por supuesto.

+0

Solo para entender, si puede darme más detalles sobre por qué multiplica el valor rojo con 32, el verde con 64 y el azul con 32? Gracias – AnAurelian

+0

Por la misma razón que la respuesta nobugz: el color RGB (verdadero) de 16 bits en Windows se acumula de 5, 6 y 5 bits (2 a la potencia de 5 es 32, 2 a la potencia de 6 es 64). Por lo tanto, si divide los bytes rojos y azules originales por 256 y los multiplica por 32 obtendrá la representación redondeada de 5 bits. Lo mismo se aplica a los 6 bits del Green. – Webleeuw

0

Dado que ColorTranslator.ToWin32 se usa debajo del capó, ¿funciona?

if(ColorTranslator.ToWin32(Value1) == ColorTranslator.ToWin32(Value2)) 
+0

Eso no funcionará, porque siempre da como resultado una representación entera de un color de 32 bits. – Webleeuw

+0

La fuente .NET para ColorTranslator.ToWin32 es: "public static int ToWin32(Color c) { return c.R << Win32RedShift | c.G << Win32GreenShift | c.B << Win32BlueShift; }" donde Win32RedShift = 0; Win32GreenShift = 8; Win32BlueShift = 16; ¿Esto se puede modificar de tal manera que se convierta el valor en una profundidad de color de 16 bits? Y más generalmente, a una profundidad de color Screen.PrimaryScreen.BitsPerPixel? – AnAurelian

1

Hay dos formatos de píxeles de color de 16 bits, 555 y 565. Habría que enmascarar, los valores de I G y B con 0xF8 (5 bits) y 0xFC (6 bits) antes de compararlos . Tenga en cuenta que la máquina en la que ejecuta el diseñador no es representativa de la máquina en la que se ejecuta el programa.

Cuestiones relacionadas