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.
|
|
|