De klasse DisplacementMapFilter gebruikt pixelwaarden uit een BitmapData-object (de displacement map image genoemd) om een verplaatsingseffect toe te passen op een nieuw object. De verschuivingskaartafbeelding verschilt doorgaans van het daadwerkelijke weergaveobject of de instantie BitmapData waarop het filter wordt toegepast. Bij verschuivingseffect worden pixels in de gefilterde afbeelding verschoven: met andere woorden, ze worden enigszins bij de oorspronkelijk locatie vandaan vergeplaatst. U kunt dit filter gebruiken voor het toepassen van een verschoven, kromgetrokken of gespikkeld effect.
De locatie en de mate van verschuiving die wordt toegepast op een bepaalde pixel, worden vastgelegd door de kleurwaarde van de verschuivingskaartafbeelding. Wanneer u werkt met het filter, geeft u naast de kaartafbeelding de volgende waarden op om te bepalen hoe de verschuiving wordt berekend uit de kaartafbeelding:
-
Kaartpunt: De locatie op de gefilterde afbeelding waarop de linkerbovenhoek van het verschuivingsfilter wordt toegepast. U kunt dit alleen gebruiken wanneer u het filter wilt toepassen op een deel van een afbeelding.
-
X-component: welk kleurkanaal van de kaartafbeelding de x-positie van pixels beïnvloedt.
-
Y-component: welk kleurkanaal van de kaartafbeelding de y-positie van pixels beïnvloedt.
-
X-schaal: een vermenigvuldigingswaarde die opgeeft hoe sterk de verschuiving van de x-as is.
-
Y-schaal: een vermenigvuldigingswaarde die opgeeft hoe sterk de verschuiving van de y-as is.
-
Filtermodus: hiermee wordt bepaald wat te doen met lege ruimten die het resultaat zijn van verplaatste pixels. De opties, die zijn gedefinieerd als constanten in de klasse DisplacementMapFilterMode, zijn: de oorspronkelijke pixels weergeven (filtermodus
IGNORE
), de pixels laten doorlopen vanaf de andere kant van de afbeelding (de standaardinstelling
WRAP
), de dichtstbijzijnde verplaatste pixel gebruiken (filtermodus
CLAMP
) of de ruimten te vullen met een kleur (filtermodus
COLOR
).
Hier volgt een eenvoudig voorbeeld ter illustratie van hoe het verplaatsingsfilter werkt. In de volgende code wordt een afbeelding geladen, wordt deze na het laden gecentreerd in het werkgebied en wordt er een verschuivingskaartfilter op toegepast waardoor de pixels in de hele afbeelding horizontaal naar links worden verschoven.
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 eigenschappen die worden gebruikt om de verschuiving te definiëren zijn:
-
Kaartbitmap: de verschuivingsbitmap is een nieuwe instantie BitmapData die is gemaakt door de code. De afmetingen komen overeen met de afmetingen van de geladen afbeelding (de verschuiving is dus toegepast op de hele afbeelding). De bitmap wordt gevuld met effen rode pixels.
-
Kaartpunt: deze waarde is ingesteld op het punt 0, 0 (ook hier wordt de verschuiving toegepast op de hele afbeelding).
-
X-component: deze waarde is ingesteld op de constante
BitmapDataChannel.RED
. Dit houdt in dat de rode waarde van de kaartbitmap bepaalt in welke mate de pixels worden verschoven (worden verplaatst) langs de x-as.
-
X-schaal: Deze waarde is ingesteld op 250. Bij een volledige mate van verschuiving (waarbij de kaartafbeelding volledig rood is) wordt de afbeelding slechts een klein stukje verschoven (ruwweg een halve pixel), dus wanneer deze waarde is ingesteld op 1, verschuift de afbeelding slechts 5 pixels horizontaal. Bij de instelling van 250 verschuift de afbeelding ongeveer 125 pixels.
Met deze instellingen worden pixels van de gefilterde afbeelding 250 pixels naar links verschoven. De richting (links of rechts) en mate van verschuiving worden gebaseerd op de kleurwaarde van de pixels in de kaartafbeelding. De filter doorloopt de pixels van de gefilterde afbeelding een voor een (tenminste, de pixels in het gebied waar het filter is toegepast, in dit geval alle pixels) en doet het volgende met elke pixel:
-
Flash Player vindt de overeenkomende pixel in de kaartafbeelding. Wanneer de filter bijvoorbeeld de mate van verschuiving berekent voor de pixel in de linkerbovenhoek van de gefilterde afbeelding, zoekt de filter naar de pixel in de linkerbovenhoek van de kaartafbeelding.
-
Flash Player stelt de waarde vast van het opgegeven kleurkanaal in de kaartpixel. In dit geval is de x-component van het kleurkanaal het rode kanaal en zoekt de filter de waarde van het rode kanaal van de kaartafbeelding op bij de desbetreffende pixel. Omdat de kaartafbeelding effen rood is, is het rode kanaal van de pixel 0xFF of 255. Dit wordt gebruikt als de verschuivingswaarde.
-
Flash Player vergelijkt de verschuivingswaarde met de ‘middelste’ waarde (127 is halverwege 0 en 255). Wanneer de verschuivingswaarde lager is dan de middelste waarde, verschuift de pixel in een positieve richting (naar rechts voor x-verschuiving, omlaag voor y-verschuiving). Wanneer de verschuivingswaarde daarentegen hoger is dan de middelste waarde (zoals in dit voorbeeld), verschuift de pixel in negatieve richting (naar links voor x-verschuiving, omhoog voor y-verschuiving). Om precies te zijn trekt de filter de verschuivingswaarde af van 127 en het resultaat (positief of negatief) is de relatieve mate van verschuiving die wordt toegepast.
-
Ten slotte bepaalt Flash Player de daadwerkelijke mate van verschuiving door vast te stellen welk percentage van volledige verschuiving de relatieve verschuivingswaarde vertegenwoordigt. In dit geval betekent volledig rood 100% verschuiving. Dat percentage wordt vervolgens vermenigvuldigd met de waarde van de x- of de y-schaal om het aantal pixels verschuiving dat wordt toegepast, vast te stellen. In dit voorbeeld bepaalt 100% keer een vermenigvuldiger van 250 de mate van verschuiving (ruwweg 125 pixels naar links).
Omdat er geen waarden zijn opgegeven voor y-component en y-schaal, zijn de standaardwaarden (die geen verschuiving veroorzaken) gebruikt. Daarom verschuift de afbeelding helemaal niet in verticale richting.
In dit voorbeeld is de standaardinstelling voor filtermodus
WRAP
gebruikt, zodat, wanneer de pixels naar links verschuiven, de lege ruimte die rechts wordt achtergelaten, wordt opgevuld met de pixels die aan de linkerkant van de afbeelding zijn verdwenen. U kunt met deze waarde experimenteren om te zien wat de verschillende effecten zijn. Wanneer u bijvoorbeeld de volgende regel toevoegt aan het deel van de code waarin de verschuivingseigenschappen zijn ingesteld (voor de regel
loader.filters = [displacementMap]
), ziet de afbeelding eruit alsof deze is uitgevlakt over het werkgebied:
displacementMap.mode = DisplacementMapFilterMode.CLAMP;
De volgende code is een complexer voorbeeld waarbij een verschuivingskaartfilter wordt gebruikt om een vergrootglaseffect toe te passen op de afbeelding:
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);
De code genereert eerst twee verlopende cirkels die samen worden gecombineerd om de verschuivingskaartafbeelding te vormen. De rode cirkel veroorzaakt de verschuiving op de x-as (
xyFilter.componentX = BitmapDataChannel.RED
) en de blauwe cirkel veroorzaakt de verschuiving op de y-as (
xyFilter.componentY = BitmapDataChannel.BLUE
). De code voegt zowel de oorspronkelijke cirkels als de gecombineerde cirkel die fungeert als de kaartafbeelding onder in het scherm, toe om u te helpen begrijpen hoe de verschuivingskaartafbeelding eruit ziet.
De code laadt vervolgens een afbeelding en past, zodra de muis beweegt, het verschuivingsfilter toe op het deel van de afbeelding dat zich onder de muis bevindt. Door de verlopende cirkels die zijn gebruikt als de verschuivingskaartafbeelding, wordt het verschoven gebied van de muisaanwijzer vandaan verspreid. De grijze gebieden van de verschuivingskaartafbeelding veroorzaken geen verschuiving. De grijze kleur is
0x7F7F7F
. De blauwe en rode kanalen van deze grijstint komen precies overeen met de middelste tint van deze kleurkanalen, waardoor er geen verschuiving plaatsvindt in een grijs gebied van de kaartafbeelding. Op dezelfde manier vindt er geen verschuiving plaats in het midden van de cirkel. Hoewel de kleur daar niet grijs is, zijn de blauwe en rode kleurkanalen van die kleur gelijk aan de blauwe en rode kleurkanalen van middengrijs. Aangezien blauw en rood de kleuren zijn die de verschuiving veroorzaken, vindt er geen verschuiving plaats.