Crea filtri personalizzati usando Pixel Bender Toolkit

Due volte al mese, rivisitiamo alcuni dei post preferiti dei nostri lettori da tutta la storia di Activetuts +. Questo tutorial è stato pubblicato per la prima volta nel settembre 2009.

Ciao, ancora una volta, mi chiamo Andr? e in questo tutorial dimostrerò come creare filtri personalizzati con Pixel Bender Toolkit, quindi usarli con Flash CS4 per generare file .pbj.

* Questa funzione funziona solo in Flash Player 10.


Passaggio 1: Pixel Bender Toolkit

Pixel Bender Toolkit viene fornito con il pacchetto Adobe Master Collection CS4 oppure è possibile scaricarlo all'indirizzo http://labs.adobe.com/downloads/pixelbender.html.


Passaggio 2: Nozioni di base

Prima di creare qualsiasi filtro, dobbiamo comprendere le funzioni e i tipi di base della lingua. È diverso da Flash e molto più semplice.

La parola chiave di input: Questo è l'input Immagine, l'immagine che verrà letta e lavorata. Possiamo avere fino a 2 immagini di input nel codice, lavorando con una immagine creeremo un filtro e lavorando con 2 immagini creeremo una modalità di fusione. L'input è sempre di tipo "image4", che è un'immagine in modalità RGBA (rosso, verde, blu e alfa).

La parola chiave di output: Questo è l'output pixel, al contrario dell'input. Questo non produrrà l'immagine, questo produrrà solo il pixel letto in RGBA. Questo è tipo "pixel4" (e non immagine4 come l'input).

La parola chiave parametro: La parola chiave parametro funzionerà come una funzione setter. Con il parametro i valori del filtro possono essere modificati quando in uso. Il parametro deve essere seguito dal tipo e nome e può anche avere valore minimo, valore massimo e valore predefinito. Esempio: parametro int dimensione ; o parametro float myfloat . Anche il parametro può essere digitato float2, float3, float3, int1, int2? esempio: parametro float2 test ;

Inoltre abbiamo i tipi float, float2, float3, float4, int, int2, int3, int4 e molti altri che non useremo qui. Inoltre, alcuni tipi non funzionano con Flash Player 10, quindi non li inserirò in questo momento. Tuttavia, parlerò un po 'dei tipi che ho menzionato qui e di come funzionano.

Digita float, float2, float3 e float4: quando crei un tipo float4, ad esempio, stai creando una matrice di 4 valori float. In Pixelbender i valori float sono definiti da dot, ma float () funziona anche come una funzione per convertire altri valori numerici in float. Per esempio "float4 test = float4 (1,2,3,4);". Qui abbiamo un oggetto con 4 valori (tipo float) nella variabile "test". Puoi anche creare un oggetto float4 da un valore, ad esempio: "float4 test = float4 (3);". Qui abbiamo un oggetto con 4 valori (RGBA) e tutti i valori sono gli stessi (3.0 float). Quando crei un valore float, puoi anche crearlo usando un punto simile "float test = 1.0;". Se provi a definirlo come "float test = 1;" genererà un errore, perché i numeri senza un punto in pixelbender funzionano come valori int.

Quindi float sono sempre definiti da punti. Anche usando "float ()" per creare il valore float restituirà un numero con un punto. Infine, per accedere ai valori float con più di un valore è possibile utilizzare la sintassi come un accesso array "variabile [0] o variabile [1] o variabile [2]?".

Digitare int, int2, int3 e in4 sono la stessa cosa dei tipi float, ma non hanno punti. Puoi anche convertire i valori numerici usando le funzioni "int".

evaluatePixel (): questa funzione viene eseguita su tutta l'immagine, pixel per pixel, quindi restituisce il tipo di output pixel4. Nei filtri personalizzati per Flash usiamo sempre questa funzione.

outCoord (): questa funzione restituisce la coordinata corrente del pixel letto dalla funzione evaluatePixel. Restituisce un valore di tipo float2, valori xey e può essere utilizzato da [] come array o .x e .y come oggetto. Per esempio: var out = outCoord (); //out.x è lo stesso di out [0] e out.y è lo stesso di out [1].

