Beispiel für das Filtern von Anzeigeobjekten: Filter Workbench

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

Die Anwendung „Filter Workbench“ bietet eine Benutzeroberfläche, über die verschiedene Filter auf Bilder und andere visuelle Inhalte angewendet werden können. Außerdem wird der resultierende Code angezeigt, mit dem die gleichen Effekte in ActionScript erzeugt werden können. Mit diesem Tool können Sie die Effekte verschiedener Filter testen. Zusätzlich werden mit dieser Anwendung die folgenden Techniken verdeutlicht:

  • Erstellen von Instanzen verschiedener Filter

  • Anwenden mehrerer Filter auf ein Anzeigeobjekt

Die Anwendungsdateien für dieses Beispiel finden Sie unter www.adobe.com/go/learn_programmingAS3samples_flash_de . Die Dateien der Anwendung „Filter Workbench“ befinden sich im Ordner „Samples/FilterWorkbench“. Die Anwendung umfasst die folgenden Dateien:

Datei

Beschreibung

com/example/programmingas3/filterWorkbench/FilterWorkbenchController.as

Klasse mit den Hauptfunktionen der Anwendung, einschließlich Ändern des Inhalts, auf den Filter angewendet werden, und Anwenden von Filtern auf Inhalte.

com/example/programmingas3/filterWorkbench/IFilterFactory.as

Schnittstelle zur Definition allgemeiner Methoden, die von allen Factory-Klassen für Filter implementiert werden. Über diese Schnittstelle werden die gemeinsamen Funktionen definiert, die von der FilterWorkbenchController-Klasse zum Interagieren mit den einzelnen Factory-Klassen für Filter verwendet werden.

Im Ordner com/example/programmingas3/filterWorkbench/:

BevelFactory.as

BlurFactory.as

ColorMatrixFactory.as

ConvolutionFactory.as

DropShadowFactory.as

GlowFactory.as

GradientBevelFactory.as

GradientGlowFactory.as

Gruppe von Klassen, die die IFilterFactory-Schnittstelle implementieren. Jede dieser Klassen enthält die Funktionen zum Erstellen eines bestimmten Filtertyps und zum Festlegen von entsprechenden Werten. In der Anwendung werden in den Eigenschaftenbedienfeldern mithilfe dieser Factory-Klassen Instanzen der jeweiligen Filter erstellt, die dann von der FilterWorkbenchController-Klasse abgerufen und auf den Bildinhalt angewendet werden.

com/example/programmingas3/filterWorkbench/IFilterPanel.as

Schnittstelle zur Definition allgemeiner Methoden, die von Klassen implementiert werden, die die zum Bearbeiten von Filterwerten verwendeten Benutzerobenflächen-Bedienfelder definieren.

com/example/programmingas3/filterWorkbench/ColorStringFormatter.as

Dienstprogrammklasse, die eine Methode zum Konvertieren von numerischen Farbwerten in das hexadezimale Stringformat enthält.

com/example/programmingas3/filterWorkbench/GradientColor.as

Klasse, die als Wertobjekt dient und in der die jeder Farbe in GradientBevelFilter und GradientGlowFilter zugeordneten drei Werte (Farbe, Alpha und Verhältnis) in einem Objekt kombiniert werden.

Benutzeroberfläche (Flex)

FilterWorkbench.mxml

Die Hauptdatei für die Benutzeroberfläche der Anwendung.

flexapp/FilterWorkbench.as

Klasse mit den Funktionen für die Benutzeroberfläche der Hauptanwendung. Diese Klasse wird als CodeBehind-Klasse für die MXML-Datei der Anwendung verwendet.

Im Ordner flexapp/filterPanels:

BevelPanel.mxml

BlurPanel.mxml

ColorMatrixPanel.mxml

ConvolutionPanel.mxml

DropShadowPanel.mxml

GlowPanel.mxml

GradientBevelPanel.mxml

GradientGlowPanel.mxml

Gruppe von MXML-Komponenten mit den Funktionen für die einzelnen Bedienfelder, in denen die Optionen für den jeweiligen Filter festgelegt werden.

flexapp/ImageContainer.as

