Verschiebungsmatrix-Filter

Flash Player 9 und höher, Adobe AIR 1.0 und höher

Die DisplacementMapFilter-Klasse verwendet Pixelwerte eines BitmapData-Objekts (als Verschiebungsmatrixbild bezeichnet), um einen Verschiebungseffekt auf ein neues Objekt anzuwenden. Die Verschiebungsmatrix unterscheidet sich im Allgemeinen vom tatsächlichen Anzeigeobjekt bzw. der BitmapData-Instanz, auf die der Filter angewendet wird. Ein Verschiebungseffekt versetzt Pixel im gefilterten Bild – mit anderen Worten, sie werden um einen bestimmten Betrag von ihrer ursprünglichen Position weg verschoben. Mit diesem Filter kann ein verschobener, verzerrter oder mit einem Fleckenmuster versehener Effekt erzielt werden.

Die Position und der Betrag der Verschiebung eines bestimmten Pixels wird über den Farbwert der Verschiebungsmatrix berechnet. Wenn Sie diesen Filter verwenden, müssen Sie nicht nur das Matrixbild angeben, sondern auch die folgenden Werte zuweisen, um die Berechnung der Verschiebung aus dem Matrixbild steuern zu können:

  • Matrixpunkt: Die Position auf dem gefilterten Bild, auf die die obere linke Ecke des Verschiebungsmatrix-Filters angewendet wird. Sie verwenden diese Option, wenn Sie den Filter nur auf einen Teil des Bilds anwenden möchten.

  • X-Komponente: Legt fest, welcher Farbkanal des Matrixbilds sich auf die x-Position der Pixel auswirkt.

  • Y-Komponente: Legt fest, welcher Farbkanal des Matrixbilds sich auf die y-Position der Pixel auswirkt.

  • x-Skalierung: Ein Multiplikatorwert, mit dem festgelegt wird, wie stark die Verschiebung entlang der x-Achse ist.

  • y-Skalierung: Ein Multiplikatorwert, mit dem festgelegt wird, wie stark die Verschiebung entlang der y-Achse ist.

  • Filtermodus: Legt fest, was an den leeren Stellen ausgeführt werden soll, die aufgrund der verschobenen Pixel zurückbleiben. Folgende Optionen stehen zur Verfügung, die als Konstanten in der DisplacementMapFilterMode-Klasse definiert sind: Anzeigen der ursprünglichen Pixel (Filtermodus IGNORE ), Verschieben der Pixel auf die andere Seite des Quellbilds (Filtermodus WRAP , die Standardeinstellung), Verwenden des nächsten verschobenen Pixels (Filtermodus CLAMP ) oder Auffüllen leerer Flächen mit einer Farbe (Filtermodus COLOR ).

Die Funktionsweise des Verschiebungsmatrix-Filters soll anhand eines einfachen Beispiels veranschaulicht werden. Im folgenden Code wird ein Bild geladen. Wenn es vollständig geladen ist, wird es auf der Bühne zentriert und ein Verschiebungsmatrix-Filter wird auf das Bild angewendet, wodurch die Pixel im gesamten Bild horizontal nach links verschoben werden.

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);

Die zur Definition der Verschiebung verwendeten Eigenschaften lauten wie folgt:

  • Matrix-Bitmap: Die Verschiebungs-Bitmap ist eine neue BitmapData-Instanz, die vom Code erstellt wurde. Ihre Abmessungen entsprechen denen des geladenen Bilds (somit wird die Verschiebung auf das gesamte Bild angewendet). Es wird mit festen roten Pixeln aufgefüllt.

  • Matrixpunkt: Dieser Wert wird auf den Punkt 0,0 eingestellt – auch dies führt dazu, dass die Verschiebung auf das gesamte Bild angewendet wird.

  • X-Komponente: Dieser Wert wird auf die Konstante BitmapDataChannel.RED gesetzt. Dies bedeutet, dass der Rotwert der Matrix-Bitmap festlegt, um welchen Abstand die Pixel auf der x-Achse verschoben (versetzt) werden.

  • x-Skalierung: Dieser Wert wird auf 250 festgelegt. Beim vollständigen Ausmaß der Verschiebung (von einem vollständig rotem Matrixbild) wird das Bild nur geringfügig verschoben (etwa um die Hälfte eines Pixels). Wenn dieser Wert also auf 1 gesetzt ist, wird das Bild daher um nur 0,5 Pixel horizontal verschoben. Bei einer Einstellung von 250 wird das Bild um etwa 125 Pixel verschoben.

