Manipulați efectele vizuale cu ColorMatrixFilter și ConvolutionFilter

ColorMatrixFilter și ConvolutionFilter pot fi folosite pentru a transforma vizual obiectele Flash. În acest articol, vă voi arăta cât de ușor este să manipulați, folosind un instrument răcoros pe care l-am construit pentru o experimentare simplă.




Introducere

V-ați experimentat vreodată cu filtrele Flash ColorMatrix și Convolution? Am săpat în jur într-o căutare pentru a găsi câteva lucruri interesante pe care le puteți face cu Flash și am dat peste ei. Experimentarea cu ele poate duce la rezultate minunate.

Am scris un EffectsTester pentru a facilita experimentarea cu ei. Check out aceste camshots am luat în timp ce joc cu el:

Acum, dacă veți găsi interesant, permiteți-mi să vă văd ce sunt cele două filtre.

Filtrul matricei de culoare

Filtrul Matrix Color este utilizat pentru a manipula culoarea unui obiect afișat.

Permiteți-mi să explic calculul exact efectuat de ColorMatrixFilter. Fiecare pixel dintr-o imagine este un amestec de roșu, verde și albastru. Aceste culori primare, atunci când sunt combinate, pot face orice altă culoare:

Imagine de la Wikimedia Commons. Mulțumesc lui Mike Horvath și jacobolus.

Cantitatea de roșu într-un pixel poate varia de la zero (fără roșu la toate) la 255. Același lucru este pentru verde și albastru. Deci, din imaginea de mai sus, puteți vedea că un pixel pur galben are roșu = 255 și verde = 255. Albul are roșu, verde și albastru toate setate la 255. Negrul are toate cele trei setate la zero.

Filtrul matricei de culoare privește fiecare pixel dintr-o imagine sursă și le schimbă în funcție de cât de mult este roșu, albastru și verde în pixel. Încheiați o imagine cu totul nouă; destinație.

Iată cum funcționează

În primul rând, să ne concentrăm pe aceste trei valori:

Să etichetăm aceste valori a [0], a [1] și a [2] la rândul lor. Acum, gândiți-vă la un singur pixel în întreaga imagine sursă (cea din colțul din stânga sus va face). Să numim cantitatea de roșu în asta srcR, cantitatea de verde srcG și cantitatea de albastru srcB.

Întrebarea este: cât de mult va fi roșul în acel pixel al imaginii destinației, destR? Flash utilizează acest calcul:

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

Aici puteți vedea că un [0] este 1, în timp ce un [1] și un [2] sunt ambele la zero, deci:

 destR = (1 * srcR) + (0 * srcG) + (0 * srcB); // ceea ce înseamnă ... destR = srcR;

Nu există nicio schimbare! Dar dacă am schimba un [0] la zero și un [1] la 1? Atunci:

 destR = (0 * srcR) + (1 * srcG) + (0 * srcB); // ceea ce înseamnă ... destR = srcG;

... cantitatea de roșu din pixelul de destinație ar fi egală cu suma de verde în pixelul sursă! În plus, dacă ați schimbat al doilea rând pentru a citi "1 0 0", atunci cantitatea de verde din pixelul de destinație ar fi egală cu cantitatea de roșu din pixelul sursă; le-ai fi schimbat și peștii tăi portocalii s-ar transforma în pești verzi:

Probabil că vă întrebați A coloana și rândul și despre ofset coloană. Ei bine, A înseamnă alfa, ceea ce înseamnă transparență. Valorile A au același efect ca și valorile RG B, dar din moment ce niciuna dintre aceste imagini eșantion nu este transparentă, este greu de demonstrat. Coloana Offset vă permite să măriți sau să micșorați cantitatea de roșu, albastru sau verde în pixelul de destinație: introduceți -255 în coloana Offset din rândul R și veți vedea că în imagine nu mai există roșu.

Experiment

Îmi dau seama că este dificil să înțelegeți acest lucru doar din citirea despre el, așa că vom examina câteva exemple de exemplu reci. Este mult mai distractiv, oricum. Dar mai întâi, pentru cei curioși, aici este formula reală matematică Flash folosită:

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

(Fiecare dintre valorile pe care le vedeți în matricea 5x4 poate varia între -255 și 255.)

Aruncați o privire la imaginea eșantionului "Color Chart":