Ein Anzeigeobjekt, das auf dem Bildschirm als Container für das geladene Bild dient.

flexapp/controls/BGColorCellRenderer.as

Benutzerdefinierte CellRenderer-Klasse zum Ändern der Hintergrundfarbe einer Zelle in der DataGrid-Komponente.

flexapp/controls/QualityComboBox.as

Benutzerdefiniertes Steuerelement, das ein Kombinationsfeld definiert, das für die Qualitätseinstellungen in verschiedenen Filter-Bedienfeldern verwendet werden kann.

flexapp/controls/TypeComboBox.as

Benutzerdefiniertes Steuerelement, das ein Kombinationsfeld definiert, das für die Typeinstellungen in verschiedenen Filter-Bedienfeldern verwendet werden kann.

Benutzeroberfläche (Flash)

FilterWorkbench.fla

Die Hauptdatei für die Benutzeroberfläche der Anwendung.

flashapp/FilterWorkbench.as

Klasse mit den Funktionen für die Benutzeroberfläche der Hauptanwendung. Diese Klasse wird als Dokumentklasse für die FLA-Datei der Anwendung verwendet.

Im Ordner flashapp/filterPanels:

BevelPanel.as

BlurPanel.as

ColorMatrixPanel.as

ConvolutionPanel.as

DropShadowPanel.as

GlowPanel.as

GradientBevelPanel.as

GradientGlowPanel.as

Gruppe von Klassen mit den Funktionen für die einzelnen Bedienfelder, in denen die Optionen für den jeweiligen Filter festgelegt werden.

Jeder Klasse ist in der Bibliothek der FLA-Datei für die Hauptanwendung auch ein MovieClip-Symbol zugeordnet, dessen Name dem Namen der Klasse entspricht (das Symbol „BlurPanel“ ist beispielsweise mit der in „BlurPanel.as“ definierten Klasse verknüpft). Die Komponenten der Benutzeroberfläche werden in diesen Symbolen positioniert und benannt.

flashapp/ImageContainer.as

Ein Anzeigeobjekt, das auf dem Bildschirm als Container für das geladene Bild dient.

flashapp/BGColorCellRenderer.as

Benutzerdefinierte CellRenderer-Klasse zum Ändern der Hintergrundfarbe einer Zelle in der DataGrid-Komponente.

flashapp/ButtonCellRenderer.as

Benutzerdefinierte CellRenderer-Klasse zum Einfügen einer Button-Komponente in eine Zelle der DataGrid-Komponente.

Gefilterter Bildinhalt

com/example/programmingas3/filterWorkbench/ImageType.as

Diese Klasse dient als Wertobjekt und enthält den Typ und die URL einer einzelnen Bilddatei. Für dieses Objekt können in der Anwendung Filter geladen und angewendet werden. Die Klasse enthält auch mehrere Konstanten, die die tatsächlich verfügbaren Bilddateien darstellen.

images/sampleAnimation.swf,

images/sampleImage1.jpg,

images/sampleImage2.jpg

Bilder und andere visuelle Inhalte, auf die in der Anwendung Filter angewendet werden.

Experimentieren mit ActionScript-Filtern

Mithilfe der Anwendung „Filter Workbench“ können Sie verschiedene Filtereffekte testen und den entsprechenden ActionScript-Code für die jeweiligen Effekte erzeugen. In der Anwendung haben Sie die Auswahl zwischen drei verschiedenen Dateien mit grafischem Inhalt, einschließlich Bitmapgrafiken und einer mit Flash erstellten Animation. Zudem können Sie acht verschiedene ActionScript-Filter entweder einzeln oder in Kombination mit anderen Filtern auf das ausgewählte Bild anwenden. Die Anwendung enthält die folgenden Filter:

  • Geschliffen (flash.filters.BevelFilter)

  • Weichzeichnen (flash.filters.BlurFilter)

  • Farbmatrix (flash.filters.ColorMatrixFilter)

  • Convolution (flash.filters.ConvolutionFilter)

  • Schlagschatten (flash.filters.DropShadowFilter)

  • Glühen (flash.filters.GlowFilter)

  • Farbverlauf-Geschliffen (flash.filters.GradientBevelFilter)

  • Farbverlauf-Glühen (flash.filters.GradientGlowFilter)

