Manipolare gli effetti visivi con ColorMatrixFilter e ConvolutionFilter

ColorMatrixFilter e ConvolutionFilter possono essere utilizzati per trasformare visivamente i tuoi oggetti Flash. In questo articolo, ti mostrerò quanto sono facili da manipolare, usando uno strumento interessante che ho costruito per una semplice sperimentazione.




introduzione

Avete mai provato i filtri ColorMatrix e Convolution di Flash? Stavo scavando in una ricerca per trovare alcune cose interessanti che puoi fare con Flash e mi sono imbattuto in loro. Sperimentare con loro può portare a risultati fantastici.

Ho scritto un EffectsTester per facilitare l'esperimento con loro. Guarda queste foto che ho scattato mentre giocavo:

Ora, se lo trovi interessante, lascia che ti spieghi in cosa consistono questi due filtri.

Il filtro Color Matrix

Il filtro Color Matrix viene utilizzato per manipolare il colore di un oggetto di visualizzazione.

Lasciatemi spiegare il calcolo esatto eseguito da ColorMatrixFilter. Ogni pixel in un'immagine è una miscela di rosso, verde e blu. Questi colori primari, quando combinato, può fare qualsiasi altro colore:

Immagine da Wikimedia Commons. Grazie a Mike Horvath e Jacobolus.

La quantità di rosso in un pixel può variare da zero (nessun rosso) a 255. Lo stesso per verde e blu. Quindi, dall'immagine sopra, puoi vedere che un pixel giallo puro ha rosso = 255 e verde = 255. Il bianco ha rosso, verde e blu tutti impostati su 255. Il nero ha tutti e tre impostati a zero.

Il filtro a matrice di colori esamina ciascun pixel in un'immagine di origine e li modifica in base alla quantità di rosso, blu e verde nel pixel. Finisci con un'immagine completamente nuova; il immagine di destinazione.

Ecco come funziona

Per prima cosa, concentriamoci su questi tre valori:

Etichettiamo questi valori a [0], a [1] e a [2] a turno. Ora, pensa a un solo pixel nell'intera immagine sorgente (quello che farà l'angolo in alto a sinistra). Chiamiamo la quantità di rosso in quello srcR, la quantità di verde srcG e la quantità di blu srcB.

La domanda è: quanto rosso sarà in quel pixel dell'immagine di destinazione, destr? Flash utilizza questo calcolo:

 destR = (a [0] * srcR) + (a [1] * srcG) + (a [2] * srcB);

Qui puoi vedere che a [0] è 1, mentre a [1] e a [2] sono entrambi zero, quindi:

 destR = (1 * srcR) + (0 * srcG) + (0 * srcB); // che significa ... destR = srcR;

Non c'è cambiamento! Ma cosa succede se abbiamo cambiato un [0] a zero e un [1] a 1? Poi:

 destR = (0 * srcR) + (1 * srcG) + (0 * srcB); // che significa ... destR = srcG;

... la quantità di rosso nel pixel di destinazione sarebbe pari alla quantità di verde nel pixel sorgente! Inoltre, se hai cambiato la seconda riga da leggere "1 0 0", quindi la quantità di verde nel pixel di destinazione sarebbe uguale alla quantità di rosso nel pixel di origine; li avresti scambiati e i tuoi pesci arancioni si sarebbero trasformati in quelli verdi:

Probabilmente ti starai chiedendo il UN colonna e riga e circa il Compensare colonna. Bene, A sta per alpha, che significa trasparenza. I valori A hanno lo stesso effetto dei valori R G B, ma poiché nessuna di queste immagini campione è trasparente, è difficile da dimostrare. La colonna Offset ti consente semplicemente di aumentare o diminuire la quantità di rosso, blu o verde nel pixel di destinazione: digita -255 nella colonna Offset della riga R e vedrai che non c'è più alcun rosso nell'immagine.

Sperimentare

Mi rendo conto che è difficile capirlo solo leggendo a riguardo, quindi daremo un'occhiata ad alcuni fantastici effetti di esempio. È molto più divertente, comunque. Ma prima, per i curiosi, ecco l'attuale formula matematica che usa Flash:

 destR = (a [0] * srcR) + (a [1] * srcG) + (a [2] * srcB) + (a [3] * srcA) + a [4]; destG = (a [5] * srcR) + (a [6] * srcG) + (a [7] * srcB) + (a [8] * srcA) + a [9]; destB = (a [10] * srcR) + (a [11] * srcG) + (a [12] * srcB) + (a [13] * srcA) + a [14]; destA = (a [15] * srcR) + (a [16] * srcG) + (a [17] * srcB) + (a [18] * srcA) + a [19];