sampleNearest (fonte, pixelCoordinate): questa funzione restituisce il valore float4 del pixel dall'immagine sorgente (immagine4) ai coordinamenti "pixelCoordinate". Normalmente usiamo la funzione "outCoord" qui.

Un'osservazione deve essere fatta; quando si utilizzano valori float e si desidera aggiungere / sottrarre / moltiplicare o dividere i valori con un altro valore float della stessa lunghezza, è possibile utilizzarli come questo esempio:

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

Il risultato sarà un tipo variabile float4 con valori 2,0, 0,0, 0,0 e 2,0. Inoltre, è possibile utilizzare:

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

Penso che sia sufficiente per capire la struttura del codice Pixel Bender, passiamo al prossimo passaggio, dopo aver menzionato solo un'altra cosa:

Prima di testare qualsiasi filtro, è importante caricare almeno un'immagine (file> carica immagine 1 "). Per testare il filtro puoi andare a costruire> esegui, se il filtro ha qualche parametro, sul lato destro dell'applicazione si ' Vediamo i cursori per modificare i valori. Cambiano in fase di esecuzione e hanno un'anteprima dal vivo, dal momento che ogni volta che premi di nuovo la corsa.


Passaggio 3: crea un nuovo filtro Pixel Bender

Questo filtro viene fornito con Pixel Bender Toolkit, ma è uno dei filtri più semplici da spiegare. Per ulteriori informazioni sul riferimento al linguaggio Pixel Bender, basta premere il tasto F1 nel programma e si aprirà la guida in .pdf.

Una volta che il programma è aperto, crea un nuovo filtro del kernel (file> nuovo filtro del kernel) il programma creerà una struttura predefinita per il filtro:

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

Nel kernel NewFilter, cambi il nome NewFilter per il nome del tuo filtro. Namespace, vendor, version and description Non ho bisogno di spiegare, solo le tue stringhe come autore, versione (int) e la descrizione.

L'immagine di input sarà l'immagine caricata dal filtro e l'output sarà il pixel generato dalla funzione evaluatePixel. L'output sarà un valore pixel4 generato dalla funzione evaluatePixel, che esegue pixel per pixel dell'immagine di input come ho spiegato.

Alla linea "dst = sampleNearest (src, outCoord ());"otteniamo il valore del pixel corrente e la coordinata outCoord () dall'immagine src (l'immagine di input), quindi possiamo modificare i valori del valore rgba del dst. Ad esempio, se vogliamo invertire i colori dell'immagine di input, potremmo fare quanto segue:

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

Cosa stiamo facendo qui?

Stiamo affermando che il valore rgb di questo pixel è la matrice di valore float3 meno il valore originale di rgb, quindi il colore sarà invertito. Puoi usare dst.rgb invece di usare dst [0], dst [1]? e l'ordine dopo il punto può essere qualsiasi ordine, leggerà ogni lettera come il valore del colore. Ad esempio, è possibile utilizzare dst.gbr = float3 (1) -dst.gbr. Un'altra cosa che puoi provare è cambiare i colori dell'immagine. Ad esempio utilizzando il codice seguente (all'interno della funzione evaluatePixel):

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

Questo codice genererà un'immagine stranamente colorata.


Passaggio 4: test di un codice preparato da Adobe

Proviamo un filtro da Adobe. Il filtro pixelate è ottimo per i test, quindi vai al file> open; nella cartella in cui è installato Pixel Bender ci sono alcuni filtri. Scegliamo il filtro pixelate. Una volta aperto, puoi premere il pulsante "Esegui" per testare il filtro. Se vuoi esportare, vai al file> Esporta il filtro del kernel per il flash player. Questo esporterà il filtro da utilizzare con Flash, puoi caricare il filtro con URLLoader o incorporare il tag Embed da Flex SDK. In questo tutorial mostrerò come lavorare con il file incorporato, dal momento che il filtro pesa solo da 4kb a 15kb (è molto leggero).

L'estensione di output è un file .pbj.


Passaggio 5: creare la struttura delle cartelle