Acum, să presupunem că doriți să eliminați toate culorile roșii din imagine. Trebuie doar să setați toate valorile din rândul R la zero:

Asta înseamnă:

 destR = (0 * srcR) + (0 * srcG) + (0 * srcB) + (0 * srcA) + 0; // care înseamnă: destR = 0 + 0 + 0 + 0 + 0; // astfel: destR = 0;

Acum, să spunem că doriți să adăugați ceva mai verde acolo unde a existat anterior roșu. Puneți "1" la intrarea 0x1, astfel încât rândul G scrie "1 1 0 0 0":

Să realizăm acum ceva foarte ciudat prin schimbarea rândului G la "0 -1 0 0 50":

Ce s-a intamplat? De exemplu, dacă la un pixel aleatoriu ați avut verde = 30, acesta a fost înmulțit cu "-1" și apoi a fost adăugat 50, astfel încât rezultatul ar fi: (30 * -1) + 50 = 20.

Prin urmare, un tip de prag este creat: pentru fiecare pixel cu o valoare verde mai mare de 50, pixelul transformat va fi oprit complet. De ce? Să presupunem că canalul verde al pixelilor are o valoare de 51:

 destG = (0 * srcR) + (-1 * srcG) + (0 * srcB) + (0 * srcA) + 50; // amintesc srcG = 51: destG = 0 + (-51) + 0 + 0 + 50; // astfel: destG = - 51 + 50; // astfel: destG = -1; // dar un pixel nu poate avea o valoare negativă de verde, deci acesta este doar setat la zero: destG = 0;

Încearcă acum:

Toți pixelii cu valori mai mari de 50 sunt dezactivate, iar cele cu valori mai mici de 50 au toate cele trei canale de culoare crescute. Acest lucru vă permite să vedeți zone ale imaginii care au doar o cantitate foarte mică de verde, ca și în cazul imaginii de pește:

X

Aici, doar pixelii cu o cantitate de verde mai mică de 50. Cu cât este mai întunecată pixelul, cu atât mai verde este în imaginea originală. Acesta este principiul de bază oricum. Știu că poate părea complicat la început, dar jucați cu el și veți obține în cele din urmă :)

Alb-negru

OK, hai să facem ceva standard: o imagine în tonuri de gri. Schimbați-vă matricea așa:

Ai o scară de gri. Frumos :)

Culori inversate

Să realizăm o altă stare de culoare populară: Culori inversate.

Pentru a inversa culorile, trebuie să facem ca fiecare pixel cu o valoare roșie de 255 să aibă o valoare roșie de zero și invers. Același lucru pentru celelalte două culori. Deci, trebuie să facem Flash să ruleze codul care arată astfel:

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

Dar este ușor! Tot ce trebuie să facem este să setăm matricea astfel:

Tada! Pești electrici:

Mai multe efecte

Cele mai multe dintre efectele exotice care pot fi obținute de ColorMatrixFilter se fac prin stabilirea unei valori negative pentru o culoare și o valoare pozitivă pentru offset - sau invers. Puneți "-1" de la 0x3 la 2x3 (alphas) ​​și 255 pentru a compensa alfa (4x3).
Acum, acum știu cum au făcut Terminator 2 :)

Sincer, nu sunt sigur ce am făcut - calculele devin foarte greu de urmărit după un timp.

Deși este posibil să înțelegem cum funcționează ColorMatrixFilter dintr-un punct de vedere matematic, în realitate va rămâne o chestiune de a juca cu el. Niciodată nu poți fi sigură ce va apărea atunci când vei pune niște valori specifice. De aceea am făcut acest Teste de Efecte. Deci jucați în jur. Fă-ți verde metalic, sau roșu, sau incolor.

Real World Application

Când aveți un efect pe care îl doriți, îl puteți aplica la orice DisplayObject (MovieClip, Sprite, Bitmap ...) în propriul cod ca acesta:

 // introduceți mai întâi ColorMatrixFilter în partea de sus a codului dvs.: import flash.filters.ColorMatrixFilter; // ... mai târziu: var filtru: Array = new Array (); // pentru totul după "= new", copiați și inserați din caseta "Cumpărați codul" din EfecteTester: var cmf: ColorMatrixFilter = nou ColorMatrixFilter (noul Array (-1,0,0,0,255,0, -1,0 , 0,255,0,0, -1,0,255,0,0,0,1,0)); // următoarele două linii aplică filtrul pe obiectul afișat: filters.push (cmf); myDisplayObject.filters = filtre;

