Erstellen und Anwenden von Filtern

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

Mit Filtern können Sie verschiedene Effekte auf Bitmap- und Anzeigeobjekte anwenden, von Schlagschatten bis hin zu abgeschrägten Kanten und Weichzeichnungen. Jeder Filter ist als eine Klasse definiert, daher müssen beim Anwenden von Filtern Instanzen der Filterobjekte erstellt werden. Dies verhält sich genauso wie beim Erstellen anderer Objekte. Nachdem Sie eine Instanz eines Filterobjekts erstellt haben, können Sie es mithilfe der filters -Eigenschaft des Objekts (oder bei einem BitmapData-Objekt mithilfe der applyFilter() -Methode) auf ein Anzeigeobjekt anwenden.

Erstellen eines Filters

Zum Erstellen eines Filterobjekts rufen Sie einfach die Konstruktormethode der ausgewählten Filterklasse auf. Um beispielsweise ein DropShadowFilter-Objekt zu erstellen, verwenden Sie den folgenden Code:

import flash.filters.DropShadowFilter; 
var myFilter:DropShadowFilter = new DropShadowFilter();

Der DropShadowFilter() -Konstruktor akzeptiert (wie alle Konstruktoren von Filterklassen) verschiedene optionale Parameter, mit denen das Erscheinungsbild des Filtereffekts angepasst werden kann. Dies wird hier jedoch nicht näher beschrieben.

Anwenden eines Filters

Nachdem Sie ein Filterobjekt erstellt haben, können Sie es auf ein Anzeigeobjekt oder ein BitmapData-Objekt anwenden. Wie der Filter genau angewendet wird, hängt von dem Objekt ab, auf das Sie ihn anwenden möchten.

Anwenden eines Filters auf ein Anzeigeobjekt

Zum Anwenden von Filtereffekten auf ein Anzeigeobjekt können Sie die filters -Eigenschaft verwenden. Die filters -Eigenschaft eines Anzeigeobjekts ist eine Array-Instanz. Deren Elemente sind die Filterobjekte, die auf das Anzeigeobjekt angewendet werden. Um einen einzelnen Filter auf ein Anzeigeobjekt anzuwenden, erstellen Sie zunächst eine Filterinstanz. Fügen Sie sie dann einer Array-Instanz hinzu und weisen Sie dieses Array-Objekt der filters -Eigenschaft des Anzeigeobjekts zu:

import flash.display.Bitmap; 
import flash.display.BitmapData; 
import flash.filters.DropShadowFilter; 
 
// Create a bitmapData object and render it to screen 
var myBitmapData:BitmapData = new BitmapData(100,100,false,0xFFFF3300); 
var myDisplayObject:Bitmap = new Bitmap(myBitmapData); 
addChild(myDisplayObject); 
 
// Create a DropShadowFilter instance. 
var dropShadow:DropShadowFilter = new DropShadowFilter(); 
 
// Create the filters array, adding the filter to the array by passing it as  
// a parameter to the Array() constructor. 
var filtersArray:Array = new Array(dropShadow); 
 
// Assign the filters array to the display object to apply the filter. 
myDisplayObject.filters = filtersArray;

Wenn Sie mehrere Filter auf ein Objekt anwenden möchten, fügen Sie einfach alle Filter zur Array-Instanz hinzu, bevor Sie das Array-Objekt der filters -Eigenschaft zuweisen. Sie können einem Array mehrere Objekte hinzufügen, indem Sie sie als Parameter an den Array-Konstruktor übergeben. Mit dem folgenden Code wird beispielsweise ein Geschliffen- (bevel) und einen Glühen-Filter (glow) auf das im vorangegangenen Beispiel erstellte Anzeigeobjekt angewendet:

import flash.filters.BevelFilter; 
import flash.filters.GlowFilter; 
 
// Create the filters and add them to an array. 
var bevel:BevelFilter = new BevelFilter(); 
var glow:GlowFilter = new GlowFilter(); 
var filtersArray:Array = new Array(bevel, glow); 
 
// Assign the filters array to the display object to apply the filter. 
myDisplayObject.filters = filtersArray;

Zum Erstellen des Arrays mit den Filtern können Sie entweder den new Array() -Konstruktor (wie in den vorangegangenen Beispielen) oder die Array-Literalsyntax verwenden, bei der die Filter in eckigen Klammern eingeschlossen sind ( [] ). Beispielsweise führt die folgende Codezeile:

