2010-02-02 24 views
7

Come posso verificare se due strutture System.Drawing.Color rappresentano lo stesso colore con profondità colore a 16 bit (o in genere in base al valore di Screen.PrimaryScreen.BitsPerPixel)?Come verificare se due strutture System.Drawing.Color rappresentano lo stesso colore con profondità colore a 16 bit?

Diciamo che ho impostato Form.TransparencyKey su Valore1 (di tipo Colore), voglio controllare che quando l'utente seleziona un nuovo colore di sfondo per il modulo (Valore2), non imposto l'intero modulo trasparente.

Nelle schermate profondità colore 32bit semplicemente confronta i due valori:

se (Valore1 Valore2 ==)

Tuttavia, questo non funziona su schermi profondità colore 16bit, come più valori di colore per il Valore2 rappresenterebbe lo stesso colore a 16 bit di Value1, come ho scoperto nel modo più difficile.

risposta

1

provare il seguente codice:

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

Basta giocherellare con il TransparancyKey e BackColor per vedere se funziona per voi. Per me lo ha fatto. E sì, lo so che è un codice gonfio e brutto, è solo inteso come esempio, naturalmente.

+0

Giusto per capire, se puoi darmi maggiori dettagli sul perché moltiplichi il valore rosso con 32, il valore verde con 64 e il valore blu con 32? Grazie – AnAurelian

+0

Per lo stesso motivo della risposta di nobugz: il colore RGB (vero) a 16 bit in Windows è costituito da 5, 6 e 5 bit (2 alla potenza di 5 è 32, 2 alla potenza di 6 è 64). Pertanto, se dividi i byte rosso e blu originali di 256 e li moltiplichi per 32 ottieni la rappresentazione arrotondata a 5 bit. Lo stesso vale per i 6 bit del Green. – Webleeuw

0

Poiché ColorTranslator.ToWin32 è utilizzato sotto il cofano, funziona?

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

Ciò non funzionerà, perché risulta sempre in una rappresentazione intera di un colore a 32 bit. – Webleeuw

+0

Il sorgente .NET per ColorTranslator.ToWin32 è: "public static int ToWin32(Color c) { return c.R << Win32RedShift | c.G << Win32GreenShift | c.B << Win32BlueShift; }" dove Win32RedShift = 0; Win32GreenShift = 8; Win32BlueShift = 16; Può essere modificato in modo tale da convertire il valore in una profondità di colore di 16 bit? E più in generale, a una profondità di colore Screen.PrimaryScreen.BitsPerPixel? – AnAurelian

1

Esistono due formati pixel per colore a 16 bit, 555 e 565. dovreste mascherare la R, G e B valori con 0xF8 (5 bit) e 0xFC (6 bit) prima di confrontarli . Tenere presente che la macchina su cui viene eseguito il progettista non è rappresentativa per la macchina su cui viene eseguito il programma.