ColorMatrixFilter och ConvolutionFilter kan användas för att visuellt omvandla dina Flash-objekt. I den här artikeln visar jag hur lätt de ska manipulera, med ett coolt verktyg som jag byggt för enkla experiment.
Har du någonsin experimenterat med Flashs ColorMatrix och Convolution-filter? Jag grävde runt i ett försök att hitta några intressanta saker du kan göra med Flash och jag stötte på dem. Experimentera med dem kan ge några fantastiska resultat.
Jag har skrivit en EffectsTester för att göra det lätt att experimentera med dem. Kolla in dessa camshots jag tog medan jag lekte med det:
Nu, om du tycker att det är intressant, låt mig gå igenom vad de här filtren handlar om.
Färgmatrisfiltret används för att manipulera färgen på ett visningsobjekt.
Låt mig förklara exakt beräkning utförd av ColorMatrixFilter. Varje pixel i en bild är en blandning av rött, grönt och blått. Dessa primära färger, när de kombineras kan göra någon annan färg:
Bild från Wikimedia Commons. Tack vare Mike Horvath och jacobolus.
Mängden rött i en pixel kan variera från noll (ingen röd alls) till 255. Samma för grön och blå. Så, från bilden ovan kan du se att en ren gul pixel har röd = 255 och grön = 255. Vit har rött, grönt och blått alltsat till 255. Svart har alla tre uppsättningar till noll.
Färgmatrisfiltret tittar på varje pixel i en källbild och ändrar dem baserat på hur mycket rött, blått och grönt är i pixeln. Du hamnar med en helt ny bild; de destinationsbild.
Låt oss först koncentrera oss på dessa tre värden:
Låt oss märka dessa värdena a [0], a [1] och a [2] i sin tur. Tänk nu på bara en enda bildpunkt i hela källbilden (den i det övre vänstra hörnet kommer att göra). Låt oss ringa mängden rött i det SRCR, mängden grön srcG och mängden blå srcB.
Frågan är: hur mycket rött kommer att vara i den pixeln i destinationsbilden, destR? Flash använder denna beräkning:
destR = (a [0] * srcR) + (a [1] * srcG) + (a [2] * srcB);
Här kan du se att a [0] är 1, medan en [1] och en [2] är båda noll, så:
destR = (1 * srcR) + (0 * srcG) + (0 * srcB); // vilket betyder ... destR = srcR;
Det finns ingen förändring! Men vad händer om vi ändrade en [0] till noll och en [1] till 1? Sedan:
destR = (0 * srcR) + (1 * srcG) + (0 * srcB); // vilket betyder ... destR = srcG;
... mängden rött i destinationspunkten skulle vara lika med mängden av grön i källpunkten! Dessutom, om du ändrade den andra raden att läsa "1 0 0", då skulle mängden grön i destinationspunkten vara lika med mängden röd i källpixeln; du skulle ha bytt dem över och din apelsin fisk skulle bli gröna:
Du undrar förmodligen om en kolumn och rad och om Offset kolumn. Tja, A står för alfa, vilket betyder öppenhet. A-värdena har ungefär samma effekt som R G B-värdena, men eftersom ingen av dessa provbilder är transparenta är det svårt att visa. Kolumnen Förskjutning gör att du enkelt kan öka eller minska mängden rött, blått eller grönt i målpunkten: skriv -255 i R-radens offsetkolumn och du ser att det inte längre finns något rött på bilden.
Jag inser att det är knepigt att förstå detta bara från att läsa om det, så vi ska titta på några coola exempel effekter. Det är väldigt roligare, ändå. Men för det nyfikna, här är den faktiska matematiska formeln Flash använder:
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];
(Var och en av de värden du ser i 5x4-matrisen kan variera mellan -255 och 255.)
Ta en titt på "Färgdiagram" -provbilden:
Låt oss nu säga att du vill ta bort all röd färg från bilden. Ange bara alla värden i R-raden till noll:
Detta betyder:
destR = (0 * srcR) + (0 * srcG) + (0 * srcB) + (0 * srcA) + 0; // vilket betyder: destR = 0 + 0 + 0 + 0 + 0; // så: destR = 0;
Låt oss nu säga att du vill lägga till lite mer grönt där det tidigare var rött. Sätt "1" vid ingången 0x1, så G-raden läser "1 1 0 0 0":
Låt oss nå uppnå något väldigt konstigt genom att ändra G-raden till "0 -1 0 0 50":
Vad hände nyss? Som exempel, om du vid någon slumpmässig pixel hade grön = 30 multiplicerades den med -1, och därefter tillsattes 50, så resultatet skulle vara: (30 * -1) + 50 = 20.
Därför en typ av tröskel skapas: för varje pixel med ett grönt värde större än 50 kommer dess transformerade pixel att vara helt avstängd. Varför? Tänk på att pixelens gröna kanal har ett värde på 51:
destG = (0 * srcR) + (-1 * srcG) + (0 * srcB) + (0 * srcA) + 50; // minns srcG = 51: destG = 0 + (-51) + 0 + 0 + 50; // så: destG = - 51 + 50; // så: destG = -1; // men en pixel kan inte ha en negativ mängd grön, så det här är bara inställt på noll: destG = 0;
Försök nu med det här:
Alla pixlar med gröna värden större än 50 blir avstängda och de med gröna värden under 50 har alla tre färgkanaler ökat. Detta låter dig se områden av bilden som bara har en mycket liten mängd grön, som med fiskbilden:
xHär är bara pixlarna med en mängd grön mindre än 50. Ju mörkare pixeln desto mer grön finns i originalbilden. Det är dock grundläggande principen. Jag vet att det kan tyckas komplicerat först, men spela med det och du får det så småningom :)
OK, låt oss gå till något standard: en gråskala bild. Ändra din matris så här:
Du har en gråskala. Trevlig :)
Låt oss uppnå ett annat populärt färgtillstånd: Inverterade färger.
För att invertera färgerna måste vi göra så att varje pixel med ett rött värde på 255 har ett rött värde på noll och vice versa. Samma för de andra två färgerna. Så vi måste göra Flash-koden som ser ut så här:
destR = 255 - srcR; destG = 255 - srcG; destB = 255 - srcB;
Men det är enkelt! Allt vi behöver göra är att ställa in matrisen så här:
Tada! Elektrisk fisk:
De flesta exotiska effekter som kan uppnås med ColorMatrixFilter görs genom att ange ett negativt värde för en färg och ett positivt värde för offset - eller vice versa. Sätt "-1" från 0x3 till 2x3 (alfaserna) och 255 för offset av alfa (4x3).
Wow, nu vet jag nu hur de gjorde Terminator 2 :)
Ärligt talat är jag inte riktigt säker på vad jag just gjorde - beräkningarna blir väldigt svåra att spåra efter ett tag.
Även om det är möjligt att förstå hur ColorMatrixFilter fungerar från en matematisk synvinkel, kommer det realistiskt att vara en fråga om att leka med det. Du kan aldrig vara exakt säker på vad som kommer att dyka upp när du anger några specifika värden. Därför gjorde jag denna EffectsTester. Så lek runt. Gör dig själv metallisk grön, eller röd, eller färglös.
När du har en effekt du gillar kan du applicera den på alla DisplayObject (MovieClip, Sprite, Bitmap ...) i din egen kod så här:
// först importera ColorMatrixFilter upp längst upp i koden: importera flash.filters.ColorMatrixFilter; // ... senare: varfilter: Array = new Array (); // för allt efter "= nytt", kopiera och klistra in från "Grab The Code" -fältet i EffectsTester: var cmf: ColorMatrixFilter = ny ColorMatrixFilter (ny array (-1,0,0,0,255,0, -1,0 , 0,255,0,0, -1,0,255,0,0,0,1,0)); // De följande två raderna applicerar filtret på ditt visningsobjekt: filters.push (cmf); myDisplayObject.filters = filters;
Låt oss nu titta på konvolutionsfiltret.
Från Adobes klassreferens:
En konvoltering kombinerar pixlar i inmatningsbilden med närliggande pixlar för att producera en bild. Ett stort antal bildeffekter kan uppnås genom omvandlingar, inklusive oskärpa, kantdetektering, skärpning, prägling och fasning.
Konvolutionfiltret slingrar igenom alla pixlar i ett visningsobjekt. För varje av dem använder den mittvärdet i matrisen som värdet av den aktuella pixeln manipuleras. I en 3 x 3-matris är till exempel mittvärdet vid (1, 1). Det multiplicerar sedan värdena från matrisen med de omgivande bildpunkterna och lägger till de resulterande värdena för alla pixlar för att få värdet för den resulterande mittpunkten.
Att förstå den exakta matematiken under konvolutionsmatrisen är värt en helt ny artikel, så jag täcker inte allt detta här. Om du vill komma in i det, kolla in det här inlägget på adobe.com.
En enkel omgång med värdena kommer så småningom att ge dig alla möjliga effekter du kan uppnå. Och det blir roligt :) Så låt oss se vad vi kan göra!
Konfolutioneringsfiltret använder en matris, precis som färgmatrisfiltret. Igen varierar värdena mellan -255 och 255. Och igen uppnår du de flesta intressanta effekterna när du kombinerar negativa värden med positiva.
Låt mig dela med dig mina observationer av hur denna sak fungerar. Försök att öka något slumpmässigt värde från matrisen. Oavsett vad du väljer, kommer det att ljusna bilden; om du vill att bilden ska ligga vid normal ljusstyrka, se till att värdet på "divisor" är lika med summan av alla värden i matrisen.
Nu om du försöker sänka ett slumpmässigt värde under noll medan du håller minst en annan över noll, får du något som händer där. Det påverkar dina kanter:
Här är det trevligt: vill du se ut som en soldat? :) Prova dessa värden:
Sänk nu "divisor" -värdet till "-1" för att bli en soldat på ett uppdrag på natten.
Många saker kan uppnås om du håller musknappen lite mer :) Sänk och höja några värden till ytterligheter. Glöm inte att justera "divisor" - det är viktigt. Förstora din matris. Gör det till exempel 5x5.
För att använda effekten i din egen kod, använd filter objekt, precis som du gjorde för ColorMatrixFilter:
// först importera ConvolutionFilter upp längst upp i koden: importera flash.filters.ConvolutionFilter; // ... senare: varfilter: Array = new Array (); // för allt efter "= nytt", kopiera och klistra in från "Grab The Code" rutan av EffectsTester: var cf: ConvolutionFilter = ny ConvolutionFilter (3,3, ny Array (1,0, -10, -2,3 , 1,6,1, -1), 0); // De följande två raderna applicerar filtret på ditt visningsobjekt: filters.push (cf); myDisplayObject.filters = filters;
Slutligen: Försök kombinera båda filtren.
// först importera filter klasserna upp längst upp på din kod: importera flash.filters.ColorMatrixFilter; importera flash.filters.ConvolutionFilter; // ... senare: varfilter: Array = new Array (); // för allt efter "= nytt", kopiera och klistra in från "Grab The Code" -fältet i EffectsTester: var cmf: ColorMatrixFilter = ny ColorMatrixFilter (ny array (-1,0,0,0,255,0, -1,0 , 0,255,0,0, -1,0,255,0,0,0,1,0)); var cf: ConvolutionFilter = ny KonvolutionFilter (3,3, ny Array (1,0, -10, -2,3,1,6,1, -1), 0); // Följande tre rader gäller filtren till ditt visningsobjekt: filters.push (cf); filters.push (cmf); myDisplayObject.filters = filters;
Ha det roligt att spela med dessa filter och skicka några resultat du får i kommentarerna! Tack för att du läser.