var filters:Array = new Array(dropShadow, blur); 

das Gleiche aus wie diese Codezeile:

var filters:Array = [dropShadow, blur];

Wenn Sie mehrere Filter auf Anzeigeobjekte anwenden, werden sie kumulativ und aufeinander folgend angewendet. Angenommen, ein filters-Array enthält zwei Elemente, zunächst einen Geschliffen-Filter und dann einen Schlagschatten-Filter, so wird erst der Geschliffen-Filter auf das Anzeigeobjekt angewendet und dann der Schlagschatten-Filter auf den Geschliffen-Filter und das Anzeigeobjekt. Der Grund hierfür ist, dass sich der Schlagschatten-Filter an zweiter Stelle im filters-Array befindet. Wenn Sie Filter nicht kumulativ anwenden möchten, wenden Sie jeden Filter auf eine neue Kopie des Anzeigeobjekts an.

Sollen einem Anzeigeobjekt nur ein oder wenige Filter zugewiesen werden, können Sie in nur einer Anweisung die Filterinstanz erstellen und dem Objekt zuweisen. Mit der folgenden Codezeile wird beispielsweise ein Weichzeichnen-Filter auf ein Anzeigeobjekt mit dem Namen myDisplayObject angewendet:

myDisplayObject.filters = [new BlurFilter()];

Mit diesem Code wird mit der Array-Literalsyntax (eckige Klammern) eine Array-Instanz erstellt. Anschließend wird eine BlurFilter-Instanz als Element dieses Arrays erstellt und das Array dann der filters -Eigenschaft des Anzeigeobjekts myDisplayObject zugewiesen.

Entfernen von Filtern von einem Anzeigeobjekt

Das Entfernen aller Filter von einem Anzeigeobjekt ist sehr einfach. Sie müssen lediglich der filters -Eigenschaft den Wert null zuweisen:

myDisplayObject.filters = null;

Wenn Sie mehrere Filter auf ein Objekt angewendet haben und nur einen Filter entfernen möchten, müssen Sie mehrere Schritte ausführen, um das Array der filters -Eigenschaft zu ändern. Weitere Informationen finden Sie unter Potenzielle Probleme beim Verwenden von Filtern .

Anwenden eines Filters auf ein BitmapData-Objekt

Zum Anwenden eines Filters auf ein BitmapData-Objekt ist die applyFilter() -Methode des BitmapData-Objekts erforderlich:

var rect:Rectangle = new Rectangle(); 
var origin:Point = new Point(); 
myBitmapData.applyFilter(sourceBitmapData, rect, origin, new BlurFilter());

Die applyFilter() -Methode wendet einen Filter auf das BitmapData-Quellobjekt an und erzeugt ein neues gefiltertes Bild. Bei dieser Methode wird das ursprüngliche Bild nicht geändert. Stattdessen wird das Ergebnis des auf das Quellbild angewendeten Filters in der BitmapData-Instanz gespeichert, für die die applyFilter() -Methode aufgerufen wird.

Funktionsweise von Filtern

Beim Anwenden von Filtern auf Anzeigeobjekte wird eine Kopie des ursprünglichen Objekts als eine transparentes Bitmap zwischengespeichert.

Nachdem ein Filter auf ein Anzeigeobjekt angewendet wurde, wird das Objekt in der Laufzeitumgebung als Bitmap zwischengespeichert, solange es über eine gültige Filterliste verfügt. Diese Quellbitmap wird dann als Originalbild für alle nachfolgend angewendeten Filtereffekte verwendet.

Jedes Anzeigeobjekt besitzt in der Regel zwei Bitmaps: eine mit dem ursprünglichen Quellanzeigeobjekt und eine zweite für das nach dem Filtern entstehende Bild. Dieses Ergebnisbild wird für die Darstellung verwendet. Solange sich das Anzeigeobjekt nicht ändert, muss das Ergebnisbild nicht aktualisiert werden.

Potenzielle Probleme beim Verwenden von Filtern

Beim Verwenden von Filtern können verschiedene potenzielle Probleme und Fehler auftreten.

Filter und Bitmap-Zwischenspeicherung

