Comparând filtrele în Flash

În acest tutorial, vom crea un program de filtrare care va permite utilizatorului să aplice diferite filtre unei imagini, să modifice nivelurile de intensitate și să compare imaginile originale și filtre. De asemenea, vom folosi componente pentru controalele noastre.




Prezentare scurta

Vor exista trei straturi: unul pentru ActionScript, altul pentru text și componente și ultimul pentru imagine. Programul compilat va conține două imagini, din moment ce unul va fi creat la execuție. Versiunea run-time va avea aplicate filtre. În plus, va fi creată o mască la timpul de execuție care va fi utilizată pentru a afișa / ascunde părți ale imaginii filtrate.

Presupun că aveți deja o înțelegere de bază a Flash și ActionScript 3.0. Totuși, voi încerca să păstrez fiecare pas cât mai clar posibil.

Notă: În timpul acestui tutorial voi folosi referințe slabe la adăugarea ascultătorilor de evenimente. Pentru mai multe informații despre referințele slabe, consultați acest post pe blog.

Pasul 1

Creați un nou document ActionScript 3.0. Setați dimensiunea Scenă la 600 x 500 pixeli. Am ales această dimensiune deoarece imaginea pe care o folosesc se va potrivi confortabil în cadrul acestor dimensiuni.

Pasul 2

Creați cele trei straturi menționate anterior (și anume "acțiuni", "text și componente" și "imagine (original)"). Blocați stratul "acțiuni" deoarece nu veți adăuga nimic la acest strat în afară de ActionScript.

Pasul 3

Selectați stratul "text și componente" și adăugați textul static "Filtru" și "Intensitate" în colțul din stânga sus.

Pasul 4

Accesați panoul Components și trageți cinci scene și două glisante pe scenă. În principiu, le puteți pune oricum, așa cum doriți.

Dați valorile etichetelor pentru butoane "Implicit", "Blur", "Embos", "Luminozitate" și "Negativ". Apoi le dați numele instanțelor "default_btn", "blur_btn", "emboss_btn", "brightness_btn" și "negative_btn".

Dați cursorului intensitate un nume de instanță a "intensity_sld", apoi denumiți glisorul mască "mask_sld".

Notă: Nu este prea important unde plasați glisorul mască, deoarece vom folosi ActionScript pentru ao repoziționa mai târziu.

Terminologie: De-a lungul acestui tutorial pot fi denumite "mask slider" sau "mask_sld" interschimbabile. Același lucru este valabil și pentru "glisorul de intensitate" și "intensity_sld".

Pasul 5

Acum puteți bloca stratul "text și componente". Apoi, selectați stratul "imagine (original)" și importați o imagine pe care doriți să o utilizați. Voi folosi o fotografie de păpădie.

Pasul 6

Selectați imaginea și convertiți-o într-un simbol Movie Clip. Am numit-o "păpădie", dar poate fi orice îți place. Asigurați-vă că punctul de înregistrare se află în colțul din stânga sus. Accesați vizualizarea "Avansat" și bifați "Export pentru ActionScript". "Export în cadru 1" trebuie să fie verificată automat. Pentru clasă, introduceți "PhotoDandelion" și lăsați clasa de bază ca "flash.display.MovieClip".

Pasul 7

Dă noua fotografie Clip Clip numele de instanță "photoOriginal". Acum puteți bloca stratul "imagine (original)".

Pasul 8 - Elementele de bază ale filtrelor

Flash vă permite să aplicați filtre similare celor din Photoshop. Puteți aplica filtre din panoul Proprietăți sau prin intermediul ActionScript. Iată câteva dintre filtrele de bază pe care le oferă Flash: teșitură, estompare, umbră, strălucire, etc.

Folosind ActionScript putem aplica un filtru pentru orice DisplayObject prin proprietatea "filtre". Valoarea atribuită proprietății "filtre" trebuie să fie o matrice. De asemenea, puteți aplica mai mult de un filtru.

 // Aplicarea unui filtru de neclaritate pe un DisplayObject. var fiFilter: BlurFilter = BlurFilter nou (); var arrFiltere: Array = [bFilter]; displayObj.filters = arrFilters;

Pasul 9 - Filtre de convoluție

Flash acceptă, de asemenea, filtre de convoluție care pot efectua efecte mai avansate, cum ar fi luminozitatea, detectarea margini, embosarea, etc.

