De ColorMatrixFilter en ConvolutionFilter kunnen worden gebruikt om uw Flash-objecten visueel te transformeren. In dit artikel laat ik je zien hoe gemakkelijk het is om te manipuleren, met behulp van een coole tool die ik heb gebouwd voor eenvoudige experimenten.
Hebben jullie wel eens geëxperimenteerd met Flash's ColorMatrix- en Convolution-filters? Ik was aan het graven in een zoektocht naar interessante dingen die je met Flash kunt doen en ik botste tegen ze op. Experimenteren met hen kan geweldige resultaten opleveren.
Ik heb een effectentester geschreven om het gemakkelijk te maken ermee te experimenteren. Bekijk deze camshots die ik heb gemaakt toen ik ermee speelde:
Nu, als je dat interessant vindt, laat me je eens doornemen waar deze twee filters allemaal over gaan.
Het kleurmatrixfilter wordt gebruikt om de kleur van een weergaveobject te manipuleren.
Laat me de exacte berekening uitleggen die door ColorMatrixFilter is uitgevoerd. Elke pixel in een afbeelding is een combinatie van rood, groen en blauw. Deze primaire kleuren, indien gecombineerd, kan elke andere kleur:
Afbeelding van Wikimedia Commons. Met dank aan Mike Horvath en jacobolus.
De hoeveelheid rood in een pixel kan variëren van nul (helemaal geen rood) tot 255. Hetzelfde voor groen en blauw. Dus, uit de afbeelding hierboven, kun je zien dat een zuiver gele pixel rood = 255 en groen = 255 heeft. Wit heeft rood, groen en blauw alle ingesteld op 255. Zwart heeft alle drie ingesteld op nul.
Het kleurenmatrixfilter kijkt naar elke pixel in een bronafbeelding en verandert deze op basis van hoeveel rood, blauw en groen de pixel is. Je krijgt een heel nieuw beeld; de bestemmingsafbeelding.
Laten we eerst ons concentreren op deze drie waarden:
Laten we deze waarden achtereenvolgens een [0], een [1] en een [2] labelen. Denk nu eens aan één enkele pixel in de volledige bronafbeelding (die in de linkerbovenhoek is voldoende). Laten we de hoeveelheid rood daarin noemen SRCR, de hoeveelheid groen srcG en de hoeveelheid blauw srcB.
De vraag is: hoeveel rood er in die pixel van de doelafbeelding zal zijn, Destr? Flash gebruikt deze berekening:
destR = (a [0] * srcR) + (a [1] * srcG) + (a [2] * srcB);
Hier kun je zien dat een [0] 1 is, terwijl een [1] en een [2] allebei nul zijn, dus:
destR = (1 * srcR) + (0 * srcG) + (0 * srcB); // wat betekent ... destR = srcR;
Er is geen verandering! Maar wat als we een [0] op nul zetten en een [1] op 1? Dan:
destR = (0 * srcR) + (1 * srcG) + (0 * srcB); // wat betekent ... destR = srcG;
... de hoeveelheid rood in de bestemmingspixel zou gelijk zijn aan de hoeveelheid groen in de bronpixel! Verder als u de tweede rij hebt gewijzigd om te lezen "1 0 0", dan zou de hoeveelheid groen in de bestemmingspixel gelijk zijn aan de hoeveelheid rood in de bronpixel; je zou ze geruild hebben en je oranje vis zou groen worden:
Je vraagt je waarschijnlijk af over de EEN kolom en rij en over de compenseren kolom. Nou, A staat voor alpha, wat transparantie betekent. De A-waarden hebben vrijwel hetzelfde effect als de R G B-waarden, maar omdat geen van deze voorbeeldafbeeldingen transparant is, is het moeilijk aan te tonen. Met de kolom Offset kunt u eenvoudig de hoeveelheid rood, blauw of groen in de doelpixel verhogen of verlagen: typ -255 in de kolom Offset van de R-rij en u zult zien dat er geen rood meer in de afbeelding staat.
Ik besef dat het lastig is om dit te begrijpen door er alleen maar over te lezen, dus we gaan kijken naar enkele coole voorbeeldeffecten. Dat is trouwens veel leuker. Maar eerst, voor de nieuwsgierigen, hier is de feitelijke wiskundige formule die Flash gebruikt:
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];
(Elk van de waarden die u in de 5x4-matrix ziet, kan variëren tussen -255 en 255.)
Bekijk de voorbeeldafbeelding van de "Kleurenkaart":
Laten we nu aannemen dat u alle rode kleuren uit de afbeelding wilt verwijderen. Stel eenvoudig alle waarden in de rij R in op nul:
Dit betekent:
destR = (0 * srcR) + (0 * srcG) + (0 * srcB) + (0 * srcA) + 0; // wat betekent: destR = 0 + 0 + 0 + 0 + 0; // so: destR = 0;
Laten we nu zeggen dat je wat meer groen wilt toevoegen waar eerder rood was. Zet "1" op ingang 0x1, dus de rij G luidt "1 1 0 0 0":
Laten we nu iets heel vreemds bereiken door de rij G te wijzigen in "0 -1 0 0 50":
Wat is er zojuist gebeurd? Als u bijvoorbeeld bij een willekeurige pixel groen = 30 had, werd dit vermenigvuldigd met '-1' en naderhand 50 toegevoegd, zodat het resultaat zou zijn: (30 * -1) + 50 = 20.
Daarom is een type drempel wordt gemaakt: voor elke pixel met een groenwaarde groter dan 50, wordt de getransformeerde pixel volledig uitgeschakeld. Waarom? Welnu, stel dat het groene kanaal van de pixel een waarde van 51 heeft:
destG = (0 * srcR) + (-1 * srcG) + (0 * srcB) + (0 * srcA) + 50; // onthoud srcG = 51: destG = 0 + (-51) + 0 + 0 + 50; // so: destG = - 51 + 50; // so: destG = -1; // maar een pixel kan geen negatieve hoeveelheid groen hebben, dus dit is gewoon op nul gezet: destG = 0;
Probeer dit nu:
Alle pixels met groene waarden groter dan 50 worden uitgeschakeld en voor degenen met groene waarden onder 50 worden alle drie de kleurkanalen verhoogd. Hiermee kunt u gedeelten van de afbeelding zien met slechts een kleine hoeveelheid groen, zoals bij de afbeelding van de vis:
XHier zijn alleen de pixels met een hoeveelheid groen kleiner dan 50. Hoe donkerder de pixel, hoe meer groen er is in de originele afbeelding. Dat is sowieso het basisprincipe. Ik weet dat het in het begin ingewikkeld lijkt, maar speel ermee en je zult het uiteindelijk wel krijgen :)
OK, laten we iets standaard kiezen: een afbeelding in grijstinten. Verander je matrix zoals zo:
Je hebt een grijswaarde. Leuk :)
Laten we een andere populaire kleurstatus bereiken: omgekeerde kleuren.
Om de kleuren om te keren, moeten we ervoor zorgen dat elke pixel met een rode waarde van 255 een rode waarde van nul heeft en omgekeerd. Hetzelfde voor de andere twee kleuren. Dus we moeten Flash-runcode maken die er zo uitziet:
destR = 255 - srcR; destG = 255 - srcG; destB = 255 - srcB;
Maar dat is makkelijk! Het enige dat we moeten doen is de matrix zo instellen:
Tada! Elektrische vis:
De meeste van de meer exotische effecten die kunnen worden bereikt door de ColorMatrixFilter, worden gedaan door een negatieve waarde in te stellen voor een kleur en een positieve waarde voor offset - of omgekeerd. Zet "-1" van 0x3 tot 2x3 (de alpha's) en 255 voor offset van het alpha (4x3).
Wow, nu weet ik nu hoe ze Terminator 2 hebben gemaakt :)
Eerlijk gezegd weet ik niet precies wat ik net heb gedaan - berekeningen worden na een tijdje echt moeilijk te volgen.
Hoewel het mogelijk is om te begrijpen hoe het ColorMatrixFilter werkt vanuit een wiskundig oogpunt, blijft het realistisch gezien een kwestie van ermee spelen. Je kunt nooit precies weten wat er opduikt als je een aantal specifieke waarden invoert. Daarom heb ik deze effectentester gemaakt. Dus speel rond. Maak jezelf metaalachtig groen, of rood of kleurloos.
Wanneer je een effect hebt dat je bevalt, kun je het op elke gewenste manier in elk DisplayObject (MovieClip, Sprite, Bitmap ...) in je eigen code toepassen:
// importeer eerst ColorMatrixFilter bovenaan uw code: import flash.filters.ColorMatrixFilter; // ... later: var filters: Array = new Array (); // voor alles na "= nieuw", kopieer en plak vanuit het vak "Grab The Code" van 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)); // de volgende twee regels passen het filter toe op uw weergaveobject: filters.push (cmf); myDisplayObject.filters = filters;
Laten we nu kijken naar het convolutiefilter.
Van de klassenreferentie van Adobe:
Een convolutie combineert pixels in het invoerbeeld met aangrenzende pixels om een beeld te produceren. Door convoluties, zoals vervaging, randdetectie, verscherping, embossing en afschuining, kan een breed scala aan afbeeldingseffecten worden bereikt..
Het ConvolutionFilter doorloopt alle pixels van een weergaveobject. Voor elk ervan gebruikt het de middelste waarde in de matrix als de waarde van de huidige pixel die wordt gemanipuleerd. In een matrix van 3 x 3 is de middelste waarde bijvoorbeeld (1, 1). Vervolgens worden de waarden uit de matrix vermenigvuldigd met de omringende pixels en worden de resulterende waarden voor alle pixels opgeteld om de waarde voor de resulterende middelste pixel te krijgen.
Het begrijpen van de exacte wiskunde onder de Convolution-matrix is een heel nieuw artikel waard, dus ik zal dit hier niet behandelen. Als je er mee wilt beginnen, bekijk dan dit bericht op adobe.com.
Een eenvoudig spel rond de waarden geeft u uiteindelijk alle mogelijke effecten die u kunt bereiken. En het zal leuk zijn :) Laten we eens kijken wat we kunnen doen!
Het convolutiefilter maakt gebruik van een matrix, net als het kleurenmatrixfilter. Nogmaals, de waarden variëren tussen -255 en 255. En nogmaals, je bereikt de meeste interessante effecten wanneer je negatieve waarden combineert met positieve waarden.
Laat me je mijn observaties vertellen over hoe dit ding werkt. Probeer een willekeurige waarde uit de matrix te vergroten. Wat je ook kiest, het zal de foto lichter maken; als je wilt dat de afbeelding op de normale helderheid blijft, zorg dan dat de waarde van "deler" gelijk is aan de som van alle waarden in de matrix.
Als je nu probeert een willekeurige waarde onder nul te verlagen terwijl je ten minste één andere boven nul houdt, krijg je daar iets aan de hand. Het beïnvloedt je randen:
Hier is een leuke: wil je op een soldaat lijken? :) Probeer deze waarden:
Verlaag nu de "deler" -waarde naar "-1" om 's nachts soldaat te worden op een missie.
Veel dingen kunnen worden bereikt als je je muisknop een beetje meer vasthoudt :) Lager en verhoog sommige waarden tot het uiterste. Vergeet niet om de "deler" aan te passen - het is cruciaal. Vergroot je matrix. Maak het 5x5, bijvoorbeeld.
Als u het effect in uw eigen code wilt toepassen, gebruikt u de filters object, net als voor de ColorMatrixFilter:
// importeer ConvolutionFilter eerst bovenaan uw code: import flash.filters.ConvolutionFilter; // ... later: var filters: Array = new Array (); // voor alles na "= nieuw", kopieer en plak vanuit het vak "Grab The Code" van EffectsTester: var cf: ConvolutionFilter = new ConvolutionFilter (3,3, new Array (1,0, -10, -2,3 , 1,6,1, -1), 0); // de volgende twee regels passen het filter toe op uw weergaveobject: filters.push (cf); myDisplayObject.filters = filters;
Eindelijk: probeer beide filters te combineren.
// importeer eerst de filterklassen bovenaan uw code: import flash.filters.ColorMatrixFilter; import flash.filters.ConvolutionFilter; // ... later: var filters: Array = new Array (); // voor alles na "= nieuw", kopieer en plak vanuit het vak "Grab The Code" van 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 = nieuwe ConvolutionFilter (3,3, nieuwe Array (1,0, -10, -2,3,1,6,1, -1), 0); // de volgende drie regels passen de filters toe op uw weergaveobject: filters.push (cf); filters.push (cmf); myDisplayObject.filters = filters;
Veel plezier met het spelen van deze filters en plaats de resultaten die je krijgt in de reacties! Bedankt voor het lezen.