Bei diesen Einstellungen werden die Pixel des gefilterten Bilds um 250 Pixel nach links verschoben. Die Richtung (links oder rechts) und der Betrag der Verschiebung basieren auf dem Farbwert der Pixel im Matrixbild. Im Prinzip durchläuft der Filter nacheinander die Pixel des gefilterten Bilds (zumindest die Pixel in dem Bereich, auf den der Filter angewendet wurde, d. h. in diesem Fall alle Pixel), und führt Folgendes mit jedem Pixel aus:

  1. Er sucht die entsprechenden Pixel im Matrixbild. Wenn der Filter z. B. die Verschiebung für das Pixel in der linken oberen Ecke des gefilterten Bilds berechnet, sucht er nach dem entsprechenden Pixel in der linken oberen Ecke des Matrixbilds.

  2. Er ermittelt den Wert des angegebenen Farbkanals im Matrixpixel. In diesem Fall ist der Farbkanal der X-Komponente der Rotkanal, also sucht der Filter nach dem Wert des Rotkanals im Matrixbild an dem betreffenden Pixel. Da das Matrixbild vollständig rot ist, lautet der Wert für den Rotkanal des Pixels 0xFF bzw. 255. Dieser Wert wird für die Verschiebung verwendet.

  3. Er vergleicht den Verschiebungswert mit dem Mittelwert (127, die Hälfte zwischen 0 und 255). Ist der Verschiebungswert kleiner als der Mittelwert, werden die Pixel in positiver Richtung verschoben (bei einer x-Verschiebung nach rechts; bei einer y-Verschiebung nach unten). Ist der Verschiebungswert größer als der Mittelwert (wie in diesem Beispiel), werden die Pixel in negativer Richtung verschoben (bei einer x-Verschiebung nach links; bei einer y-Verschiebung nach oben). Um genau zu sein, subtrahiert der Filter den Verschiebungswert von 127, und das Ergebnis (positiv oder negativ) ist der relative Betrag der Verschiebung, der letztlich angewendet wird.

  4. Schließlich berechnet der Filter den tatsächlichen Betrag der Verschiebung, indem ermittelt wird, welchen Prozentsatz der vollständigen Verschiebung die relative Verschiebung darstellt. In diesem Fall bedeutet vollständig rot eine Verschiebung um 100 %. Dieser Prozentsatz wird dann mit dem Wert der x-Skalierung oder der y-Skalierung multipliziert, um die Anzahl der Pixel der angewendeten Verschiebung zu berechnen. In diesem Beispiel wird der Betrag der Verschiebung über 100 % mal einem Multiplikator von 250 berechnet – in etwa 125 Pixel nach links.

Da keine Werte für y-Komponente und y-Skalierung angegeben wurden, werden die Standardwerte verwendet (die keine Verschiebung verursachen). Aus diesem Grund wird das Bild nicht in vertikaler Richtung verschoben.

In diesem Beispiel wird die Standardeinstellung WRAP für den Filtermodus verwendet, sodass der leere Bereich auf der rechten Seite beim Verschieben der Pixel nach links mit den Pixeln gefüllt wird, die über den linken Rand des Bilds hinausgeschoben wurden. Sie können ein wenig mit diesem Wert experimentieren, um die unterschiedlichen Effekte zu betrachten. Wenn Sie beispielsweise die folgende Zeile zu dem Codeteil hinzufügen, in dem die Eigenschaften der Verschiebung angegeben werden (vor der Zeile loader.filters = [displacementMap] ), sieht das Bild so aus, als wäre es über die Bühne geschmiert:

displacementMap.mode = DisplacementMapFilterMode.CLAMP;

Im folgenden komplexeren Codebeispiel wird ein Verschiebungsmatrixfilter verwendet, um den Effekt eines Vergrößerungsglases über dem Bild zu erzeugen:

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);

Im Code werden zunächst zwei Farbverlaufkreise erstellt, die kombiniert werden, um die Verschiebungsmatrix zu bilden. Der rote Kreis erzeugt die Verschiebung auf der x-Achse ( xyFilter.componentX = BitmapDataChannel.RED ) und der blaue Kreis die Verschiebung auf der y-Achse ( xyFilter.componentY = BitmapDataChannel.BLUE ). Damit Sie eine bessere Vorstellung davon haben, wie die Verschiebungsmatrix aussieht, werden im Code zusätzlich die Originalkreise sowie der kombinierte Kreis, der als Matrixbild dient, am unteren Bildschirmrand dargestellt.

Bild mit dem Foto einer Blume, in dem ein kreisförmiger Bereich unter dem Mauszeiger vergrößert dargestellt ist.

Dann lädt der Code ein Bild. Wenn sich die Maus bewegt, wird der Verschiebungsmatrixfilter auf den Bereich des Bilds angewendet, der sich unter der Maus befindet. Die Farbverlaufkreise, die als Verschiebungsmatrixfilter verwendet werden, führen dazu, dass der verschobene Bereich vom Zeiger weg verteilt wird. Beachten Sie, dass die grauen Bereiche der Verschiebungsmatrix keine Verschiebung verursachen. Die Farbe Grau hat den Wert 0x7F7F7F . Die Blau- und Rotkanäle dieses Grautons entsprechen exakt dem mittleren Ton dieser Farbkanäle, somit findet im grauen Bereich des Matrixbilds keine Verschiebung statt. Entsprechend gibt es im Mittelpunkt des Kreises keine Verschiebung. Obwohl die Farbe dort nicht grau ist, sind der Blaukanal und Rotkanal dieser Farbe identisch mit dem Blau- und Rotkanal eines mittleren Graus, und da nur Blau und Rot zu einer Verschiebung führen, findet hier keine Verschiebung statt.