FörskjutningsfilterFlash Player 9 och senare, Adobe AIR 1.0 och senare Klassen DisplacementMapFilter använder pixelvärden från ett BitmapData-objekt (kallas för förskjutningsbild) för att skapa en förskjutningseffekt på ett nytt objekt. Förskjutningsbilden är oftast annorlunda än det visningsobjekt eller den BitmapData-instans som filtret tillämpas på. En förskjutningseffekt innebär att pixlar förskjuts i den filtrerade bilden. M.a.o. flyttas de bort från den ursprungliga platsen i någon utsträckning. Filtret kan användas för att skapa en skiftad, förvrängd eller ojämn effekt. Var och hur mycket förskjutning som används på en viss pixel avgörs av förskjutningsbildens färgvärde. När du arbetar med filtret anger du inte bara förskjutningsbild, du anger också följande värden som styr hur förskjutningen beräknas utifrån förskjutningsbilden:
Ett enkelt exempel gör det lättare att förstå hur förskjutningsfilter fungerar. I koden läses en bild in. När den har lästs in helt centreras den på scenen och ett förskjutningsfilter tillämpas på den så att pixlarna i hela bilden flyttas vågrätt till vänster. 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); De egenskaper som används för att definiera förskjutningen är följande:
De här inställningarna gör att den filtrerade bildens pixlar flyttas 250 pixlar till vänster. Förflyttningens riktning (vänster eller höger) och mängden förflyttning baseras på färgvärdet i pixlarna i förskjutningsbilden. Filtret går igenom pixlarna i den filtrerade bilden en i taget (åtminstone pixlarna i det område som filtret tillämpas på, vilket i det här fallet är alla pixlar) och gör följande med varje pixel:
Eftersom inga värden angavs för y-komponenten och y-skalan användes standardvärdena (vilket innebär att ingen förskjutning görs). Därför flyttas bilden inte alls i lodrät riktning. Standardinställningen för filterläge, WRAP, används i det här exemplet så att de tomma pixlar som uppstår till höger fylls av de pixlar som flyttades utanför bildens vänsterkant. Du kan experimentera med det här värdet för att se de olika effekterna. Om du till exempel lägger till följande rad i den del av koden där förskjutningsegenskaperna ställs in (före raden loader.filters = [displacementMap]) ser bilden ut som om den har smetats ut på scenen: displacementMap.mode = DisplacementMapFilterMode.CLAMP; Följande kod är ett mer komplicerat exempel där ett förskjutningsfilter används för att skapa effekten av ett förstoringsglas på en bild: 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); Koden skapar först två övertoningscirklar som kombineras till förskjutningsbilden. Den röda cirkeln skapar x-axelns förskjutning (xyFilter.componentX = BitmapDataChannel.RED) och den blå cirkeln skapar y-axelns förskjutning (xyFilter.componentY = BitmapDataChannel.BLUE). För att det ska bli lättare att förstå hur förskjutningsbilden ser ut läggs både originalcirklarna och den kombinerade cirkeln som fungerar som förskjutningsbild till längst ned på skärmen. Sedan läses en bild in och när musen flyttas tillämpas förskjutningsfiltret på den del av bilden som är under muspekaren. Övertoningscirklarna som används som förskjutningsbild gör att det förskjutna området sprids ut från pekaren. Observera att de grå områdena i förskjutningsbilden inte orsakar någon förskjutning. Den grå färgen är 0x7F7F7F. De blå och röda kanalerna för den nyansen av grått matchar mellannyansen för dessa färgkanaler exakt. Det gör att ingen förskjutning görs i grå områden i förskjutningsbilden. På samma sätt görs ingen förskjutning i cirkelns mitt. Färgen där är inte grå, men färgens blå kanal och röda kanal är identiska med den blå kanalen och den röda kanalen i mellangrå. Eftersom blå och röd är de färger som orsakar förskjutningen görs ingen förskjutning där. |
|