Wenn ein Benutzer ein Bild und einen auf das Bild anzuwendenden Filter ausgewählt hat, wird ein Bedienfeld mit Steuerelementen angezeigt, über die die spezifischen Eigenschaften des ausgewählten Filters festgelegt werden können. In der folgenden Abbildung ist beispielsweise der Geschliffen-Filter ausgewählt:

Wenn der Benutzer die Filtereigenschaften ändert, wird die Vorschau in Echtzeit aktualisiert. Der Benutzer kann auch mehrere Filter anwenden, indem er einen Filter anpasst, auf die Schaltfläche „Anwenden“ klickt, dann einen anderen Filter anpasst, auf die Schaltfläche „Anwenden“ klickt usw.

Es folgt die Beschreibung einiger Funktionen und Beschränkungen bei einzelnen Bedienfeldern für Filter in der Anwendung:

  • Der Farbmatrixfilter enthält mehrere Steuerelemente zur direkten Bearbeitung allgemeiner Bildeigenschaften, z. B. Helligkeit, Kontraste, Sättigung und Farbton. Zusätzlich können benutzerdefinierte Farbmatrixwerte angegeben werden.

  • Der Convolution-Filter, der nur bei Verwendung von ActionScript verfügbar ist, enthält mehrere häufig verwendete Convolution-Matrixwerte. Zudem können benutzerdefinierte Werte angegeben werden. Zwar kann bei der ConvolutionFilter-Klasse eine Matrix beliebiger Größe verwendet werden, in der Anwendung „Filter Workbench“ wird jedoch eine feste 3x3-Matrix verwendet (die am häufigsten verwendete Filtergröße).

  • Der Verschiebungsmatrixfilter und der Shader-Filter, die nur in ActionScript verfügbar sind, stehen in der Anwendung „Filter Workbench“ nicht zur Verfügung.

Erstellen von Filterinstanzen

Die Anwendung „Filter Workbench“ enthält für jeden der verfügbaren Filter je eine Klasse, die im jeweiligen Bedienfeld zum Erstellen der Filterinstanz verwendet wird. Wenn ein Benutzer einen Filter auswählt, wird mit dem ActionScript-Code, der dem Bedienfeld für den Filter zugeordnet ist, eine Instanz der entsprechenden Factory-Klasse für Filter erstellt. (Diese Klassen werden als Factory-Klassen bezeichnet, da sie zum Erstellen von Instanzen anderer Objekte dienen, ähnlich einer Fabrik (engl. „factory“), in der einzelne Produkte hergestellt werden.)

Bei jeder Änderung eines Eigenschaftswerts im Bedienfeld wird durch den Code des Bedienfelds die entsprechende Methode der Factory-Klasse aufgerufen. Jede Factory-Klasse enthält spezifische Methoden, mit denen im Bedienfeld die entsprechende Filterinstanz erstellt wird. Wenn der Benutzer beispielsweise den Weichzeichnen-Filter auswählt, wird in der Anwendung eine BlurFactory-Instanz erstellt. Die BlurFactory-Klasse enthält eine modifyFilter() -Methode, die drei Parameter akzeptiert: blurX , blurY und quality , die zusammen für die Erstellung der gewünschten BlurFilter-Instanz verwendet werden:

private var _filter:BlurFilter; 
 
public function modifyFilter(blurX:Number = 4, blurY:Number = 4, quality:int = 1):void 
{ 
    _filter = new BlurFilter(blurX, blurY, quality); 
    dispatchEvent(new Event(Event.CHANGE)); 
}

Wenn der Benutzer dagegen den Convolution-Filter auswählt, der eine viel größere Flexibilität zulässt, ist eine größere Anzahl festzulegender Eigenschaften verfügbar. In der ConvolutionFactory-Klasse wird der folgende Code aufgerufen, wenn der Benutzer im Bedienfeld einen anderen Wert auswählt:

private var _filter:ConvolutionFilter; 
 