Se hai un classpath per Flash, usa il tuo classpath, se non ne hai uno e vuoi crearne uno, apri il mio tutorial precedente e segui il Passo 1. Se non vuoi un classpath, usa la stessa cartella del tuo documento .fla . Assumiamo il classpath per il tutorial.

Nel classpath creare la cartella "pixelbender". Quindi all'interno della cartella "pixelbender", all'interno del classpath creare la cartella "pbj". Copia il file .pbj (ad esempio: pixelate.pbj) in questa cartella pbj che hai creato.


Passaggio 6: creazione della classe per il filtro Pixelate

Apri Flash CS4 o Flex con SDK aggiornato per FP10. Se utilizzi Flash, è importante impostare Flex SDK per Flash. Se non sai come fare, premi "ctrl + u" per aprire le preferenze di Flash, quindi seleziona "actionscripts" nella categoria, quindi "Actionsctipt 3.0 settings". Nella finestra "Impostazioni avanzate di Actionscript 3.0" fai clic sul pulsante "+" del percorso della libreria e aggiungi quanto segue: $ (FlexSDK) /frameworks/libs/flex.swc. Fai clic sul pulsante OK.

Ora crea un nuovo file .as e inizia a codificare quanto segue:

Per prima cosa impostiamo il pacchetto e importiamo le classi necessarie.

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

Crea la classe pubblica PixelateFilter estendendo ShaderFilter. ShaderFilter può essere applicato come filtro normale nell'array di filtri di qualsiasi DisplayObject.

 PixelateFilter di classe pubblica estende ShaderFilter 

Incorporare il file pixelate.pbj nella cartella pbj (supponiamo che salveremo gli .as nella cartella pixelate del nostro classpath). Il tag embed è un tag Flex che incorpora i file in un file SWF invece di caricarli. Ci sono molti tipi che puoi incorporare, come .flv, .jpg e altri, e come applicazione mimeType / octet-stream il file sarà incorporato come ByteArray. Il tag embed crea una classe per il file incorporato, qui sto usando una classe chiamata "Filter".

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

Nel costruttore, creiamo un'istanza del nostro file incorporato come ByteArray. ByteArray è il parametro del costruttore Shader, quindi creeremo anche l'istanza dello shader, impostando il filtro su "ByteArray" come parametro del costruttore. Poiché stiamo estendendo lo ShaderFilter, non è necessario creare un'istanza di ShaderFilter. Questa classe è già estesa a ShaderFilter, quindi tutto ciò che dobbiamo fare è impostare il parametro shader della nostra classe ShaderFilter come istanza dello shader.

funzione pubblica PixelateFilter (): void var filter: ByteArray = new Filter () come ByteArray; // Il file incorporato come ByteArray var shader: Shader = new Shader (filtro); // L'istanza di Shader this.shader = shader; // impostazione del parametro shader della nostra classe

Ora creiamo un nuovo parametro per la nostra classe, il parametro "dimensione". Questo parametro influenzerà la "dimensione del parametro int" creata nel pixelbender. La funzione setter modificherà il valore e la funzione getter otterrà solo il valore corrente. I valori dei dati dello shader sono accessibili da "instance.data.value", i valori sono array. Se avessimo un parametro "parametro int2 position;" nel filtro, ad esempio, accediamo rispettivamente a "instance.data.position [0]" e "instance.data.position [1]".

dimensione del set di funzioni pubbliche (valore: Number): void shader.data.dimension.value [0] = value;  public function get dimension (): Number return shader.data.dimension.value [0]; 

Dopo tutto ciò, basta chiudere il pacchetto e la classe.

 

Ora viene creata la classe per questo filtro, salvare il file .as con il nome "PixelateFilter.as" (lo stesso nome della classe) nella cartella pixelbender all'interno del classpath (lo stesso nome del pacchetto e dove si ha anche creato la cartella pbj).


Passaggio 7: test del nuovo filtro

Primo passo, crea un nuovo documento .fla AS3, salvalo ovunque, ad esempio c: / mycustomfilter.

