Maak aangepaste filters met de Pixel Bender Toolkit

Twee keer per maand bekijken we enkele van onze favoriete lezers uit de geschiedenis van Activetuts +. Deze tutorial is voor het eerst gepubliceerd in september 2009.

Hallo, nogmaals, mijn naam is Andr? en in deze tutorial zal ik laten zien hoe je aangepaste filters kunt maken met de Pixel Bender Toolkit, en deze vervolgens kunt gebruiken met Flash CS4 om .pbj-bestanden uit te voeren.

* Deze functie werkt alleen in Flash Player 10.


Stap 1: de Pixel Bender Toolkit

De Pixel Bender Toolkit wordt geleverd met het Adobe Master Collection CS4-pakket of u kunt het downloaden op http://labs.adobe.com/downloads/pixelbender.html.


Stap 2: De basis

Voordat we een filter maken, moeten we de basisfuncties en -typen van de taal begrijpen. Het is anders dan Flash en veel eenvoudiger.

Het invoerzoekwoord: Dit is de invoer beeld, de afbeelding die wordt gelezen en bewerkt. We kunnen maximaal 2 invoerafbeeldingen in de code hebben, als u met één afbeelding werkt, wordt een filter gemaakt en als u met twee afbeeldingen werkt, wordt een overvloeimodus gemaakt. De invoer is altijd het type "image4", een afbeelding in RGBA-modus (rood, groen, blauw en alfa).

Het uitgangssleutelwoord: Dit is de uitvoer pixel, in tegenstelling tot de invoer. Dit zal de afbeelding niet uitvoeren, dit zal alleen de pixel afgeven die in RGBA is gelezen. Dit is type "pixel4" (en niet image4 zoals de invoer).

Het parameterzoekwoord: Parameter keyword werkt als een setter-functie. Met de parameter kunnen de waarden van het filter worden gewijzigd tijdens gebruik. De parameter moet worden gevolgd door het type en de naam en kan ook een minimumwaarde, maximale waarde en standaardwaarde hebben. Voorbeeld: parameter int dimensie ; of parameter float myfloat . Ook kan de parameter worden getypt float2, float3, float3, int1, int2? voorbeeld: parameter float2-test ;

We hebben ook de typen float, float2, float3, float4, int, int2, int3, int4 en vele andere die we hier niet zullen gebruiken. Sommige typen werken ook niet met Flash Player 10, dus daar kom ik nu niet op in. Ik zal echter een beetje praten over de typen die ik hier heb genoemd en hoe ze werken.

Type float, float2, float3 en float4: wanneer u bijvoorbeeld een float4-type maakt, maakt u een array van 4 float-waarden. In Pixelbender zijn de zwevende waarden per punt gedefinieerd, maar zweven () werkt ook als een functie om andere getalswaarden in zwevend te converteren. Bijvoorbeeld "float4-test = float4 (1,2,3,4);". Hier hebben we een object met 4 waarden (type float) in de variabele "test". U kunt ook een float4-object maken van één waarde, bijvoorbeeld: "float4-test = float4 (3);". Hier hebben we een object met 4 waarden (RGBA) en alle waarden zijn hetzelfde (3.0 float). Wanneer u een zwevende waarde maakt, kunt u deze ook maken met een punt zoals "zweeftest = 1,0;". Als je het zo wilt definiëren "zweeftest = 1;" het zal een fout veroorzaken, omdat getallen zonder een punt in pixelbender werken als int-waarden.

Dus zweven worden altijd gedefinieerd door een punt. Zelfs als u "zweven ()" gebruikt om de zweefwaarde te maken, wordt een getal met een punt geretourneerd. Als laatste, om toegang te krijgen tot zwevende waarden met meer dan één waarde, kunt u syntaxis gebruiken zoals een array-toegang "variabel [0] of variabel [1] of variabel [2]?".

Type int, int2, int3 en in4 zijn hetzelfde als floattypen, maar hebben geen puntjes. U kunt ook getalswaarden converteren met behulp van "int" -achtige functies.

evaluatePixel (): deze functie loopt pixel voor pixel over het hele beeld en retourneert dan het uitvoertype pixel4. In aangepaste filters voor Flash gebruiken we altijd deze functie.

outCoord (): deze functie retourneert de huidige coördinaat van de pixel die wordt gelezen door de functie evaluPixel. Het retourneert een float2-, x- en y-waarden van het waardetype en kan worden benaderd door [] zoals array of .x en .y like object. Bijvoorbeeld: var out = outCoord (); //out.x is hetzelfde van out [0] en out.y is hetzelfde van out [1].