Filtrele Convolution pot fi aplicate numai prin ActionScript și necesită, de asemenea, utilizarea unor matrici care descriu modul în care ar trebui să se efectueze culorile pentru fiecare pixel. Matricea trebuie să fie într-o matrice.

 // Valoare implicită var matrixDefault: Array = [0, 0, 0, 0, 1, 0, 0, 0, 0]; // Brighter var matrixBrighter: Array = [0, 0, 0, 0, 2, 0, 0, 0, 0]; // Darker var matrixDarker: Array = [0, 0, 0, 0, 0,5, 0, 0, 0, 0]; // Emboss var matrixEmboss: Array = [-1, -1, 0, -1, 1, 1, 0, 1, 1];

Valoarea centrală este pixelul curent, iar valorile înconjurătoare sunt pixelii vecini. Valoarea implicită este 1; creșterea acestei valori va face ca imaginea să fie mai luminată. Scăderea va provoca o întunecare. Având valori negative în partea stângă sus și valorile pozitive din dreapta jos (sau invers) creează un efect de emboss.

Folosind ActionScript, putem aplica un filtru de convoluție astfel:

 // Următoarea matrice va luminiza imaginea. var matrixBrighter: Array = [0, 0, 0, 0, 2, 0, 0, 0, 0]; var matrixCol: Număr = 3; // Numărul coloanei var matrixRow: Number = 3; // Numărul rândului var cvFilter: ConvolutionFilter = ConvolutionFilter nou (matrixCol, matrixRow, matrixBrighter); var arrFiltere: Array = [cvFilter]; displayObj.filters = arrFilters;

Pentru mai multe informații despre filtrul Convolution, consultați acest articol Adobe Flash.

Pasul 10

Acum vom scrie codul ActionScript. Selectați primul cadru al stratului "acțiuni" și intrați în panoul Acțiuni.

Pasul 11

În mod normal, îmi place să păstrez coerența textului în întregul program. Deci, aici este codul pentru setarea textului (Verdana) pentru toate componentele la nivel global.

 import fl.managers.StyleManager; var format: TextFormat = TextFormat nou ("Verdana", 10, 0x000000); StyleManager.setStyle ("textFormat", format);

Pasul 12

Acum, să creați o copie a fotografiei (pentru aplicarea filtrelor) și să o poziționați în aceeași locație ca și fotografia originală. Voi folosi versiunea B, deoarece vreau să aplice o mască după filtru. Cu versiunea A, dacă aplicați un filtru de neclaritate, puteți observa că estomparea depășește masca. Acest lucru se datorează faptului că filtrul își aplică efectul după mască.

Mai târziu, vom masca "photoWrapper" și vom aplica doar filtrele la "photoEffected".

 / * // Versiunea A var fotoEffected: PhotoDandelion = new PhotoDandelion (); photoEffected.x = photoOriginal.x; photoEffected.y = photoOriginal.y; addChild (photoEffected); * / // Versiunea B var photoWrapper: Sprite = Sprite nou (); photoWrapper.x = photoOriginal.x; photoWrapper.y = photoOriginal.y; var fotoEfectuată: PhotoDandelion = noua PhotoDandelion (); photoWrapper.addChild (photoEffected); addChild (photoWrapper);

Pasul 13

Apoi creați linia care va separa fotografia filtrată și originală. Vom folosi o formă pentru a desena o linie. Poziționați linia spre mijlocul inferior al fotografiei, apoi trageți linia de jos în sus.

 var compareLine: Shape = Formă nouă (); comparatieLine.x = photoOriginal.x + photoOriginal.width / 2; comparatieLine.y = photoOriginal.y + photoOriginal.height; comparațieLine.graphics.lineStyle (2, 0x999999, 1, true); comparațieLine.graphics.moveTo (0, 0); comparațieLine.graphics.lineTo (0, -photoOriginal.height); addChild (comparisonLine);

Pasul 14

Îți amintești că avem un cursor de mască. Folosind ActionScript, putem să o poziționăm sub fotografie și să o întindem astfel încât lățimea ei să fie aceeași cu lățimea fotografiei. Setarea valorilor "maximă" și "lățime" la lățimea fotografiei ajută la crearea unui raport de 1: 1. Prin urmare, nu va mai fi nevoie să creați o conversie la scară mai târziu. În plus, vom centra săgeata în cursă.

 mask_sld.x = photoOriginal.x; mask_sld.y = photoOriginal.y + photoOriginal.height; mask_sld.minimum = 0; mask_sld.maximum = photoOriginal.width; mask_sld.value = photoOriginal.width / 2; mask_sld.width = photoOriginal.width;