Um einen Filter auf ein Anzeigeobjekt anwenden zu können, muss die Bitmap-Zwischenspeicherung für das Objekt aktiviert sein. Wenn Sie einen Filter auf ein Anzeigeobjekt anwenden, dessen cacheAsBitmap -Eigenschaft auf false gesetzt ist, wird die cacheAsBitmap -Eigenschaft des Objekts automatisch auf true gesetzt. Wenn Sie später sämtliche Filter eines Anzeigeobjekts entfernen, wird die cacheAsBitmap -Eigenschaft auf den Wert zurückgesetzt, der zuletzt eingestellt war.

Ändern von Filtern zur Laufzeit

Wenn einem Anzeigeobjekt bereits ein oder mehrere Filter zugewiesen wurden, können Sie diesen Filtersatz nicht ändern, indem Sie zusätzliche Filter hinzufügen oder Filter aus dem Array der filters -Eigenschaft entfernen. Um den bereits angewendeten Filtersatz zu erweitern oder zu ändern, müssen Sie die Änderungen an einem separaten Array vornehmen und dieses Array dann der filters-Eigenschaft des Anzeigeobjekts für die auf das Objekt anzuwendenden Filter zuweisen. Die einfachste Methode dafür ist das Einlesen des Arrays der filters -Eigenschaft in eine Array-Variable und das Vornehmen von Änderungen in diesem temporären Array. Anschließend weisen Sie das Array wieder der filters -Eigenschaft des Anzeigeobjekts zu. In komplexeren Fällen müssen Sie unter Umständen ein separates Master-Filter-Array verwenden. Sie nehmen dann alle Änderungen an diesem Master-Filter-Array vor und weisen das Master-Array der filters -Eigenschaft des Anzeigeobjekts nach jeder Änderung erneut zu.

Hinzufügen eines zusätzlichen Filters

Der folgende Code zeigt das Hinzufügen eines zusätzlichen Filters zu einem Anzeigeobjekt, das schon einen oder mehrere Filter aufweist. Zunächst wurde ein Glühen-Filter auf ein Anzeigeobjekt namens myDisplayObject angewendet. Beim Klicken auf das Anzeigeobjekt wird dann die Funktion addFilters() aufgerufen. In dieser Funktion werden zwei zusätzliche Filter auf myDisplayObject angewendet:

import flash.events.MouseEvent; 
import flash.filters.*; 
 
myDisplayObject.filters = [new GlowFilter()]; 
 
function addFilters(event:MouseEvent):void 
{ 
    // Make a copy of the filters array. 
    var filtersCopy:Array = myDisplayObject.filters; 
 
    // Make desired changes to the filters (in this case, adding filters). 
    filtersCopy.push(new BlurFilter()); 
    filtersCopy.push(new DropShadowFilter()); 
 
    // Apply the changes by reassigning the array to the filters property. 
    myDisplayObject.filters = filtersCopy; 
} 
 
myDisplayObject.addEventListener(MouseEvent.CLICK, addFilters);

Entfernen eines Filters aus einem Filtersatz

Wenn mehrere Filter auf ein Anzeigeobjekt angewendet wurden und Sie einen der Filter entfernen möchten, während die anderen Filter weiter auf das Objekt angewendet sind, können Sie die Filter in ein temporäres Array kopieren, den unerwünschten Filter aus diesem Array entfernen und das temporäre Array der filters -Eigenschaft des Anzeigeobjekts neu zuweisen. Verschiedene Möglichkeiten zum Entfernen eines oder mehrerer Elemente aus einem Array werden im Abschnitt Abrufen von Werten und Entfernen von Array-Elementen beschrieben.

Die einfachste Möglichkeit ist das Entfernen des obersten Filters für das Objekt (der zuletzt auf das Objekt angewendete Filter). Sie verwenden die pop() -Methode der Array-Klasse zum Entfernen des Filters aus dem Array:

// Example of removing the top-most filter from a display object  
// named "filteredObject". 
 
var tempFilters:Array = filteredObject.filters; 
 
// Remove the last element from the Array (the top-most filter). 
tempFilters.pop(); 
 
// Apply the new set of filters to the display object. 
filteredObject.filters = tempFilters;

Zum Entfernen des untersten Filters (des zuerst auf das Objekt angewendeten Filters) verwenden Sie den gleichen Code, wobei Sie jedoch die shift() -Methode der Array-Klasse anstatt der pop() -Methode verwenden.