sampleNearest (bron, pixelCoordinate): deze functie retourneert de float4-waarde van de pixel uit de bronafbeelding (image4) op de coördinaten "pixelCoordinate". Normaal gesproken gebruiken we de "outCoord" -functie hier.

Er moet een waarneming worden gemaakt; wanneer u zwevende waarden gebruikt en u waarden wilt optellen / aftrekken / vermenigvuldigen of verdelen met een andere zwevende waarde van dezelfde lengte, kunt u ze gebruiken zoals in dit voorbeeld:

 float4 test1 = float4 (3.0,2.0,2.0,3.0); float4 test2 = float4 (1.0, 2.0, 2.0, 10.1); float4-resultaat = test1-test2;

Het resultaat is een variabele type float4 met waarden van 2,0, 0,0, 0,0 en 2,0. Je zou ook kunnen gebruiken:

 float4 test1 = float4 (3.0,2.0,2.0,3.0); float4 test2 = float4 (1.0, 2.0, 2.0, 10.1); float4 resultaat = test1; resultaat [0] = test1 [0] -test2 [0]; resultaat [2] - = 0,5;

Ik denk dat dit voldoende is om de structuur van de Pixel Bender-code te begrijpen, laten we doorgaan naar de volgende stap, nadat ik nog maar één ding heb genoemd:

Voordat u een filter test, is het belangrijk om minstens één afbeelding te laden (bestand> afbeelding 1 laden.) Als u het filter wilt testen, gaat u naar> uitvoeren, als het filter over parameters beschikt, aan de rechterkant van de toepassing die u gebruikt. Ik zal schuifregelaars zien om de waarden te veranderen. Ze veranderen tijdens runtime en hebben een live preview, omdat elke keer dat je op run drukt opnieuw wordt weergegeven.


Stap 3: Maak een nieuw Pixel Bender-filter

Dit filter wordt geleverd met Pixel Bender Toolkit, maar is een van de eenvoudigere filters om uit te leggen. Voor meer informatie over de Pixel Bender-taalreferentie drukt u gewoon op de F1-knop in het programma en wordt de Help in .pdf geopend.

Als het programma eenmaal is geopend, maakt u een nieuw kernelfilter (bestand> nieuw kernelfilter) en maakt het programma een standaardstructuur voor het filter:

  kernel NewFilter < namespace : "Your Namespace"; vendor : "Your Vendor"; version : 1; description : "your description"; > input image4 src; uitvoer pixel4 dst; void evaluationPixel () dst = sampleNearest (src, outCoord ()); 

In kernel NewFilter, verander je de naam NewFilter voor de naam van je filter. Naamruimte, leverancier, versie en beschrijving Ik hoef het niet uit te leggen, alleen je strings als auteur, versie (int) en de beschrijving.

Het invoerbeeld is de afbeelding die door het filter wordt geladen en de uitvoer is de pixel die door de evaluPixelfunctie wordt gegenereerd. De uitvoer is een pixel4-waarde die wordt gegenereerd door de evaluPixel-functie, die pixel voor pixel van het invoerbeeld wordt uitgevoerd zoals ik heb uitgelegd.

Aan de lijn "dst = sampleNearest (src, outCoord ());"we krijgen de waarde van de huidige pixel en de coördinaat outCoord () van image src (de invoerafbeelding), dus we kunnen de waarden van de rgba-waarde van de dst wijzigen, bijvoorbeeld als we de kleuren willen omkeren van het invoerbeeld, kunnen we het volgende doen:

 dst = sampleNearest (src, outCoord ()); dst.rgb = float3 (1) -dst.rgb;

Wat doen we hier?

We verklaren dat de rgb-waarde van deze pixel de array van float3-waarde minus de oorspronkelijke waarde van rgb is, dus de kleur zal worden omgekeerd. U kunt de dst.rgb gebruiken in plaats van dst [0], dst [1]? en de volgorde na de punt kan elke willekeurige volgorde zijn, het zal elke letter lezen als de waarde van de kleur. U kunt bijvoorbeeld dst.gbr = float3 (1) -st.gbr gebruiken. Een ander ding dat u kunt proberen, is om de kleuren van de afbeelding te veranderen. Bijvoorbeeld door de onderstaande code te gebruiken (binnen de evaluPixelfunctie):

 dst = sampleNearest (src, outCoord ()); dst.rgb = dst.brg;

Deze code levert een vreemd gekleurd beeld op.


Stap 4: Een voorbereide code testen bij Adobe

