Filtre Mappage de déplacementFlash Player 9 et ultérieur, Adobe AIR 1.0 et ultérieur La classe DisplacementMapFilter utilise des valeurs de pixel extraites d’un objet BitmapData (appelé image de mappage du déplacement) pour appliquer un effet de déplacement à un nouvel objet. L’image de mappage du déplacement est en général différente de l’occurrence d’objet d’affichage ou BitmapData à laquelle le filtre est appliqué. L’effet de déplacement nécessite de déplacer les pixels de l’image filtrée, autrement dit de les décaler d’un certain niveau. Ce filtre permet de créer un effet de décalage, de gondole ou de marbrure. La direction et la valeur du déplacement appliqué à un pixel donné sont déterminées par la valeur colorimétrique de l’image de mappage du déplacement. Pour utiliser ce filtre, il est nécessaire de spécifier l’image de mappage, ainsi que les valeurs suivantes, qui permettent de contrôler le calcul du déplacement :
Pour comprendre le fonctionnement d’un filtre de mappage de déplacement, prenons un exemple simple. Dans le code ci-dessous, une image est chargée, puis elle est centrée sur la scène et un filtre Mappage de déplacement lui est appliqué, ce qui déplace horizontalement (vers la gauche) les pixels de toute l’image. import flash.display.BitmapData; import flash.display.Loader; import flash.events.MouseEvent; import flash.filters.DisplacementMapFilter; import flash.geom.Point; import flash.net.URLRequest; // Load an image onto the Stage. var loader:Loader = new Loader(); var url:URLRequest = new URLRequest("http://www.helpexamples.com/flash/images/image3.jpg"); loader.load(url); this.addChild(loader); var mapImage:BitmapData; var displacementMap:DisplacementMapFilter; // This function is called when the image finishes loading. function setupStage(event:Event):void { // Center the loaded image on the Stage. loader.x = (stage.stageWidth - loader.width) / 2; loader.y = (stage.stageHeight - loader.height) / 2; // Create the displacement map image. mapImage = new BitmapData(loader.width, loader.height, false, 0xFF0000); // Create the displacement filter. displacementMap = new DisplacementMapFilter(); displacementMap.mapBitmap = mapImage; displacementMap.mapPoint = new Point(0, 0); displacementMap.componentX = BitmapDataChannel.RED; displacementMap.scaleX = 250; loader.filters = [displacementMap]; } loader.contentLoaderInfo.addEventListener(Event.COMPLETE, setupStage); Les propriétés utilisées pour définir le déplacement sont les suivantes :
Ces valeurs provoquent un déplacement des pixels de l’image filtrée de 250 pixels à gauche. La direction (gauche ou droite) et l’importance du déplacement dépendent de la valeur colorimétrique des pixels de l’image de mappage. Le principe de fonctionnement de ce filtre est le suivant : il analyse un par un les pixels de l’image filtrée (ou tout au moins ceux de la zone à laquelle le filtre est appliqué, ce qui ici signifie toute l’image), et procède comme suit pour chaque pixel :
Comme nous ne spécifions aucune valeur pour les composants x et y, les valeurs par défaut (qui ne provoquent pas de déplacement) sont utilisées. C’est pourquoi l’image n’est pas déplacée dans le sens vertical. Dans cet exemple, le paramètre par défaut de mode de filtrage, WRAP, est utilisé, si bien que lorsque les pixels sont déplacés vers la gauche, l’espace laissé vide à droite est rempli par les pixels qui ont été décalés le long du côté gauche de l’image. Vous pouvez modifier cette valeur pour voir les différents effets ainsi obtenus. Par exemple, si vous ajoutez la ligne suivante dans la partie du code qui définit les propriétés de déplacement (avant la ligne loader.filters = [displacementMap]), l’image semble avoir subi un balayage : displacementMap.mode = DisplacementMapFilterMode.CLAMP; Le code ci-dessous propose un exemple plus complexe, en utilisant un filtre Mappage de déplacement pour créer un effet de loupe dans l’image : import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.BitmapDataChannel; import flash.display.GradientType; import flash.display.Loader; import flash.display.Shape; import flash.events.MouseEvent; import flash.filters.DisplacementMapFilter; import flash.filters.DisplacementMapFilterMode; import flash.geom.Matrix; import flash.geom.Point; import flash.net.URLRequest; // Create the gradient circles that will together form the // displacement map image var radius:uint = 50; var type:String = GradientType.LINEAR; var redColors:Array = [0xFF0000, 0x000000]; var blueColors:Array = [0x0000FF, 0x000000]; var alphas:Array = [1, 1]; var ratios:Array = [0, 255]; var xMatrix:Matrix = new Matrix(); xMatrix.createGradientBox(radius * 2, radius * 2); var yMatrix:Matrix = new Matrix(); yMatrix.createGradientBox(radius * 2, radius * 2, Math.PI / 2); var xCircle:Shape = new Shape(); xCircle.graphics.lineStyle(0, 0, 0); xCircle.graphics.beginGradientFill(type, redColors, alphas, ratios, xMatrix); xCircle.graphics.drawCircle(radius, radius, radius); var yCircle:Shape = new Shape(); yCircle.graphics.lineStyle(0, 0, 0); yCircle.graphics.beginGradientFill(type, blueColors, alphas, ratios, yMatrix); yCircle.graphics.drawCircle(radius, radius, radius); // Position the circles at the bottom of the screen, for reference. this.addChild(xCircle); xCircle.y = stage.stageHeight - xCircle.height; this.addChild(yCircle); yCircle.y = stage.stageHeight - yCircle.height; yCircle.x = 200; // Load an image onto the Stage. var loader:Loader = new Loader(); var url:URLRequest = new URLRequest("http://www.helpexamples.com/flash/images/image1.jpg"); loader.load(url); this.addChild(loader); // Create the map image by combining the two gradient circles. var map:BitmapData = new BitmapData(xCircle.width, xCircle.height, false, 0x7F7F7F); map.draw(xCircle); var yMap:BitmapData = new BitmapData(yCircle.width, yCircle.height, false, 0x7F7F7F); yMap.draw(yCircle); map.copyChannel(yMap, yMap.rect, new Point(0, 0), BitmapDataChannel.BLUE, BitmapDataChannel.BLUE); yMap.dispose(); // Display the map image on the Stage, for reference. var mapBitmap:Bitmap = new Bitmap(map); this.addChild(mapBitmap); mapBitmap.x = 400; mapBitmap.y = stage.stageHeight - mapBitmap.height; // This function creates the displacement map filter at the mouse location. function magnify():void { // Position the filter. var filterX:Number = (loader.mouseX) - (map.width / 2); var filterY:Number = (loader.mouseY) - (map.height / 2); var pt:Point = new Point(filterX, filterY); var xyFilter:DisplacementMapFilter = new DisplacementMapFilter(); xyFilter.mapBitmap = map; xyFilter.mapPoint = pt; // The red in the map image will control x displacement. xyFilter.componentX = BitmapDataChannel.RED; // The blue in the map image will control y displacement. xyFilter.componentY = BitmapDataChannel.BLUE; xyFilter.scaleX = 35; xyFilter.scaleY = 35; xyFilter.mode = DisplacementMapFilterMode.IGNORE; loader.filters = [xyFilter]; } // This function is called when the mouse moves. If the mouse is // over the loaded image, it applies the filter. function moveMagnifier(event:MouseEvent):void { if (loader.hitTestPoint(loader.mouseX, loader.mouseY)) { magnify(); } } loader.addEventListener(MouseEvent.MOUSE_MOVE, moveMagnifier); Ce code génère d’abord deux cercles en dégradé, qui sont combinés pour former l’image de mappage du déplacement. Le cercle rouge est à l’origine du déplacement sur l’axe x (xyFilter.componentX = BitmapDataChannel.RED) et le cercle bleu est à l’origine du déplacement sur l’axe y (xyFilter.componentY = BitmapDataChannel.BLUE). Pour vous permettre de comprendre plus aisément l’aspect de l’image de mappage du déplacement, le code affiche les cercles originaux, ainsi que le cercle combiné qui fait office d’image de mappage, en bas de l’écran. Le code charge ensuite une image et, en fonction des déplacements de la souris, applique le filtre de déplacement à la partie de l’image qui est sous la souris. Les cercles dégradés utilisés pour l’image de mappage de déplacement provoquent un effet centrifuge dans la zone à laquelle le filtre est appliqué. Notez que les zones en gris de l’image de mappage du déplacement ne provoquent pas de déplacement. En effet, la valeur du gris est 0x7F7F7F. Les canaux bleu et rouge de ce niveau de gris ont donc exactement une valeur médiane, si bien qu’il n’y a pas de déplacement lorsqu’une zone grise apparaît dans l’image de mappage. Il n’y a pas non plus de déplacement au centre du cercle. Bien que cette zone ne soit pas de couleur grise, ses canaux rouge et bleu ont des valeurs identiques à celles des canaux rouge et bleu du gris moyen, et puisque le déplacement est basé sur les valeurs de bleu et de rouge, aucun déplacement n’a lieu. |
|