Pasul 15

Acum, să creăm funcția și să atribuim evenimentul pentru glisorul mască. Vrem ca "comparația" să urmeze cursorul de mascare. Lățimea "photoMask" trebuie să se schimbe în funcție de glisorul mască ori de câte ori este târât. Știu că nu am abordat încă "photoMask", dar acesta este următorul pas.

 import fl.events.SliderEvent; funcția maskSliderDrag (evt: SliderEvent): void compareLine.x = evt.target.value + evt.target.x; photoMask.width = evt.target.value;  mask_sld.addEventListener (SliderEvent.THUMB_DRAG, maskSliderDrag, false, 0, true);

Pasul 16

Așa cum am menționat anterior, "photoMask" va fi folosit pentru a masca "photoWrapper" spre deosebire de "photoEffected". De când va fi o mască rectangulară, vom folosi o formă. Setați poziția și dimensiunea dreptunghiului la aceeași valoare cu cea a "photoOriginal". Asigurați-vă că ați umplut forma cu o culoare (aceasta poate fi orice culoare) sau altfel masca poate să nu funcționeze conform așteptărilor. Apoi setați "photoMask" ca mască fotoWrapper și lățimea măștii la "valoarea" cursorului de mască,.

 var photoMask: Shape = Formă nouă (); photoMask.x = photoOriginal.x; photoMask.y = photoOriginal.y; photoMask.graphics.beginFill (0xff9900); photoMask.graphics.drawRect (0, 0, photoOriginal.width, photoOriginal.height); photoMask.graphics.endFill (); addChild (foto-mască); photoWrapper.mask = photoMask; photoMask.width = mask_sld.value;

Pasul 17

Avem nevoie de o modalitate de a stoca ultimul buton apăsat, pe care îl vom păstra în "activeFilter". Acesta va fi folosit ulterior de glisorul de intensitate.

 var activFilter: Buton;

Pasul 18

Apoi vom trece la cursorul de intensitate. Definim funcția "intensityChange" care va fi apelată ori de câte ori glisorul de intensitate este tras. Funcția va expedia un eveniment (adică un click de mouse) bazat pe ultimul buton apăsat. De asemenea, vom atribui evenimentul și vom dezactiva inițial cursorul.

 schimbarea funcției (evt: SliderEvent): void activeFilter.dispatchEvent (nou MouseEvent (MouseEvent.CLICK));  intensity_sld.addEventListener (SliderEvent.THUMB_DRAG, intensityChange, false, 0, true); intensity_sld.enabled = false;

Pasul 19

Acum, să definim funcțiile filtrului. Funcțiile de filtrare "implicite" și "negative" sunt similare prin aceea că ambele dezactivează glisorul de intensitate și, prin urmare, nu trebuie să actualizeze proprietățile cursorului. Pentru "blur", "emboss" și "luminozitate", toți trebuie să reactiveze sliderul de intensitate. În plus, utilizează proprietatea "value" pentru a determina intensitatea filtrului. De asemenea, fiecare filtru are propria sa valoare "maximă" unică, deci trebuie să recalculați "snapInterval". De asemenea, proprietatea "value" este recalculată, deoarece aș vrea ca glisorul să fie resetat pe jumătate între min și max. Trebuie doar să setăm proprietățile cursorului de intensitate atunci când "activeFilter" nu este egal cu țintă curentă.

 funcția default_btnHandler (evt: MouseEvent): void var matrixDefault: Array = [0, 0, 0, 0, 1, 0, 0, 0, 0]; var conv: ConvolutionFilter = noul ConvolutionFilter (3, 3, matrixDefault); photoEffected.filters = [conv]; activeFilter = evt.target ca buton; intensity_sld.enabled = false;  funcția blur_btnHandler (evt: MouseEvent): void if (activeFilter! = evt.target) intensity_sld.maximum = 30; intensity_sld.snapInterval = (intensity_sld.maximum - intensity_sld.minimum) / 40; intensity_sld.value = intensity_sld.maximum / 2;  var blurX: Număr = intensitate_valoare; var blurY: număr = intensitate_valoare; photoEffected.filters = [BlurFilter nou (blurX, blurY, BitmapFilterQuality.HIGH)]; activeFilter = evt.target ca buton; intensity_sld.enabled = true;  funcția emboss_btnHandler (evt: MouseEvent): void if (activeFilter! = evt.target) intensity_sld.maximum = 4; intensity_sld.snapInterval = (intensity_sld.maximum - intensity_sld.minimum) / 40; intensity_sld.value = intensity_sld.maximum / 2;  var matrixEmboss: Array = [-intensity_sld.value, -intensity_sld.value, 0, -intensity_sld.value, 1, value_sld.value, 0, intensity_sld.value, intensity_sld.value]; var conv: ConvolutionFilter = noul ConvolutionFilter (3, 3, matrixEmboss); photoEffected.filters = [conv]; activeFilter = evt.target ca buton; intensity_sld.enabled = true;  funcția brightness_btnHandler (evt: MouseEvent): void if (activeFilter! = evt.target) intensity_sld.maximum = 6; intensity_sld.snapInterval = (intensity_sld.maximum - intensity_sld.minimum) / 40; intensity_sld.value = intensity_sld.maximum / 2;  var matrixBrightness: Array = [0, 0, 0, 0, intensitate_valoare, 0, 0, 0, 0]; var conv: ConvolutionFilter = noul ConvolutionFilter (3, 3, matrixBrightness); photoEffected.filters = [conv]; activeFilter = evt.target ca buton; intensity_sld.enabled = true;  funcția negative_btnHandler (evt: MouseEvent): void var matrixNegativ: ColorMatrixFilter = nou ColorMatrixFilter ([- 1, 0, 0, 0, 255, 0, -1, 0, 255, 0, 0, -1, 0 , 255, 0, 0, 0, 1, 0]); photoEffected.filters = [matrixNegative]; activeFilter = evt.target ca buton; intensity_sld.enabled = false; 