(Ciascuno dei valori che vedi nella matrice 5x4 può variare tra -255 e 255.)

Dai un'occhiata all'immagine di esempio "Grafico a colori":

Ora, diciamo che vuoi rimuovere tutti i colori rossi dall'immagine. Basta impostare tutti i valori nella riga R a zero:

Questo significa:

 destR = (0 * srcR) + (0 * srcG) + (0 * srcB) + (0 * srcA) + 0; // che significa: destR = 0 + 0 + 0 + 0 + 0; // so: destR = 0;

Ora diciamo che vuoi aggiungere un po 'più verde dove prima c'era il rosso. Metti "1" all'ingresso 0x1, quindi la riga G riporta "1 1 0 0 0":

Raggiungiamo ora qualcosa di molto strano cambiando la riga G in "0 -1 0 0 50":

Cosa è appena successo? Ad esempio, se in alcuni pixel casuali avevi green = 30, veniva moltiplicato con '-1' e successivamente veniva aggiunto 50, quindi il risultato sarebbe: (30 * -1) + 50 = 20.

Pertanto, un tipo di soglia viene creato: per ogni pixel con un valore verde maggiore di 50, i pixel trasformati verranno completamente disattivati. Perché? Supponiamo che il canale verde del pixel abbia un valore di 51:

 destG = (0 * srcR) + (-1 * srcG) + (0 * srcB) + (0 * srcA) + 50; // remember srcG = 51: destG = 0 + (-51) + 0 + 0 + 50; // so: destG = - 51 + 50; // so: destG = -1; // ma un pixel non può avere una quantità negativa di verde, quindi questo è appena impostato a zero: destG = 0;

Ora prova questo:

Tutti i pixel con valori verdi maggiori di 50 vengono disattivati ​​e quelli con valori verdi inferiori a 50 hanno tutti e tre i canali di colore aumentati. Questo ti permette di vedere aree dell'immagine che hanno solo una piccola quantità di verde, come con l'immagine del pesce:

X

Qui, solo i pixel con una quantità di verde inferiore a 50. Più scuro è il pixel, più verde c'è nell'immagine originale. Questo è comunque il principio base. So che all'inizio può sembrare complicato, ma giocaci e alla fine lo otterrai :)

Scala di grigi

OK, andiamo per qualcosa di standard: un'immagine in scala di grigi. Cambia la tua matrice in questo modo:

Hai una scala di grigi. Bello :)

Colori invertiti

Raggiungiamo un altro popolare stato di colore: Colori invertiti.

Per invertire i colori, dobbiamo fare in modo che ogni pixel con un valore rosso di 255 abbia un valore rosso pari a zero e viceversa. Lo stesso per gli altri due colori. Quindi abbiamo bisogno di creare codice di esecuzione Flash simile a questo:

 destR = 255 - srcR; destG = 255 - srcG; destB = 255 - srcB;

Ma è facile! Tutto ciò che dobbiamo fare è impostare la matrice in questo modo:

Tada! Pesce elettrico:

Più effetti

La maggior parte degli effetti più esotici che possono essere ottenuti da ColorMatrixFilter vengono eseguiti impostando un valore negativo per un colore e un valore positivo per l'offset o viceversa. Metti "-1" da 0x3 a 2x3 (l'alfa) e 255 per sfalsare l'alfa (4x3).
Wow, ora so come hanno fatto Terminator 2 :)

Onestamente, non sono proprio sicuro di quello che ho appena fatto - i calcoli diventano davvero difficili da tracciare dopo un po '.

Sebbene sia possibile capire come il ColorMatrixFilter funzioni da un punto di vista matematico, realisticamente rimarrà una questione di giocarci. Non puoi mai essere esattamente sicuro di ciò che sta per apparire quando inserisci valori specifici. Ecco perché ho creato questo EffectsTester. Quindi, gioca. Renditi verde metallizzato, o rosso, o incolore.

Applicazione del mondo reale

Quando hai un effetto che ti piace, puoi applicarlo a qualsiasi DisplayObject (MovieClip, Sprite, Bitmap ...) nel tuo codice come questo:

 // prima importare ColorMatrixFilter nella parte superiore del codice: import flash.filters.ColorMatrixFilter; // ... più avanti: var filters: Array = new Array (); // per tutto dopo "= new", copia e incolla dalla casella "Grab The Code" di EffectsTester: var cmf: ColorMatrixFilter = new ColorMatrixFilter (new Array (-1,0,0,0,255,0, -1,0 , 0,255,0,0, -1,0,255,0,0,0,1,0)); // le prossime due righe applicano il filtro all'oggetto di visualizzazione: filters.push (cmf); myDisplayObject.filters = filtri;