Acum, să ne uităm la filtrul de convoluție.

Filtrul Convoluție

Din referința claselor Adobe:

O convoluție combină pixeli în imaginea de intrare cu pixelii vecini pentru a produce o imagine. O mare varietate de efecte de imagine pot fi obținute prin convoluții, incluzând neclaritatea, detectarea marginilor, ascuțirea, ștanțarea și tăierea.

ConvolutionFilter rulează prin toți pixelii unui obiect afișat. Pentru fiecare dintre ele, aceasta utilizează valoarea centrală în matrice ca valoare a pixelului curent care este manipulat. De exemplu, într-o matrice 3 x 3, valoarea centrului este la (1, 1). Apoi, se multiplică valorile din matrice cu pixelii din jur și se adaugă valorile rezultate pentru toți pixelii pentru a obține valoarea pentru pixelul central rezultat.

Înțelegerea matematică exactă sub matricea Convoluție merită un articol complet nou, așa că nu voi acoperi toate acestea aici. Dacă doriți să intrați în acesta, consultați această postare pe adobe.com.

Cu toate acestea, o simplă redare cu valorile vă va da în cele din urmă toate efectele posibile pe care le puteți obține. Și va fi distractiv :) Deci, să vedem ce putem face!

Experiment

Filtrul de convoluție folosește o matrice, la fel ca filtrul de matrice de culoare. Din nou, valorile variază între -255 și 255. Și din nou, realizați majoritatea efectelor interesante atunci când combinați valorile negative cu cele pozitive.

Permiteți-mi să vă împărtășesc observațiile mele despre cum funcționează acest lucru. Încercați să crească unele valori aleatorii din matrice. Indiferent ce alegeți, va lumina imaginea; dacă doriți ca imaginea să rămână la o luminozitate normală, asigurați-vă că valoarea "divizorului" este egală cu suma tuturor valorilor din matrice.

Acum, dacă încercați să micșorați o valoare aleatorie sub zero în timp ce țineți cel puțin o altă valoare deasupra nulului, veți obține ceva ce se întâmplă acolo. Afectează marginile dvs.:

Iată unul frumos: vrea să arate ca un soldat? :) Încercați aceste valori:

Acum micșorați valoarea "divizorului" la "-1" pentru a deveni soldat în timpul unei misiuni pe timp de noapte.

O mulțime de lucruri pot fi realizate dacă țineți butonul mouse-ului puțin mai mult :) Mai jos și ridicați unele valori la extreme. Nu uitați să ajustați "divizorul" - este crucial. Măriți-vă matricea. Fa-o de 5x5, de exemplu.

Real World Application

Pentru a aplica efectul în propriul cod, utilizați filtre obiect, așa cum ați făcut pentru ColorMatrixFilter:

 // introduceți primul ConvolutionFilter în partea de sus a codului: import flash.filters.ConvolutionFilter; // ... mai târziu: var filtru: Array = new Array (); // pentru totul după "= new", copiați și lipiți din caseta "Cumpărați codul" din EfecteTester: var cf: ConvolutionFilter = nou ConvolutionFilter (3,3, noul Array (1,0, -10,2,3 , 1,6,1, -1), 0); // următoarele două linii aplică filtrul pe obiectul afișat: filters.push (cf); myDisplayObject.filters = filtre;

În cele din urmă: încercați să combinați ambele filtre.

 // introduceți mai întâi clasele de filtrare în partea de sus a codului dvs.: import flash.filters.ColorMatrixFilter; import flash.filters.ConvolutionFilter; // ... mai târziu: var filtru: Array = new Array (); // pentru totul după "= new", copiați și inserați din caseta "Cumpărați codul" din EfecteTester: var cmf: ColorMatrixFilter = nou ColorMatrixFilter (noul Array (-1,0,0,0,255,0, -1,0 , 0,255,0,0, -1,0,255,0,0,0,1,0)); var cf: ConvolutionFilter = ConvolutionFilter nou (3,3, Array nou (1,0, -10, -2,3,1,6,1, -1), 0); // următoarele trei linii aplică filtrele pe obiectul afișat: filters.push (cf); filters.push (cmf); myDisplayObject.filters = filtre;

Distreaza-te jucand cu aceste filtre si postezi rezultatele obtinute in comentarii! Vă mulțumim pentru lectură.

Cod