Notă: Pentru filtrul "negativ", am folosit un ColorMatrixFilter care utilizează o matrice de 4 ori 5 pentru a aplica transformări de culoare. Pentru mai multe informații despre ColorMatrixFilter, consultați acest articol Adobe Flash.

Pasul 20

Acum, să alocăm fiecărui buton funcțiilor corespunzătoare.

 default_btn.addEventListener (MouseEvent.CLICK, default_btnHandler, false, 0, true); blur_btn.addEventListener (MouseEvent.CLICK, blur_btnHandler, false, 0, adevărat); emboss_btn.addEventListener (MouseEvent.CLICK, emboss_btnHandler, false, 0, true); brightness_btn.addEventListener (MouseEvent.CLICK, luminozitate_btnHandler, false, 0, true); negative_btn.addEventListener (MouseEvent.CLICK, negative_btnHandler, false, 0, true);

Pasul 21 - Codul final

Am creat trei funcții suplimentare: "applyConvolutionFilter", "activeFilterAndIntensityOnOff" și "setSliderProperties". Scopul lor este de a reduce codarea repetitivă în funcțiile filtrului.

Codul dvs. final final ar trebui să arate similar cu acest ...

 import fl.events.SliderEvent; import fl.managers.StyleManager; var format: TextFormat = TextFormat nou ("Verdana", 10, 0x000000); StyleManager.setStyle ("textFormat", format); var photoWrapper: Sprite = Sprite nou (); photoWrapper.x = photoOriginal.x; photoWrapper.y = photoOriginal.y; var fotoEfectuată: PhotoDandelion = noua PhotoDandelion (); photoWrapper.addChild (photoEffected); addChild (photoWrapper); var compareLine: Shape = Formă nouă (); comparatieLine.x = photoOriginal.x + photoOriginal.width / 2; comparatieLine.y = photoOriginal.y + photoOriginal.height; comparațieLine.graphics.lineStyle (2, 0x999999, 1, true); comparațieLine.graphics.moveTo (0, 0); comparațieLine.graphics.lineTo (0, -photoOriginal.height); addChild (comparisonLine); mask_sld.x = photoOriginal.x; mask_sld.y = photoOriginal.y + photoOriginal.height; mask_sld.minimum = 0; mask_sld.maximum = photoOriginal.width; mask_sld.value = photoOriginal.width / 2; mask_sld.width = photoOriginal.width; funcția maskSliderDrag (evt: SliderEvent): void compareLine.x = evt.target.value + evt.target.x; photoMask.width = evt.target.value;  mask_sld.addEventListener (SliderEvent.THUMB_DRAG, maskSliderDrag); var photoMask: Shape = Formă nouă (); photoMask.x = photoOriginal.x; photoMask.y = photoOriginal.y; photoMask.graphics.beginFill (0xff9900); photoMask.graphics.drawRect (0, 0, photoOriginal.width, photoOriginal.height); photoMask.graphics.endFill (); addChild (foto-mască); photoWrapper.mask = photoMask; photoMask.width = mask_sld.value; var activFilter: Buton; schimbarea funcției (evt: SliderEvent): void activeFilter.dispatchEvent (nou MouseEvent (MouseEvent.CLICK));  intensity_sld.addEventListener (SliderEvent.THUMB_DRAG, intensityChange); intensity_sld.enabled = false; funcția applyConvolutionFilter (matrice: Array): void var cFilter: ConvolutionFilter = ConvolutionFilter nou (3, 3, matrice); photoEffected.filters = [cFilter];  funcția activFilterAndIntensityOnOff (btn: Buton, intensityOnOff: Boolean): void activeFilter = btn; intensity_sld.enabled = intensityOnOff;  funcția setSliderProperties (btn: Buton, max: Număr): void if (activeFilter! = btn) intensity_sld.maximum = max; intensity_sld.snapInterval = (intensity_sld.maximum - intensity_sld.minimum) / 40; intensity_sld.value = intensity_sld.maximum / 2;  funcția default_btnHandler (evt: MouseEvent): void var matrixDefault: Array = [0, 0, 0, 0, 1, 0, 0, 0, 0]; applyConvolutionFilter (matrixDefault); activeFilterAndIntensityOnOff (evt.target ca Button, false);  funcția blur_btnHandler (evt: MouseEvent): void var btn: buton = evt.target ca buton; setSliderProperties (btn, 30); var blurX: Numărul = intensitatea_valoare; var blurY: număr = intensitate_valoare; photoEffected.filters = [BlurFilter nou (blurX, blurY, BitmapFilterQuality.HIGH)]; activeFilterAndIntensityOnOff (btn, adevărat);  funcția emboss_btnHandler (evt: MouseEvent): void var btn: buton = evt.target ca buton; setSliderProperties (btn, 4); var matrixEmboss: array = [-intensity_sld.value, -intensity_sld.value, 0, -intensity_sld.value, 1, intensity_sld.value, 0, intensity_sld.value, intensity_sld.value]; applyConvolutionFilter (matrixEmboss); activeFilterAndIntensityOnOff (btn, adevărat);  funcția brightness_btnHandler (evt: MouseEvent): void var btn: buton = evt.target ca buton; setSliderProperties (btn, 6); var matrixLuminozitate: Array = [0, 0, 0, 0, intensitate_valoare, 0, 0, 0, 0]; applyConvolutionFilter (matrixBrightness); activeFilterAndIntensityOnOff (btn, adevărat);  funcția negative_btnHandler (evt: MouseEvent): void var matrixNegativ: ColorMatrixFilter = nou ColorMatrixFilter ([- 1, 0, 0, 0, 255, 0, -1, 0, 255, 0, 0, -1, 0 , 255, 0, 0, 0, 1, 0]); photoEffected.filters = [matrixNegative]; activeFilterAndIntensityOnOff (evt.target ca Button, false);  default_btn.addEventListener (MouseEvent.CLICK, default_btnHandler, false, 0, true); blur_btn.addEventListener (MouseEvent.CLICK, blur_btnHandler, false, 0, adevărat); emboss_btn.addEventListener (MouseEvent.CLICK, emboss_btnHandler, false, 0, true); brightness_btn.addEventListener (MouseEvent.CLICK, luminozitate_btnHandler, false, 0, true); negative_btn.addEventListener (MouseEvent.CLICK, negative_btnHandler, false, 0, true);

Notă: Puteți merge chiar dincolo de ceea ce am făcut, cum ar fi implementarea unei funcții centrale care să cuprindă toate filtrele. Apoi folosiți un buton "if else if" sau "switch" pentru a executa codul necesar pentru filtrul corespunzător.

Concluzie

Există multe lucruri pe care le puteți face cu filtrele, pur și simplu am dat o scurtă introducere. Filtrele de bază din Flash sunt destul de bune, deoarece există parametri suficienți pentru a juca cu ei. Dacă nu găsiți ceea ce căutați, încercați câteva dintre celelalte filtre, cum ar fi ColorMatrixFilter, ConvolutionFilter, DisplacementMapFilter etc. Este posibil să fiți surprinsi de ceea ce găsiți. Continuați să experimentați și cel mai important, să vă distrați!

Vă mulțumim că ați acordat timp pentru a vedea acest tutorial. Sper că ați găsit-o utilă.

Cod