Definire una classe per questo documento .fla. Aprire il pannello delle proprietà del documento .fla dalla finestra> proprietà, nella casella "Classe" digitare "Principale" e creare un nuovo file actionscript.

Copia qualsiasi immagine nella stessa cartella del documento .fla, ad esempio ho usato una delle immagini campione dagli esempi di Pixel Bender; YellowFlowers.png, che può essere trovato con i file di origine.

Se non hai ancora la classe TweenLite, scaricala su http://blog.greensock.com/tweenliteas3/ e decomprimi il contenuto della cartella gs all'interno della cartella gs nel classpath.

Crea un nuovo documento .as.

Includere le classi necessarie per il nostro classpath:

 pacchetto import flash.display.Sprite; import flash.display.Bitmap; import pixelbender.PixelateFilter; // Il nostro filtro personalizzato importa gs.TweenLite; // la migliore classe di Tweening

Crea la classe Main estendendo la classe Sprite:

 public class Main estende Sprite 

Incorpora l'immagine per il test, il mimeType è "image / png", quindi stiamo incorporando come immagine non ByteArray. Dai un nome alla sua classe "Img". Inoltre, digitiamo una variabile denominata "filter" del tipo PixelateFilter, quindi possiamo utilizzarla in qualsiasi funzione in seguito.

[Incorpora (source = "YellowFlowers.png", mimeType = "image / png")] private var Img: Class; filtro var privato: PixelateFilter;

Nel costruttore, iniziamo a creare la nostra immagine, che sarà influenzata dal filtro, quindi aggiungere il bambino dell'immagine allo stage. Quindi crea l'istanza di PixelateFilter. Abbiamo creato la variabile in precedenza, quindi non è necessario digitare nuovamente. Imposta la dimensione del filtro su 100, in modo che possiamo vedere meglio l'effetto, inoltre aggiungi il filtro alla lista di filtri della nostra classe principale.

Quindi, usando la classe TweenLite, animiamo il parametro del filtro. Il parametro dimensione verrà animato da 100 a 1. Mentre l'animazione è in fase di aggiornamento, viene eseguita la funzione "tweenLiteUpdate" e al termine dell'animazione verrà eseguita la funzione "newTween".

funzione pubblica Main (): void var image: Bitmap = new Img () come Bitmap; addChild (immagine); filter = new PixelateFilter (); filter.dimension = 100; this.filters = [filtro]; TweenLite.to (filtro, 3, dimensione: 1, onUpdate: tweenLiteUpdate, onComplete: newTween); 

Mentre TweenLite viene aggiornato, tweenLiteUpdate viene eseguito e aggiorna il filtro della nostra classe Main. Senza questo metodo non vedremmo TweenLite aggiornare il filtro.

funzione privata tweenLiteUpdate (): void this.filters = [filtro]; 

Al termine della prima animazione Tweening, verrà eseguita la nuova funzione Tween. La prima riga di questa funzione controllerà se il valore della dimensione del filtro è 1. Se è così, imposterà la variabile dim su 100, altrimenti imposterà la variabile su 1. Questo è lo stesso con if e else, o switch. La seconda riga avvierà nuovamente l'animazione Tweening del filtro.

funzione privata newTween (): void var dim: Number = (filter.dimension == 1)? 100: 1; TweenLite.to (filtro, 3, dimensione: dim, onUpdate: tweenLiteUpdate, onComplete: newTween); 

Ora basta chiudere il pacchetto e la classe con il doppio "".

 

Salva il tuo file come "Main.as" nella stessa cartella del tuo file .fla, e se tutti i file e le cartelle sono OK, puoi testare il tuo file. L'animazione inizierà a essere pixelata, passerà all'immagine normale e si accosterà continuamente.


Conclusione

Spero che ti sia piaciuto, e spero che sarà molto utile. In Adobe Exchange ci sono molti altri filtri che puoi scaricare, alcuni dei quali sono gratuiti o open source. Ho anche messo qualche altro .pbj e classi con la fonte per studiare. Ad esempio, SpherizeFilter.as: http://cavallari.freehostia.com/spherize/, animato dalla posizione del mouse.