Zum Entfernen eines Filters aus der Mitte eines Filter-Arrays (wenn das Array mehr als zwei Filter hat) können Sie die splice() -Methode verwenden. Sie müssen die Indexposition (die Position im Array) des Filters kennen, den Sie entfernen möchten. Mit dem folgenden Code wird z. B. der zweite Filter (Filter mit Indexposition 1) von einem Anzeigeobjekt entfernt:

// Example of removing a filter from the middle of a stack of filters 
// applied to a display object named "filteredObject". 
 
var tempFilters:Array = filteredObject.filters; 
 
// Remove the second filter from the array. It's the item at index 1  
// because Array indexes start from 0. 
// The first "1" indicates the index of the filter to remove; the  
// second "1" indicates how many elements to remove. 
tempFilters.splice(1, 1); 
 
// Apply the new set of filters to the display object. 
filteredObject.filters = tempFilters;

Ermitteln der Indexposition eines Filters

Sie müssen wissen, welcher Filter aus dem Array entfernt werden soll, um die Indexposition des Filters zu kennen. Sie müssen die Indexposition des zu entfernenden Filters entweder kennen (anhand des Aufbaus der Anwendung) oder berechnen.

Der beste Ansatz ist dabei, die Anwendung so zu konzipieren, dass sich der zu entfernende Filter immer an der gleichen Position innerhalb des Filtersatzes befindet. Wenn z. B. ein einziges Anzeigeobjekt vorliegt, auf das zuerst ein Convolution-Filter und dann ein Schlagschatten-Filter angewendet wurde, und Sie den Schlagschatten-Filter entfernen, den Convolution-Filter aber beibehalten möchten, wissen Sie, an welcher Position sich der zu entfernende Filter befindet (oberste Position), sodass die zu verwendende Array-Methode leicht zu ermitteln ist (in diesem Beispiel Array.pop() zum Entfernen des Schlagschatten-Filters).

Wenn der zu entfernende Filter immer einen bestimmten Typ aufweist, aber sich nicht immer unbedingt an der gleichen Position innerhalb des Filtersatzes befindet, können Sie die Datentypen der einzelnen Filter im Array prüfen, um zu ermitteln, welcher Filter entfernt werden soll. Mit dem folgenden Code wird z. B. ermittelt, welcher Filter innerhalb eines Filtersatzes ein Glühen-Filter ist, und dieser Filter aus dem Satz entfernt.

// Example of removing a glow filter from a set of filters, where the 
//filter you want to remove is the only GlowFilter instance applied  
// to the filtered object. 
 
var tempFilters:Array = filteredObject.filters; 
 
// Loop through the filters to find the index of the GlowFilter instance. 
var glowIndex:int; 
var numFilters:int = tempFilters.length; 
for (var i:int = 0; i < numFilters; i++) 
{ 
    if (tempFilters[i] is GlowFilter) 
    { 
        glowIndex = i; 
        break; 
    } 
} 
 
// Remove the glow filter from the array. 
tempFilters.splice(glowIndex, 1); 
 
// Apply the new set of filters to the display object. 
filteredObject.filters = tempFilters;

In komplexeren Fällen, wenn der zu entfernende Filter z. B. zur Laufzeit ausgewählt wird, besteht der beste Ansatz in der Erstellung einer separaten, dauerhaften Kopie des Filter-Arrays, die als Master-Filterliste fungiert. Jedes Mal, wenn Sie eine Änderung am Filtersatz vornehmen, ändern Sie die Master-Liste und wenden Sie dann dieses Filter-Array als filters -Eigenschaft des Anzeigeobjekts an.

Im folgenden Codebeispiel werden z. B. mehrere Convolution-Filter auf ein Anzeigeobjekt angewendet, um verschiedene visuelle Effekte zu erzeugen. Später wird einer dieser Filter entfernt, während die anderen beibehalten werden. In diesem Beispiel werden eine Master-Kopie des Filter-Arrays sowie ein Verweis auf den zu entfernenden Filter erstellt. Das Auffinden und Entfernen des speziellen Filters ähnelt dem vorhergehenden Verfahren, nur wird keine temporäre Kopie des Filter-Arrays erstellt, sondern die Master-Kopie wird bearbeitet und auf das Anzeigeobjekt angewendet.

// Example of removing a filter from a set of  
// filters, where there may be more than one  
// of that type of filter applied to the filtered  
// object, and you only want to remove one. 
 
// A master list of filters is stored in a separate, 
// persistent Array variable. 
var masterFilterList:Array; 
 
