2010-02-02 5 views
7

Comment puis-je vérifier si deux structures System.Drawing.Color représentent la même couleur en profondeur de couleur 16 bits (ou généralement en fonction de la valeur de Screen.PrimaryScreen.BitsPerPixel)? Supposons que je mette Form.TransparencyKey à Value1 (de type Color), je veux vérifier que lorsque l'utilisateur sélectionne une nouvelle couleur d'arrière-plan pour le formulaire (Value2), je ne mets pas le formulaire entier en transparence.Comment vérifier si deux structures System.Drawing.Color représentent la même couleur dans une profondeur de couleur de 16 bits?

Sur les écrans de profondeur de couleur de 32 bits je compare simplement les deux valeurs:

if (Valeur1 == Valeur2)

Cependant, cela ne fonctionne pas sur les écrans de profondeur de couleur de 16 bits, comme plus de valeurs de couleur pour les Valeur2 représenterait la même couleur 16 bits que Value1, comme je l'ai découvert à la dure.

Répondre

1

Essayez le code suivant:

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

Juste violon avec le TransparancyKey et BackColor pour voir si cela fonctionne pour vous. Pour moi ça l'a fait. Et oui, je sais que c'est du code gonflé et moche, c'est juste un exemple bien sûr.

+0

Juste pour comprendre, si vous pouvez me donner plus de détails sur pourquoi vous multipliez la valeur rouge avec 32, la valeur verte avec 64 et la valeur bleue avec 32? Merci – AnAurelian

+0

Pour la même raison que nobugz réponse: couleur RVB 16 bits (vrai) dans Windows sont constitués de 5, 6 et 5 bits (2 à la puissance de 5 est de 32, 2 à la puissance de 6 est de 64). Par conséquent, si vous divisez les octets Rouge et Bleu d'origine par 256 et que vous les multipliez par 32, vous obtenez la représentation arrondie à 5 bits. La même chose s'applique aux 6 bits de Green. – Webleeuw

0

Puisque ColorTranslator.ToWin32 est utilisé sous le capot, est-ce que cela fonctionne?

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

Cela ne fonctionnera pas, car il en résulte toujours une représentation entière d'une couleur 32 bits. – Webleeuw

+0

La source .NET pour ColorTranslator.ToWin32 est: "public static int ToWin32(Color c) { return c.R << Win32RedShift | c.G << Win32GreenShift | c.B << Win32BlueShift; }" où Win32RedShift = 0; Win32GreenShift = 8; Win32BlueShift = 16; Est-ce que cela peut être modifié en convertissant la valeur en une profondeur de couleur de 16 bits? Et plus généralement, à une profondeur de couleur Screen.PrimaryScreen.BitsPerPixel? – AnAurelian

1

Il existe deux formats de pixels pour la couleur 16 bits, 555 et 565. Vous auriez à masquer les valeurs R, G et B avec 0xF8 (5 bits) et 0xFC (6 bits) avant de les comparer . Gardez à l'esprit que la machine sur laquelle vous exécutez le concepteur n'est pas représentative de la machine sur laquelle votre programme s'exécute.

Questions connexes