Esempio di filtraggio degli oggetti di visualizzazione: Pannello dei filtriFlash Player 9 e versioni successive, Adobe AIR 1.0 e versioni successive Il pannello dei filtri è un'interfaccia utente che ha lo scopo di applicare diversi filtri a immagini e altri contenuti visivi e di vedere il codice risultante da utilizzare per generare lo stesso effetto in ActionScript. Oltre a fornire uno strumento per la sperimentazione con i filtri, questa applicazione mostra le seguenti tecniche:
Per ottenere i file dell'applicazione per questo esempio, visitate la pagina www.adobe.com/go/learn_programmingAS3samples_flash_it. I file di applicazione del pannello dei filtri si trovano nella cartella Samples/FilterWorkbench. L'applicazione è composta dai seguenti file:
Esperimenti con i filtri ActionScriptL'applicazione Pannello dei filtri è progettata per dare la possibilità di sperimentare vari effetti di filtro e generare il relativo codice ActionScript. L'applicazione permette di selezionare tre diversi file con contenuto visivo, comprese immagini bitmap e animazioni create da Flash, e di applicare otto diversi filtri ActionScript alle immagini selezionate sia singolarmente che combinati tra loro. L'applicazione comprende i seguenti filtri:
Dopo che l'utente ha selezionato un'immagine e un filtro da applicare, l'applicazione visualizza un pannello per l'impostazione delle proprietà specifiche del filtro selezionato. L'immagine seguente, ad esempio, mostra l'applicazione con il filtro Smussatura selezionato: L'immagine di anteprima si aggiorna in tempo reale man mano che l'utente modifica le proprietà del filtro. L'utente ha anche la possibilità di applicare diversi filtri personalizzandone uno, facendo clic sul pulsante Applica, poi personalizzandone un'altro, facendo nuovamente clic su Applica, e così via. Nei pannelli di filtro dell'applicazione sono presenti alcune caratteristiche e limitazioni:
Creazione di istanze di filtroL'applicazione Pannello dei filtri comprende un gruppo di classi: una per ognuno dei filtri disponibili; queste classi vengono utilizzate dai singoli pannelli per creare i filtri. Quando un utente seleziona un filtro, il codice ActionScript associato al pannello del filtro crea un'istanza corrispondente alla classe filter factory appropriata (queste classi vengono dette classi factory perché il loro scopo è quello di creare istanze di altri oggetti, proprio come una fabbrica crea singoli prodotti). Ogni qualvolta l'utente cambia un valore di proprietà nel pannello, il codice del pannello chiama il metodo appropriato nella classe factory. Ogni classe factory comprende metodi specifici che il pannello utilizza per creare l'istanza appropriata per il filtro. Se, ad esempio, l'utente seleziona il filtro Sfocatura, l'applicazione crea l'istanza BlurFactory. La classe BlurFactory include un metodo modifyFilter() che accetta tre parametri: blurX, blurY e quality, che vengono utilizzati insieme per creare l'istanza BlurFilter desiderata: private var _filter:BlurFilter;
public function modifyFilter(blurX:Number = 4, blurY:Number = 4, quality:int = 1):void
{
_filter = new BlurFilter(blurX, blurY, quality);
dispatchEvent(new Event(Event.CHANGE));
}
Se invece l'utente seleziona il filtro Convoluzione, poiché questo filtro è molto più flessibile le proprietà da controllare sono molte di più. Nella classe relativa a questo filtro chiamata ConvolutionFactory, quando l'utente seleziona un diverso valore sul pannello del filtro viene chiamato il seguente codice: private var _filter:ConvolutionFilter;
public function modifyFilter(matrixX:Number = 0,
matrixY:Number = 0,
matrix:Array = null,
divisor:Number = 1.0,
bias:Number = 0.0,
preserveAlpha:Boolean = true,
clamp:Boolean = true,
color:uint = 0,
alpha:Number = 0.0):void
{
_filter = new ConvolutionFilter(matrixX, matrixY, matrix, divisor, bias, preserveAlpha, clamp, color, alpha);
dispatchEvent(new Event(Event.CHANGE));
}
Notate che ogni volta che i valori del filtro vengono cambiati, l'oggetto factory invia un evento Event.CHANGE per notificare ai listener che i valori del filtro sono cambiati. La classe FilterWorkbenchController, il cui compito è quello di applicare i filtri ai contenuti filtrati, “ascolta” tali eventi per verificare quando è necessario recuperare una nuova copia del filtro e applicarlo nuovamente al contenuto filtrato. La classe FilterWorkbenchController non ha bisogno di conoscere i dettagli specifici di ogni classe filter factory: deve solo ricevere notifica del cambiamento dei parametri del filtro ed essere in grado di accedere a una copia del filtro. Per fare questo, l'applicazione include un'interfaccia, IFilterFactory, che definisce il comportamento che una classe filter factory deve assumere in modo che l'istanza dell'applicazione FilterWorkbenchController possa svolgere questo compito. IFilterFactory definisce il metodo getFilter() che viene usato nella classe FilterWorkbenchController: function getFilter():BitmapFilter; Notate che la definizione del metodo di interfaccia getFilter() restituisce un'istanza BitmapFilter e non uno specifico tipo di filtro. La classe BitmapFilter non definisce uno specifico tipo di filtro. BitmapFilter è, piuttosto, una classe base sulla quale tutte le classi dei filtri sono costruite. Ogni classe filter factory definisce una specifica implementazione del metodo getFilter() in cui restituisce un riferimento all'oggetto filtro che ha costruito. Di seguito viene riportata, a scopo di esempio, una versione abbreviata del codice sorgente della classe ConvolutionFactory: public class ConvolutionFactory extends EventDispatcher implements IFilterFactory
{
// ------- Private vars -------
private var _filter:ConvolutionFilter;
...
// ------- IFilterFactory implementation -------
public function getFilter():BitmapFilter
{
return _filter;
}
...
}
Nell'implementazione della classe ConvolutionFactory del metodo getFilter(), viene restituita un'istanza ConvolutionFilter, sebbene gli oggetti che chiamano getFilter() non ne siano necessariamente a conoscenza: secondo la definizione del metodo getFilter() seguito da ConvolutionFactory, esso deve restituire qualsiasi istanza BitmapFilter, la quale a sua volta può essere un'istanza di qualsiasi classe del filtro ActionScript. Applicazione dei filtri agli oggetti di visualizzazioneCome illustrato in precedenza, l'applicazione Pannello dei filtri utilizza un'istanza della classe FilterWorkbenchController (da qui in avanti indicata come “istanza di controllo”), che ha il vero e proprio compito di applicare i filtri agli oggetti visivi selezionati. Affinché l'istanza di controllo possa applicare un filtro, deve sapere a quale immagine o contenuto visivo il filtro deve essere applicato. Quando l'utente seleziona un'immagine, l'applicazione chiama il metodo setFilterTarget() nella classe FilterWorkbenchController, passando una delle costanti definite nella classe ImageType: public function setFilterTarget(targetType:ImageType):void
{
...
_loader = new Loader();
...
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, targetLoadComplete);
...
}
Utilizzando questa informazione, l'istanza di controllo carica il file selezionato memorizzandolo in una variabile di istanza chiamata _currentTarget al momento del caricamento: private var _currentTarget:DisplayObject;
private function targetLoadComplete(event:Event):void
{
...
_currentTarget = _loader.content;
...
}
Quando l'utente seleziona un filtro, l'applicazione chiama il metodo dell'istanza di controllo setFilter() assegnando all'istanza di controllo un riferimento all'oggetto filter factory corrispondente, il quale memorizza una variabile di istanza denominata _filterFactory. private var _filterFactory:IFilterFactory;
public function setFilter(factory:IFilterFactory):void
{
...
_filterFactory = factory;
_filterFactory.addEventListener(Event.CHANGE, filterChange);
}
Notate che, come descritto in precedenza, l'istanza di controllo non conosce il tipo di dati specifici dell'istanza filter factory assegnata; sa solamente che l'oggetto implementa l'istanza IFilterFactory e questo vuol dire che dispone di un metodo getFilter() e che invia un evento change(Event.CHANGE) quando il filtro viene modificato. Quando l'utente modifica le proprietà di un filtro nel pannello, l'istanza di controllo rileva che il filtro è stato modificato tramite l'evento change della filter factory, che chiama il metodo filterChange() dell'istanza di controllo. Questo metodo, a sua volta, chiama il metodo applyTemporaryFilter(): private function filterChange(event:Event):void
{
applyTemporaryFilter();
}
private function applyTemporaryFilter():void
{
var currentFilter:BitmapFilter = _filterFactory.getFilter();
// Add the current filter to the set temporarily
_currentFilters.push(currentFilter);
// Refresh the filter set of the filter target
_currentTarget.filters = _currentFilters;
// Remove the current filter from the set
// (This doesn't remove it from the filter target, since
// the target uses a copy of the filters array internally.)
_currentFilters.pop();
}
L'applicazione del filtro all'oggetto di visualizzazione avviene all'interno del metodo applyTemporaryFilter(). Per prima cosa l'istanza di controllo recupera un riferimento all'oggetto filtro chiamando il metodo getFilter() della filter factory. var currentFilter:BitmapFilter = _filterFactory.getFilter(); L'istanza di controllo dispone di una variabile di istanza Array denominata _currentFilters, nella quale memorizza tutti i filtri che sono stati applicati all'oggetto di visualizzazione. Il passaggio successivo consiste nell'aggiungere il filtro appena aggiornato all'array: _currentFilters.push(currentFilter); Successivamente il codice assegna l'array dei filtri alla proprietà filters dell'oggetto di visualizzazione, che applica effettivamente il filtro all'immagine: _currentTarget.filters = _currentFilters; Alla fine, poiché l'ultimo filtro aggiunto non deve essere applicato in via definitiva all'oggetto di visualizzazione in quanto ancora “attivo”, viene rimosso dall'array _currentFilters: _currentFilters.pop(); La rimozione di questo filtro dall'array non influisce sull'oggetto di visualizzazione filtrato, perché gli oggetti di visualizzazione creano una copia dell'array dei filtri quando vengono assegnati alla proprietà filters e usano questo array interno invece dell'originale. Per questo motivo tutte le modifiche apportate all'array dei filtri non influiscono sull'oggetto di visualizzazione fino a quando l'array non viene assegnato nuovamente alla proprietà filters dell'oggetto di visualizzazione. |
|