public function modifyFilter(matrixX:Number = 0,  
                                                matrixY:Number = 0,  
                                                matrix:Array = null,  
                                                divisor:Number = 1.0,  
                                                bias:Number = 0.0,  
                                                preserveAlpha:Boolean = true,  
                                                clamp:Boolean = true,  
                                                color:uint = 0,  
                                                alpha:Number = 0.0):void 
{ 
    _filter = new ConvolutionFilter(matrixX, matrixY, matrix, divisor, bias, preserveAlpha, clamp, color, alpha); 
    dispatchEvent(new Event(Event.CHANGE)); 
}

Bei jeder Änderung der Werte für den Filter löst das Factory-Objekt ein Event.CHANGE -Ereignis aus, um die Listener zu benachrichtigen, dass die Werte des Filters geändert wurden. Die FilterWorkbenchController-Klasse, mit der Filter auf den zu filternden Inhalt angewendet werden, überwacht das Eintreten dieses Ereignisses und ermittelt den Zeitpunkt, zu dem eine neue Kopie des Filters abgerufen und der Filter erneut auf den zu filternden Inhalt angewendet werden muss.

An die FilterWorkbenchController-Klasse müssen nicht die spezifischen Einzelheiten der einzelnen Factory-Klassen für Filter übergeben werden. Es muss lediglich angegeben werden, dass ein Filter geändert wurde, und die Klasse muss auf eine Kopie des Filters zugreifen können. Dazu enthält die Anwendung die IFilterFactory-Schnittstelle, über die das erforderliche Verhalten der Factory-Klassen für Filter definiert wird, sodass die entsprechenden Vorgänge durch die FilterWorkbenchController-Instanz durchgeführt werden können. Die IFilterFactory-Schnittstelle definiert die getFilter() -Methode, die in der FilterWorkbenchController-Klasse verwendet wird:

function getFilter():BitmapFilter;

Beachten Sie, dass in der Definition der getFilter() -Methode angegeben ist, dass kein bestimmter Filtertyp, sondern eine BitmapFilter-Instanz zurückgegeben wird. Mit der BitmapFilter-Klasse wird kein bestimmter Filtertyp definiert. Bei der BitmapFilter-Klasse handelt es sich vielmehr um die Basisklasse, die allen Filterklassen zugrunde liegt. Jede Factory-Klasse für Filter definiert eine spezifische Implementierung der getFilter() -Methode, in der ein Verweis auf das durch die Klasse erstellte Filterobjekt zurückgegeben wird. Es folgt der Quellcode der ConvolutionFactory-Klasse in gekürzter Form:

public class ConvolutionFactory extends EventDispatcher implements IFilterFactory 
{ 
    // ------- Private vars ------- 
    private var _filter:ConvolutionFilter; 
    ... 
    // ------- IFilterFactory implementation ------- 
    public function getFilter():BitmapFilter 
    { 
        return _filter; 
    } 
    ... 
}

In der Implementierung der getFilter() -Methode durch die ConvolutionFactory-Klasse wird eine ConvolutionFilter-Instanz zurückgegeben, auch wenn dieser Instanztyp für Objekte, die getFilter() aufrufen, u. U. unbekannt ist. Entsprechend der Definition der getFilter() -Methode durch die ConvolutionFactory-Klasse kann eine beliebige BitmapFilter-Instanz zurückgegeben werden, die eine Instanz einer der ActionScript-Filterklassen ist.

Anwenden von Filtern auf Anzeigeobjekte

Wie bereits erläutert wurde, wird in der Anwendung „Filter Workbench“ eine Instanz der FilterWorkbenchController-Klasse (im Folgenden als „Controller-Instanz“ bezeichnet) verwendet, um Filter auf das ausgewählte Anzeigeobjekt anzuwenden. Damit über die Controller-Instanz Filter angewendet werden können, muss zunächst festgelegt werden, auf welches Bild oder welchen grafischen Inhalt der entsprechende Filter angewendet werden soll. Wenn der Benutzer ein Bild auswählt, wird in der Anwendung die setFilterTarget() -Methode der FilterWorkbenchController-Klasse aufgerufen und eine der in der ImageType-Klasse definierten Konstanten übergeben:

