Exemple de filtrage des objets d’affichage : Filter WorkbenchFlash Player 9 et ultérieur, Adobe AIR 1.0 et ultérieur L’exemple Filter Workbench comporte une interface utilisateur qui permet d’appliquer divers filtres à des images et autre contenu visuel et de voir le code résultant, qui peut être utilisé pour générer le même effet en ActionScript. Non seulement cette application fournit un outil permettant d’expérimenter avec les filtres, mais elle illustre également les techniques suivantes :
Pour obtenir les fichiers d’application associés à cet exemple, voir www.adobe.com/go/learn_programmingAS3samples_flash_fr. Les fichiers d’application Filter Workbench résident dans le dossier Samples/FilterWorkbench. L’application se compose des fichiers suivants :
Utilisation des filtres ActionScriptL’application Filter Workbench est conçue pour vous aider à expérimenter avec divers effets de filtre et générer le code ActionScript approprié correspondant. Elle vous permet de sélectionner trois fichiers distincts comportant un contenu visuel, tel que des images bitmap et une animation créée par Flash et d’appliquer huit filtres ActionScript distincts à l’image sélectionnée, soit seuls, soit combinés à d’autres filtres. L’application comprend les filtres suivants :
Lorsqu’un utilisateur a sélectionné une image et un filtre à appliquer à celle-ci, l’application affiche un panneau contenant des contrôles de définition des propriétés du filtre sélectionné. Par exemple, l’image suivante illustre l’application dans laquelle est sélectionné le filtre Biseau : Lorsque l’utilisateur règle les propriétés du filtre, l’aperçu est actualisé en temps réel. L’utilisateur peut également appliquer plusieurs filtres. Pour ce faire, il personnalise un filtre, clique sur le bouton Apply, personnalise un autre filtre, clique sur le bouton Apply, et ainsi de suite. Les panneaux de filtre de l’application proposent diverses fonctions et sont soumis à quelques limites :
Création d’occurrences de filtreL’application Filter Workbench comprend un jeu de classes, une par filtre disponible, qui sont utilisées par les divers panneaux pour créer les filtres. Lorsqu’un utilisateur sélectionne un filtre, le code ActionScript associé au panneau de filtre crée une occurrence de la classe de filtres usine appropriée. (Ces classes portent le nom de classes usine, car elles ont pour objet de créer des occurrences d’autres objets, à l’instar d’une vraie usine qui fabrique des produits). Lorsque l’utilisateur modifie la valeur d’une propriété dans le panneau, le code correspondant appelle la méthode appropriée dans la classe usine. Chaque classe usine comporte des méthodes spécifiques utilisées par le panneau pour créer l’occurrence de filtre appropriée. Par exemple, si l’utilisateur sélectionne le filtre Flou, l’application crée une occurrence de BlurFactory. La classe BlurFactory comporte une méthode modifyFilter() qui gère trois paramètres : blurX, blurY et quality. Conjointement, ces paramètres permettent de créer l’occurrence de BlurFilter requise : 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)); } En revanche, si l’utilisateur sélectionne le filtre Convolution, celui-ci étant beaucoup plus souple, il contrôle un nombre supérieur de propriétés. Dans la classe ConvolutionFactory, le code suivant est appelé lorsque l’utilisateur sélectionne une autre valeur dans le panneau des filtres : 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)); } Notez que dans chaque cas, lorsque les valeurs du filtre sont modifiées, l’objet usine distribue un événement Event.CHANGE pour avertir les écouteurs de la modification. La classe FilterWorkbenchController, qui applique les filtres au contenu filtré, recherche cet événement pour s’assurer qu’elle doit extraire une nouvelle copie du filtre et l’appliquer à nouveau au contenu filtré. La classe FilterWorkbenchController n’a pas besoin de connaître les détails précis de chaque classe usine associé au filtre. Elle doit juste savoir que le filtre a été modifié et être en mesure d’accéder à une copie de ce dernier. A cet effet, l’application comporte une interface, IFilterFactory, qui définit le comportement requis d’une classe usine de filtres pour que l’occurrence de FilterWorkbenchController de l’application soit en mesure de fonctionner correctement. L’interface IFilterFactory définit la méthode getFilter() utilisée par la classe FilterWorkbenchController : function getFilter():BitmapFilter; Notez que la définition de la méthode de l’interface getFilter() stipule de renvoyer une occurrence de BitmapFilter plutôt qu’un type déterminé de filtre. La classe BitmapFilter ne définit pas de type spécifique de filtre. BitmapFilter constitue de fait la classe de base sur laquelle se fondent toutes les classes de filtre. Chaque classe usine de filtres définit une implémentation déterminée de la méthode getFilter(), dans laquelle elle renvoie une référence à l’objet filtre généré. Par exemple, une version abrégée du code source de la classe ConvolutionFactory est illustrée ci-après : public class ConvolutionFactory extends EventDispatcher implements IFilterFactory { // ------- Private vars ------- private var _filter:ConvolutionFilter; ... // ------- IFilterFactory implementation ------- public function getFilter():BitmapFilter { return _filter; } ... } Dans l’implémentation de la classe ConvolutionFactory de la méthode getFilter(), elle renvoie une occurrence de ConvolutionFilter, bien que tout objet qui appelle getFilter() ne sache pas nécessairement que, conformément à la définition de la méthode getFilter() appliquée par ConvolutionFactory, il doit renvoyer toute occurrence de BitmapFilter, soit une occurrence de n’importe quelle classe de filtre ActionScript. Application de filtres aux objets d’affichageComme indiqué précédemment, l’application Filter Workbench utilise une occurrence de la classe FilterWorkbenchController (appelée à partir de maintenant l’« occurrence de contrôleur »), chargée d’appliquer les filtres à l’objet visuel sélectionné. Avant que l’occurrence de contrôleur ne puisse appliquer un filtre, elle doit identifier l’image ou le contenu visuel concerné. Lorsque l’utilisateur sélectionne une image, l’application appelle la méthode setFilterTarget() de la classe FilterWorkbenchController et transmet l’une des constantes définies dans la classe ImageType : public function setFilterTarget(targetType:ImageType):void { ... _loader = new Loader(); ... _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, targetLoadComplete); ... } En se référant à ces informations, l’occurrence de contrôleur charge le fichier indiqué, puis le stocke dans une variable d’occurrence appelée _currentTarget : private var _currentTarget:DisplayObject; private function targetLoadComplete(event:Event):void { ... _currentTarget = _loader.content; ... } Lorsque l’utilisateur sélectionne un filtre, l’application appelle la méthode setFilter() de l’occurrence de contrôleur en indiquant au contrôleur une référence à l’objet Filter Factory approprié, qu’elle stocke dans une variable d’occurrence appelée _filterFactory. private var _filterFactory:IFilterFactory; public function setFilter(factory:IFilterFactory):void { ... _filterFactory = factory; _filterFactory.addEventListener(Event.CHANGE, filterChange); } Notez que, comme indiqué précédemment, l’occurrence de contrôleur ne connaît pas le type de données précis de l’occurrence de Filter Factory assigné. Elle ne sait qu’une chose, c’est que l’objet implémente l’occurrence de IFilterFactory, ce qui signifie qu’il possède une méthode getFilter() et distribue un événement change (Event.CHANGE) lorsque le filtre est modifié. Lorsque l’utilisateur modifie les propriétés d’un filtre dans le panneau des filtres, l’occurrence de contrôleur est avertie de la modification par l’événement change de Filter Factory, qui appelle la méthode filterChange() de l’occurrence de contrôleur. Cette méthode appelle alors la méthode 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’application du filtre à l’objet d’affichage se produit au sein de la méthode applyTemporaryFilter(). Le contrôleur extrait d’abord une référence à l’objet filtre en appelant la méthode getFilter() de Filter Factory. var currentFilter:BitmapFilter = _filterFactory.getFilter(); L’occurrence de contrôleur possède une variable d’occurrence de Array appelée _currentFilters, dans laquelle elle stocke tous les filtres appliqués à l’objet d’affichage. L’étape suivante consiste à ajouter le filtre mis à jour à ce tableau : _currentFilters.push(currentFilter); Le code assigne ensuite le tableau de filtres à la propriété filters de l’objet d’affichage, qui applique à proprement parler les filtres à l’image : _currentTarget.filters = _currentFilters; Enfin, puisque le filtre appliqué en dernier demeure le filtre de « travail », il ne doit pas être appliqué à titre définitif à l’objet d’affichage. Il est donc supprimé du tableau _currentFilters : _currentFilters.pop(); Supprimer ce filtre du tableau n’affecte pas l’objet d’affichage filtré, car un objet d’affichage effectue une copie du tableau de filtres lorsqu’il est assigné à la propriété filters et utilise ce tableau interne au lieu du tableau initial. De ce fait, toute modification du tableau de filtres n’affecte pas l’objet d’affichage tant que le tableau n’a pas été à nouveau assigné à la propriété filters de l’objet d’affichage. |
|