Laten we een filter testen bij Adobe. Het pixelatfilter is geweldig om te testen, dus ga naar bestand> open; in de map waarin Pixel Bender is geïnstalleerd, zijn enkele filters aanwezig. Laten we het pixelfilter kiezen. Als het eenmaal is geopend, kunt u op de knop "uitvoeren" klikken om het filter te testen. Als u wilt exporteren, gaat u naar bestand> Kernelfilter exporteren voor Flash Player. Hiermee wordt het filter geëxporteerd om te gebruiken met Flash. U kunt het filter laden met de URLLoader of insluiten met de inslagringtag van Flex SDK. In deze zelfstudie laat ik zien hoe je met het ingesloten bestand kunt werken, omdat het filter slechts ongeveer 4 kb tot 15 kb weegt (het is erg licht).

De uitvoerextensie is een .pbj-bestand.


Stap 5: Creëer de mappenstructuur

Als je een klassenpad hebt voor Flash, gebruik dan je klassenpad, als je er geen hebt en er een wilt maken, open dan mijn vorige zelfstudie en volg stap 1. Als je geen klassenpad wilt, gebruik dan dezelfde map van je .fla-document . Laten we het klassenpad voor de zelfstudie aannemen.

Maak in je klassepad de map "pixelbender". Vervolgens maakt u in de map "pixelbender" binnen uw klassepad de map "pbj" aan. Kopieer het .pbj-bestand (bijvoorbeeld: pixelate.pbj) naar deze pbj-map die u hebt gemaakt.


Stap 6: De klasse voor het pixelfilter maken

Open Flash CS4 of Flex met bijgewerkte SDK voor FP10. Als u Flash gebruikt, is het belangrijk om de Flex SDK in te stellen voor Flash. Als u niet weet hoe u dit moet doen, drukt u op "ctrl + u" om de voorkeuren van Flash te openen, selecteert u vervolgens de "actionscripts" bij categorie en vervolgens "Actionsctipt 3.0-instellingen". In het venster "geavanceerde instellingen van Actionscript 3.0" klikt u op de knop "+" van het bibliotheekpad en voegt u het volgende toe: $ (FlexSDK) /frameworks/libs/flex.swc. Klik op de knop OK.

Maak nu een nieuw .as-bestand en begin met het coderen van het volgende:

Eerst stellen we het pakket in en importeren we de nodige klassen.

 pakket pixelbender import flash.display.Shader; import flash.filters.ShaderFilter; import flash.utils.ByteArray;

Maak de public class PixelateFilter met uitbreiding van de ShaderFilter. De ShaderFilter kan worden toegepast als een normaal filter in de filterarray van elk DisplayObject.

 public class PixelateFilter breidt ShaderFilter uit 

Sluit het pixelate.pbj-bestand in de map pbj in (we nemen aan dat we de .as opslaan in de pixelmap van ons klassenpad). De embed-tag is een Flex-tag die bestanden in een swf invoegt in plaats van ze te laden. Er zijn veel typen die u kunt insluiten, zoals .flv, .jpg en anderen, en als mimeType-toepassing / octet-stream wordt het bestand ingesloten als ByteArray. De embed-tag maakt een klasse voor het ingesloten bestand, hier gebruik ik een klasse met de naam "Filter".

 [Embed (source = "pbj / pixelate.pbj", mimeType = "application / octet-stream")] private var Filter: Class;

Laten we in de constructor een exemplaar van ons ingesloten bestand maken als ByteArray. De ByteArray is de parameter van de Shader-constructor, dus we zullen ook de shader-instantie maken en het filter instellen op "ByteArray" als de parameter van de constructor. Omdat we de ShaderFilter uitbreiden, hoeven we geen instantie van ShaderFilter te maken. Deze klasse is al ShaderFilter uitgebreid, dus alles wat we moeten doen is de shader-parameter van onze ShaderFilter-klasse instellen als de shader-instantie.

public function PixelateFilter (): void var filter: ByteArray = new Filter () als ByteArray; // Het ingesloten bestand als ByteArray var shader: Shader = new Shader (filter); // Het exemplaar van Shader this.shader = shader; // de parameter shader van onze klasse instellen

Nu maken we een nieuwe parameter voor onze klasse, de parameter "dimensie". Deze parameter is van invloed op de "parameter int-dimensie" die in de pixelbender is gemaakt. De functie setter zal de waarde veranderen en de getterfunctie krijgt gewoon de huidige waarde. De arceringsgegevenswaarden zijn toegankelijk via "instance.data.value", de waarden zijn arrays. Als we een parameter hadden "parameter int2 positie;" in het filter zouden we bijvoorbeeld toegang krijgen door respectievelijk "instance.data.position [0]" en "instance.data.position [1]".

openbare functieset dimensie (waarde: getal): void shader.data.dimension.value [0] = waarde;  public function get dimensions (): Number return shader.data.dimension.value [0]; 

Sluit tenslotte het pakket en de klas.

 