// At some point, you store a reference to the filter you 
// want to remove. 
var filterToRemove:ConvolutionFilter; 
 
// ... assume the filters have been added to masterFilterList, 
// which is then assigned as the filteredObject.filters: 
filteredObject.filters = masterFilterList; 
 
// ... later, when it's time to remove the filter, this code gets called: 
 
// Loop through the filters to find the index of masterFilterList. 
var removeIndex:int = -1; 
var numFilters:int = masterFilterList.length; 
for (var i:int = 0; i < numFilters; i++) 
{ 
    if (masterFilterList[i] == filterToRemove) 
    { 
        removeIndex = i; 
        break; 
    } 
} 
 
if (removeIndex >= 0) 
{ 
    // Remove the filter from the array. 
    masterFilterList.splice(removeIndex, 1); 
 
    // Apply the new set of filters to the display object. 
    filteredObject.filters = masterFilterList; 
}

Bei diesem Verfahren (Vergleichen eines gespeicherten Filterverweises mit den Elementen im Filter-Array, um den zu entfernenden Filter zu ermitteln) müssen Sie eine separate Kopie des Filter-Arrays erstellen – der Code funktioniert nicht, wenn Sie den gespeicherten Filterverweis mit den Elementen in einem temporären Array vergleichen, das von der filters -Eigenschaft des Anzeigeobjekts kopiert wurde. Dies liegt daran, dass die Laufzeitumgebung Kopien der Filterobjekte im Array erstellt, wenn Sie ein Array zur filters -Eigenschaft zuweisen. Diese Kopien (und nicht die Originalobjekte) werden auf das Anzeigeobjekt angewendet; wenn Sie die filters -Eigenschaft in ein temporäres Array einlesen, enthält das temporäre Array Verweise auf die kopierten Filterobjekte, und nicht auf die Original-Filterobjekte. Wenn Sie dementsprechend im vorangehenden Beispiel versuchen, die Indexposition von filterToRemove zu ermitteln, indem Sie ihn mit den Filtern in einem temporären Filter-Array vergleichen, wird keine Übereinstimmung gefunden.

Filter und Objekttransformationen

Gefilterte Regionen (z. B. ein Schlagschatten) außerhalb des Begrenzungsrahmens eines Anzeigeobjekts werden bei der Kollisionserkennung (beim Ermitteln, ob eine Instanz eine andere Instanz überlappt oder schneidet) nicht als Teil der Oberfläche berücksichtigt. Da die Kollisionserkennung der DisplayObject-Klasse vektorbasiert ist, können Sie keine Kollisionserkennung am Bitmapergebnis vornehmen. Wenn Sie z. B. einen Geschliffen-Filter auf eine Schaltflächeninstanz anwenden, steht die Kollisionserkennung für den entsprechenden Teil der Instanz nicht zur Verfügung.

Skalierung, Drehung und Neigung werden nicht von Filtern unterstützt. Zwar ist das gefilterte Anzeigeobjekt selbst skaliert (wenn scaleX und scaleY nicht 100 % sind), der Filtereffekt wird jedoch nicht zusammen mit der Instanz skaliert. Das bedeutet, dass die ursprüngliche Form der Instanz gedreht, skaliert oder geneigt ist, der Filter diese Effekte jedoch nicht nachvollzieht.

Um realistische Effekte zu erstellen, können Sie eine Instanz mit einem Filter animieren, oder Sie erzielen den gleichen Effekt durch das Verschachteln von Instanzen und Animieren von Filtern mit der BitmapData-Klasse.

Filter und Bitmapobjekte

Wenn Sie einen Filter auf ein BitmapData-Objekt anwenden, wird die cacheAsBitmap -Eigenschaft automatisch auf true gesetzt. Auf diese Weise wird der Filter auf die Kopie des Objekts und nicht auf das ursprüngliche Objekt angewendet.

Diese Kopie wird dann auf der Hauptanzeige (über dem ursprünglichen Objekt) möglichst nah am nächsten Pixel platziert. Ändern sich die Begrenzungen der ursprünglichen Bitmap, wird die gefilterte Kopie der Bitmap nicht gestreckt oder verzerrt, sondern neu erstellt.

Wenn Sie alle Filter eines Anzeigeobjekts löschen, wird die cacheAsBitmap -Eigenschaft auf den Wert zurückgesetzt, der vor dem Anwenden der Filter gültig war.