public function setFilterTarget(targetType:ImageType):void 
{ 
    ... 
    _loader = new Loader(); 
    ... 
    _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, targetLoadComplete); 
    ... 
}

Anhand dieser Informationen wird die angegebene Datei durch die Controller-Instanz geladen und nach dem Laden in der Instanzvariable _currentTarget gespeichert:

private var _currentTarget:DisplayObject; 
 
private function targetLoadComplete(event:Event):void 
{ 
    ... 
    _currentTarget = _loader.content; 
    ... 
}

Wenn der Benutzer einen Filter auswählt, wird die setFilter() -Methode der Controller-Instanz mit einem Verweis auf das relevante Factory-Objekt für Filter aufgerufen, das dann in der Instanzvariable _filterFactory gespeichert wird.

private var _filterFactory:IFilterFactory; 
 
public function setFilter(factory:IFilterFactory):void 
{ 
    ... 
     
    _filterFactory = factory; 
    _filterFactory.addEventListener(Event.CHANGE, filterChange); 
}

Wie zuvor beschrieben, erkennt die Controller-Instanz den spezifischen Datentyp der angegebenen Factory-Instanz für Filter nicht. Sie erkennt lediglich, dass das Objekt die IFilterFactory-Instanz implementiert, d. h., dass sie über eine getFilter() -Methode verfügt und ein change -Ereignis ( Event.CHANGE ) auslöst, wenn der Filter geändert wird.

Wenn der Benutzer die Eigenschaften eines Filters im Bedienfeld für den Filter ändert, erkennt die Controller-Instanz die Änderung des Filters durch das change -Ereignis der Factory-Klasse für Filter, bei dem die filterChange() -Methode der Controller-Instanz aufgerufen wird. Diese Methode ruft wiederum die applyTemporaryFilter() -Methode auf:

private function filterChange(event:Event):void 
{ 
    applyTemporaryFilter(); 
} 
 
private function applyTemporaryFilter():void 
{ 
    var currentFilter:BitmapFilter = _filterFactory.getFilter(); 
     
    // Add the current filter to the set temporarily 
    _currentFilters.push(currentFilter); 
     
    // Refresh the filter set of the filter target 
    _currentTarget.filters = _currentFilters; 
     
    // Remove the current filter from the set 
    // (This doesn't remove it from the filter target, since  
    // the target uses a copy of the filters array internally.) 
    _currentFilters.pop(); 
}

Das Anwenden des Filters auf das Anzeigeobjekt erfolgt in der applyTemporaryFilter() -Methode. Die Controller-Instanz ruft zunächst einen Verweis auf das Filterobjekt ab, indem sie die getFilter() -Methode der Factory-Klasse für Filter aufruft.

var currentFilter:BitmapFilter = _filterFactory.getFilter();

Die Controller-Instanz verfügt über die Array-Instanzvariable _currentFilters , in der alle Filter gespeichert sind, die auf das Anzeigeobjekt angewendet wurden. Der neu aktualisierte Filter wird dann diesem Array hinzugefügt:

_currentFilters.push(currentFilter);

Anschließend wird das Filter-Array der filters -Eigenschaft des Anzeigeobjekts zugewiesen, mit der die Filter dann auf das Bild angewendet werden:

_currentTarget.filters = _currentFilters;

Da der zuletzt hinzugefügte Filter bis zum endgültigen Anwenden nur getestet wird, darf er nicht dauerhaft auf das Anzeigeobjekt angewendet werden. Deshalb wird er wieder aus dem _currentFilters -Array entfernt:

_currentFilters.pop();

Das Entfernen des Filters aus dem Array wirkt sich nicht auf das gefilterte Anzeigeobjekt aus, da im Anzeigeobjekt eine Kopie des Filter-Arrays erstellt wird, wenn es der filters -Eigenschaft zugewiesen wird. Dieses interne Array wird dann anstelle des Original-Arrays verwendet. Aus diesem Grund wirken sich Änderungen, die am Filter-Array vorgenommen werden, nur dann auf das Anzeigeobjekt aus, wenn das Array erneut der filters -Eigenschaft des Anzeigeobjekts zugewiesen wird.