Nu wordt de klasse voor dit filter gemaakt, sla het .as-bestand met de naam "PixelateFilter.as" (dezelfde naam als de klasse) op in de map pixelbender in uw klassenpad (dezelfde naam als uw pakket, en waar u ook hebt heeft de pbj-map gemaakt).


Stap 7: Test het nieuwe filter

Eerste stap, maak een nieuw .fla AS3-document, bewaar het waar u maar wilt, bijvoorbeeld c: / mycustomfilter.

Definieer een klasse voor dit .fla-document. Open het eigenschappenvenster van het .fla-document vanuit het venster> eigenschappen, in het vak "Klasse" type "Hoofd" en maak een nieuw actionscript-bestand aan.

Kopieer elke afbeelding naar dezelfde map van het .fla-document, bijvoorbeeld ik heb een van de voorbeeldafbeeldingen uit de Pixel Bender-voorbeelden gebruikt; YellowFlowers.png, die te vinden is met de bronbestanden.

Als je de TweenLite-klasse nog niet hebt, download deze dan op http://blog.greensock.com/tweenliteas3/ en pak de inhoud van de map gs uit in de map gs in je klassenpad.

Maak een nieuw .as document.

Voeg de nodige klassen toe aan ons klassenpad:

 pakket import flash.display.Sprite; import flash.display.Bitmap; pixelbender.PixelateFilter importeren; // Onze aangepaste filter importeert gs.TweenLite; // de beste Tweening-les

Maak de Hoofdklasse die de Sprite-klasse uitbreidt:

 public class Main breidt uit

Sluit de afbeelding in voor testen, het mimeType is "image / png", dus we zijn inbedding als afbeelding en niet als ByteArray. Noem zijn klasse "Img". Daarnaast typen we een variabele met de naam "filter" van het type PixelateFilter, zodat we deze later in elke functie kunnen gebruiken.

[Embed (source = "YellowFlowers.png", mimeType = "image / png")] private var Img: Class; privé-var-filter: PixelateFilter;

In de constructor beginnen we met het maken van onze afbeelding, die wordt beïnvloed door het filter en vervolgens het afbeeldingkind toevoegt aan het werkgebied. Maak vervolgens een exemplaar van PixelateFilter. We hebben de variabele eerder gemaakt, dus we hoeven niet opnieuw te typen. Stel de filterdimensie in op 100, zodat we het effect beter kunnen zien, voeg ook het filter toe aan de filterlijst van onze hoofdklasse.

Vervolgens gebruiken we de TweenLite-klasse om de filterparameter te animeren. De dimensieparameter wordt geanimeerd van 100 tot 1. Terwijl de animatie wordt bijgewerkt, wordt de functie "tweenLiteUpdate" uitgevoerd en wanneer deze klaar is met animeren, wordt de "newTween" -functie uitgevoerd.

public function Main (): void var image: Bitmap = new Img () als Bitmap; addChild (afbeelding); filter = nieuw PixelateFilter (); filter.dimension = 100; this.filters = [filter]; TweenLite.to (filter, 3, afmeting: 1, onUpdate: tweenLiteUpdate, onComplete: newTween); 

Terwijl TweenLite wordt bijgewerkt, wordt de tweenLiteUpdate uitgevoerd en wordt het filter van onze hoofdklasse bijgewerkt. Zonder deze methode zouden we de TweenLite het filter niet updaten.

private function tweenLiteUpdate (): void this.filters = [filter]; 

Wanneer de eerste Tweening-animatie is voltooid, wordt de nieuwe Tween-functie uitgevoerd. De eerste regel van deze functie controleert of de filterdimensiewaarde 1 is. Als dat zo is, wordt de dimvariabele ingesteld op 100, anders stelt hij de variabele in op 1. Dit is hetzelfde met if en else of switch. De tweede regel start de Tweening-animatie van het filter opnieuw.

private function newTween (): void var dim: Number = (filter.dimension == 1)? 100: 1; TweenLite.to (filter, 3, afmeting: dim, onUpdate: tweenLiteUpdate, onComplete: newTween); 

Sluit nu het pakket en de klas met dubbele "".

 

Sla uw bestand op als "Main.as" in dezelfde map van uw .fla-bestand en als alle bestanden en mappen in orde zijn, kunt u uw bestand testen. De animatie begint te pixeleren, verandert naar het normale beeld en zal continu doorlopen.


Conclusie

Ik hoop dat je dit leuk vond en ik hoop dat het erg nuttig zal zijn. In Adobe Exchange zijn er veel andere filters die u kunt downloaden, sommige zijn gratis of open source. Ik heb ook een aantal andere .pbj en klassen met de bron voor het bestuderen. SpherizeFilter.as: http://cavallari.freehostia.com/spherize/, animeert door de positie van de muis.