2010-08-15 7 views
10

Sono abbastanza nuovo in C# e sto provando a fare un semplice software di elaborazione delle immagini. Capisco questo frammento estratti A, R, G, B da un valore int ARGB di un pixel WriteableBitmap "corrente"Cosa fa l'operatore >> in C#?

for(int i = 0; i < bitmapArray.Length; i++) { 
    var current = bitmapArray[i]; 

    var alpha = (byte)(current >> 24); 
    var red = (byte)(current >> 16); 
    var green = (byte)(current >> 8); 
    var blue = (byte)(current); 
    //Some code 
} 

ciò che è ">>" facendo per convertire i valori?

Inoltre, se eseguo alcuni calcoli su r, geb individualmente, come posso convertirli in un valore ARGB intero per sostituire il pixel originale con quello nuovo?

Grazie in anticipo.

Modifica: grazie ragazzi, ha senso ora.

+0

In realtà è piuttosto irritante che la struttura 'Color' in Silverlight non fornisca un mezzo per convertire un' Int32' in 'Color'. – AnthonyWJones

risposta

12

Sta spostando i bit del valore current a destra. Nel caso di questo particolare snippit di codice, sembra che stia estraendo ogni byte di informazioni sul colore dall'elemento di matrice di bitmap selezionato in byte di colore individuali.

http://msdn.microsoft.com/en-us/library/xt18et0d.aspx

Supponendo che l'array contiene interi, per ottenere un valore calcolato nuovamente dentro l'elemento dell'array, si potrebbe invertire il processo bit-shifting e OR i risultati di nuovo insieme, in questo modo:

int current = (alpha << 24) | (red << 16) | (green << 8) | blue; 
+0

Mi chiedo ... è 'BitConverter.GetBytes (corrente)' troppo complicato? Hm, forse troppo lento per una seria manipolazione delle immagini. – Joey

+0

@Johannes: 'BitConverter' è molto veloce. Immagino che sarebbe appropriato qui. –

+1

È un'operazione così semplice, ovvia e comune che non vedo il vantaggio di utilizzare altro che operatori binari.Se non capisci cosa sta succedendo, dovresti imparare o stare lontano dall'elaborazione delle immagini (non "tu" in particolare, solo in generale) –

16

È l'operatore di spostamento binario.

Se si dispone di un colore definito da (a, r, g, b), è la rappresentazione binaria sarebbe simile a questa (assumendo una profondità del canale di 8 bit):

AAAAAAAA RRRRRRRR GGGGGGGG BBBBBBBB 

Quindi, spostare tutta quella cosa più 24 posti e si sono lasciati con il canale alfa

AAAAAAAA 

Spostamento del 16 e si ottiene il canale alfa e il canale rosso

AAAAAAAARRRRRRRR 

Ora, dal momento che è gettato come un byte, solo i primi 8 bit vengono estratti

(byte)AAAAAAAARRRRRRRR == RRRRRRRR 

Si potrebbe anche ottenere il canale rosso spostando 16 posti e AND'ing con 11111111 (0xFF)

AAAAAAAARRRRRRRR & 
0000000011111111 
---------------- 
00000000RRRRRRRR 
+1

+1. Questa è una grande spiegazione, mi sono sempre chiesto il cambio di bit e il modo in cui funziona. Se tu avessi tempo, sarebbe bello vedere un esempio di come il fare cambia il valore di un colore e come. Ad esempio, come il bit shifting cambia 128, 64, 256 in un altro valore RGB. Inoltre, non sottovaluto ancora '(byte) AAAAAAAARRRRRRRR == RRRRRRRR' (cioè è estratto da destra a sinistra?), Ma almeno ne so più di prima di visitare questa risposta. –

+0

@Otaku: il file binario viene letto da destra a sinistra e, in questo caso, "primi 8 bit" significa proprio questo. – junkforce

+0

Se si esegue il cast (pixel e 0xff000000) su un byte, si otterrà uno zero indipendentemente da quando gli 8 bit più a destra saranno 0. Quindi non penso che il tuo ultimo blocco sia corretto. – Jacob

2

seguito alla risposta di Robert - e per coprire la seconda parte della tua domanda - è possibile combinare i componenti separati di nuovo in un intero utilizzando i << (left-shift) e | (bitwise OR) operatori:

int combined = (alpha << 24) | (red << 16) | (green << 8) | blue; 
+0

@Robert: L'OP non specifica, e suppongo che filosoficamente non sia né - è solo un set di 4 ottetti senza segno. Se il * meccanismo di memorizzazione * è un 'int', allora il mio codice funzionerà perfettamente (e il risultato sarà un' int' negativo se il valore alfa è maggiore di 127). Se il meccanismo di archiviazione è un 'uint', saranno necessari ulteriori casting ecc. – LukeH