置換對應濾鏡Flash Player 9 以及更新的版本,Adobe AIR 1.0 以及更新的版本 DisplacementMapFilter 類別會使用 BitmapData 物件 (稱為置換對應影像) 的像素值,對新的物件執行置換特效。置換對應影像通常與實際顯示物件或是套用了濾鏡的 BitmapData 實體不同。置換效果牽涉到置換含濾鏡的影像像素,換句話說,就是在某種程度上將這些像素從原始位置偏移到其它位置。您可以使用這個濾鏡來建立偏移、彎曲或斑駁的效果。 套用至特定像素的置換位置與數量,需取決於置換對應影像的顏色值。在您使用此濾鏡時,除了指定對應影像外,還需指定下列數值,以控制對應影像中計算置換的方式:
若要瞭解置換對應濾鏡的運作方式,請以下列基本範例為例。下列程式碼會載入一個影像,並在影像完成載入時將影像放在「舞台」的中央,接著套用一個置換對應濾鏡,讓整個影像中的像素都向左水平平移。 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); 用來定義置換的屬性如下所示:
這些設定都會導致含濾鏡的影像像素向左偏移 250 個像素。像素的偏移方向 (向左或向右) 與數量,取決於對應影像中的像素顏色值。在概念上,濾鏡會依序檢查含濾鏡影像的每個像素 (至少會針對套用濾鏡區域中的像素進行檢查,在這裡指的是所有像素),並對每個像素執行下列動作:
由於並未指定任何有關 y 組件與 y 軸比例的值,所以會使用預設值 (也就不會置換),這就是為何影像不會沿著垂直方向做任何偏移的原因。 這個範例採用預設的濾鏡模式設定 WRAP,因此當像素向左偏移時,右側的空白空間就會填滿由影像左側邊緣偏移過來的像素。您可以使用這個值來測試一下,就可以看到不同的效果。例如,假如您將下列這一行程式碼加入設定了置換屬性的程式碼區段中 (在 loader.filters = [displacementMap] 這一行之前),會讓「舞台」上的影像看起來好像一大片塗鴉: displacementMap.mode = DisplacementMapFilterMode.CLAMP; 為了進一步說明較為複雜的案例,下列範例採用置換對應濾鏡,在影像上建立放大鏡效果: 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); 程式碼首先會產生兩個漸層圓形,以便加以結合並形成一個置換對應影像。紅色圓形會建立 x 軸置換 (xyFilter.componentX = BitmapDataChannel.RED),而藍色圓形則會建立 y 軸置換 (xyFilter.componentY = BitmapDataChannel.BLUE)。為了協助您認識置換對應影像的外觀,程式碼加入了原始圓形以及結合後放在畫面底部做為對應影像的圓形。 程式碼會接著載入影像,並在滑鼠移動時,將置換濾鏡套用至位於滑鼠底下的影像部分。用來做為置換對應影像的漸層圓形,會讓置換的區域從游標往外散開。請注意,置換對應影像的灰色區域不會產生任何置換效果。灰色值為 0x7F7F7F。由於此灰色色調的藍色與紅色色版剛好與這些顏色色版的中間色調一樣,因此在對應影像的灰色區域中不會產生任何置換效果。同理,圓形的中心位置也不會產生任何置換效果。雖然該處的顏色不是灰色,然而該顏色的藍色色版與紅色色版卻與淺灰色的藍色色版及紅色色版一模一樣,而且由於藍色與紅色都是會產生置換效果的顏色,因此該處不會有任何置換情況。 |
|