Ora diamo un'occhiata al filtro di convoluzione.

Il filtro convoluzione

Dal riferimento alla classe di Adobe:

Una convoluzione combina i pixel nell'immagine di input con i pixel vicini per produrre un'immagine. È possibile ottenere un'ampia gamma di effetti immagine attraverso le convoluzioni, tra cui sfocatura, rilevamento dei bordi, nitidezza, goffratura e smussatura.

ConvolutionFilter scorre tutti i pixel di un oggetto di visualizzazione. Per ognuno di essi, utilizza il valore centrale nella matrice come valore del pixel corrente che viene manipolato. Ad esempio, in una matrice 3 x 3, il valore centrale è a (1, 1). Quindi moltiplica i valori dalla matrice per i pixel circostanti e aggiunge i valori risultanti per tutti i pixel per ottenere il valore per il pixel centrale risultante.

Comprendere la matematica esatta al di sotto della matrice di Convolution vale un intero nuovo articolo, quindi non coprirò tutto questo qui. Se vuoi approfondire questo, controlla questo post su adobe.com.

Tuttavia, un semplice gioco con i valori alla fine ti darà tutti gli effetti possibili che puoi ottenere. E sarà divertente :) Allora vediamo cosa possiamo fare!

Sperimentare

Il filtro di convoluzione utilizza una matrice, proprio come il filtro matriciale. Ancora una volta, i valori variano tra -255 e 255. E ancora, ottieni la maggior parte degli effetti interessanti quando combini i valori negativi con quelli positivi.

Permettetemi di condividere con voi le mie osservazioni su come funziona questa cosa. Prova ad aumentare un valore casuale dalla matrice. Qualunque cosa tu scelga, alleggerirà l'immagine; se vuoi che l'immagine rimanga alla normale luminosità, assicurati che il valore di "divisore" sia uguale alla somma di tutti i valori nella matrice.

Ora se provi ad abbassare un valore casuale sotto lo zero mantenendo almeno un altro sopra lo zero, ottieni qualcosa che sta succedendo lì. Colpisce i tuoi bordi:

Ecco una bella cosa: vuoi sembrare un soldato? :) Prova questi valori:

Ora abbassa il valore del "divisore" a "-1" per diventare un soldato in missione durante la notte.

Un sacco di cose può essere raggiunto se si tiene premuto il pulsante del mouse un po 'di più :) Abbassare e aumentare alcuni valori agli estremi. Non dimenticare di regolare il "divisore": è fondamentale. Ingrandisci la tua matrice. Rendilo 5x5, per esempio.

Applicazione del mondo reale

Per applicare l'effetto nel tuo codice, usa il filtri oggetto, proprio come hai fatto per ColorMatrixFilter:

 // first import ConvolutionFilter up nella parte superiore del codice: import flash.filters.ConvolutionFilter; // ... più avanti: var filters: Array = new Array (); // per tutto dopo "= new", copia e incolla dalla casella "Grab The Code" di EffectsTester: var cf: ConvolutionFilter = new ConvolutionFilter (3,3, new Array (1,0, -10, -2,3 , 1,6,1, -1), 0); // le prossime due righe applicano il filtro all'oggetto di visualizzazione: filters.push (cf); myDisplayObject.filters = filtri;

Infine: prova a combinare entrambi i filtri.

 // prima importa le classi filtro nella parte superiore del tuo codice: import flash.filters.ColorMatrixFilter; import flash.filters.ConvolutionFilter; // ... più avanti: var filters: Array = new Array (); // per tutto dopo "= new", copia e incolla dalla casella "Grab The Code" di EffectsTester: var cmf: ColorMatrixFilter = new ColorMatrixFilter (new Array (-1,0,0,0,255,0, -1,0 , 0,255,0,0, -1,0,255,0,0,0,1,0)); var cf: ConvolutionFilter = new ConvolutionFilter (3,3, new Array (1,0, -10, -2,3,1,6,1, -1), 0); // le prossime tre linee applicano i filtri all'oggetto di visualizzazione: filters.push (cf); filters.push (cmf); myDisplayObject.filters = filtri;

Divertiti a giocare con questi filtri e pubblica tutti i risultati che ottieni nei commenti! Grazie per aver letto.