Voorbeeld van het filteren van weergaveobjecten: Filter Workbench

Flash Player 9 of hoger, Adobe AIR 1.0 of hoger

De Filter Workbench biedt een gebruikersinterface voor het toepassen van verschillende filters op afbeeldingen en overige zichtbare inhoud en voor het weergeven van de resulterende code die kan worden gebruikt om hetzelfde effect te genereren in ActionScript. Naast gereedschap voor het experimenteren met filters, biedt deze toepassing de volgende technieken:

  • Instanties maken van diverse filters

  • Meerdere filters toepassen op een weergaveobject

Zie www.adobe.com/go/learn_programmingAS3samples_flash_nl als u de toepassingsbestanden voor dit voorbeeld wilt downloaden. U vindt de toepassingsbestanden van Filter Workbench in de map Samples/FilterWorkbench. De toepassing bestaat uit de volgende bestanden:

Bestand

Beschrijving

com/example/programmingas3/filterWorkbench/FilterWorkbenchController.as

Klasse die de hoofdfunctionaliteit van de toepassing biedt, inclusief schakelen tussen inhoud waarop filters worden toegepast en het toepassen van filters op inhoud.

com/example/programmingas3/filterWorkbench/IFilterFactory.as

Interface die de algemene methoden definieert die worden geïmplementeerd door elke filterfabrieksklassen. Deze interface definieert de algemene functionaliteit die de klasse FilterWorkbenchController gebruikt om te communiceren met de afzonderlijke filterfabrieksklassen.

In map com/example/programmingas3/filterWorkbench/:

BevelFactory.as

BlurFactory.as

ColorMatrixFactory.as

ConvolutionFactory.as

DropShadowFactory.as

GlowFactory.as

GradientBevelFactory.as

GradientGlowFactory.as

Set klassen, die elk de interface IFilterFactory implementeert. Elk van deze klassen biedt de functionaliteit voor het maken en instellen van waarden voor een enkel type filter. De filtereigenschapdeelvensters in de toepassing gebruiken deze fabrieksklassen om instanties van hun specifieke filters te maken, die de klasse FilterWorkbenchController ophaalt en op de afbeeldingsinhoud toepast.

com/example/programmingas3/filterWorkbench/IFilterPanel.as

Interface waarin algemene methoden worden gedefinieerd die worden geïmplementeerd door klassen die de deelvensters van de gebruikersinterface definiëren die worden gebruikt om filterwaarden in de toepassing te bewerken.

com/example/programmingas3/filterWorkbench/ColorStringFormatter.as

Hulpprogrammaklasse die een methode bevat om een numerieke kleurwaarde om te zetten in een hexadecimale tekenreeksindeling.

com/example/programmingas3/filterWorkbench/GradientColor.as

Klasse die als waardeobject fungeert; deze maakt één enkel object van de drie waarden (kleur, alfa en verhouding) die zijn gekoppeld aan elke kleur in GradientBevelFilter en GradientGlowFilter.

Gebruikersinterface (Flex)

FilterWorkbench.mxml

Het hoofdbestand dat de gebruikersinterface van de toepassing definieert.

flexapp/FilterWorkbench.as

Klasse die de functionaliteit biedt voor de gebruikersinterface van de hoofdtoepassing; deze klasse wordt gebruikt als code-achtergrondklasse voor het MXML-toepassingsbestand.

In map flexapp/filterPanels:

BevelPanel.mxml

BlurPanel.mxml

ColorMatrixPanel.mxml

ConvolutionPanel.mxml

DropShadowPanel.mxml

GlowPanel.mxml

GradientBevelPanel.mxml

GradientGlowPanel.mxml

Set MXML-componenten die de functionaliteit biedt voor elk deelvenster dat wordt gebruikt om opties in te stellen voor een enkel filter.

flexapp/ImageContainer.as

Een weergaveobject dat fungeert als container voor de geladen afbeelding op het scherm.

flexapp/controls/BGColorCellRenderer.as

Aangepaste celrenderer die wordt gebruikt om de achtergrondkleur van een cel in de component DataGrid te wijzigen.

flexapp/controls/QualityComboBox.as

Aangepast besturingselement dat een keuzelijst definieert die kan worden gebruikt voor de instelling Quality in verschillende filterdeelvensters.

flexapp/controls/TypeComboBox.as

Aangepast besturingselement dat een keuzelijst definieert die kan worden gebruikt voor de instelling Type in verschillende filterdeelvensters.

Gebruikersinterface (Flash)

FilterWorkbench.fla

Het hoofdbestand dat de gebruikersinterface van de toepassing definieert.

flashapp/FilterWorkbench.as

Klasse die de functionaliteit biedt voor de gebruikersinterface van de hoofdtoepassing; deze klasse wordt gebruikt als documentklasse voor het FLA-toepassingsbestand.

In map flashapp/filterPanels:

BevelPanel.as

BlurPanel.as

ColorMatrixPanel.as

ConvolutionPanel.as

DropShadowPanel.as

GlowPanel.as

GradientBevelPanel.as

GradientGlowPanel.as

Set klassen die de functionaliteit biedt voor elk deelvenster dat wordt gebruikt om opties in te stellen voor een enkel filter.

Voor elke klasse bestaat er ook een gekoppeld filmclipsymbool in de bibliotheek van het FLA-hoofdtoepassingsbestand, waarvan de naam overeenkomt met de naam van de klasse (het symbool BlurPanel is bijvoorbeeld gekoppeld aan de klasse die is gedefinieerd in BlurPanel.as). De componenten die de gebruikersinterface vormen, worden gepositioneerd en benoemd binnen deze symbolen.

flashapp/ImageContainer.as

Een weergaveobject dat fungeert als container voor de geladen afbeelding op het scherm.

flashapp/BGColorCellRenderer.as

Aangepaste celrenderer die wordt gebruikt om de achtergrondkleur van een cel in de component DataGrid te wijzigen.

flashapp/ButtonCellRenderer.as

Aangepaste celrenderer die wordt gebruikt om een component Button op te nemen in een cel in de component DataGrid.

Gefilterde afbeeldingsinhoud

com/example/programmingas3/filterWorkbench/ImageType.as

Deze klasse fungeert als een waardeobject dat het type en de URL bevat van een enkel afbeeldingsbestand waarnaar de toepassing filters kan laden en toepassen. De klasse bevat tevens een set constanten die de werkelijk beschikbare afbeeldingsbestanden vertegenwoordigt.

images/sampleAnimation.swf

images/sampleImage1.jpg

images/sampleImage2.jpg

Afbeeldingen en overige zichtbare inhoud waarop filters worden toegepast in de toepassing.

Experimenteren met ActionScript-filters

De toepassing Filter Workbench is ontworpen om u te helpen experimenteren met diverse filtereffecten en het genereren van de relevante ActionScript-code voor die effecten. U kunt kiezen uit drie verschillende bestanden met zichtbare inhoud (inclusief bitmapafbeeldingen en een animatie die met Flash is gemaakt) en u kunt acht verschillende ActionScript-filters toepassen op de geselecteerde afbeelding, zowel afzonderlijk als in combinatie met andere filters. De toepassing bevat de volgende filters:

  • Schuine-kantfilter (flash.filters.BevelFilter)

  • Vervagend filter (flash.filters.BlurFilter)

  • Kleurenmatrixfilter (flash.filters.ColorMatrixFilter)

  • Convolutiefilter (flash.filters.ConvolutionFilter)

  • Slagschaduwfilter (flash.filters.DropShadowFilter)

  • Gloedfilter (flash.filters.GlowFilter)

  • Verlopende schuine-kantfilter (flash.filters.GradientBevelFilter)

  • Verlopende-gloedfilter (flash.filters.GradientGlowFilter)

Zodra een gebruiker een afbeelding heeft geselecteerd en een filter op die afbeelding heeft toegepast, wordt een deelvenster met besturingselementen weergegeven voor het instellen van de specifieke eigenschappen van het geselecteerde filter. De volgende afbeelding toont bijvoorbeeld de toepassing met een geselecteerd schuine-kantfilter:

Terwijl de gebruiker de filtereigenschappen aanpast, wordt de voorvertoning realtime bijgewerkt. De gebruiker kan ook meerdere filters toepassen door een filter aan te passen, te klikken op de knop Apply filter and add another, een volgend filter aan te passen, nogmaals op de knop Apply filter and add another te klikken enzovoort.

De filterdeelvensters van de toepassing bevatten een aantal functies en beperkingen:

  • Het kleurenmatrixfilter bevat een set besturingselementen voor het rechtstreeks manipuleren van algemene afbeeldingseigenschappen, zoals helderheid, contrast, verzadiging en kleurtoon. Bovendien kunnen aangepaste kleurenmatrixwaarden worden opgegeven.

  • Het convolutiefilter, dat alleen beschikbaar is in ActionScript, bevat een set veelgebruikte convolutiematrixwaarden, maar er kunnen ook aangepaste waarden worden opgegeven. De klasse ConvolutionFilter accepteert een matrix met willekeurige grootte, maar de toepassing Filter Workbench gebruikt standaard een matrix van 3 x 3, de meestgebruikte filtergrootte.

  • Het verschuivingskaartfilter en het arceringsfilter, alleen beschikbaar in ActionScript, zijn niet beschikbaar in de toepassing Filter Workbench.

Filterinstanties maken

De toepassing Filter Workbench bevat een set klassen, één voor elk van de beschikbare filters, die worden gebruikt door de afzonderlijke deelvensters om de filters te maken. Wanneer een gebruiker een filter selecteert, maakt de ActionScript-code die is gekoppeld aan het filterdeelvenster een instantie van de juiste filterfabrieksklasse. (Deze klassen staan bekend als fabrieksklassen omdat zij instanties van andere objecten maken, zoals een fabriek afzonderlijke producten maakt.)

Op het moment dat de gebruiker een eigenschapwaarde in het deelvenster wijzigt, wordt aan de hand van de code van het deelvenster de juiste methode in de fabrieksklasse aangeroepen. Elke fabrieksklasse bevat specifieke methoden die het deelvenster gebruikt om de juiste filterinstantie te maken. Wanneer de gebruiker bijvoorbeeld het vervagende filter selecteert, maakt de toepassing een instantie van BlurFactory. De klasse BlurFactory bevat een methode modifyFilter() die drie parameters accepteert: blurX, blurY en quality, die tezamen worden gebruikt om de gewenste instantie BlurFilter te maken:

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

Wanneer de gebruiker daarentegen het convolutiefilter selecteert, heeft de gebruiker meer flexibiliteit ter beschikking en dus een grotere set eigenschappen om te beheren. In de klasse ConvolutionFactory wordt de volgende code aangeroepen wanneer de gebruiker een andere waarde in het filterdeelvenster selecteert:

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

Telkens wanneer de filterwaarden worden gewijzigd, verzendt het fabrieksobject een gebeurtenis Event.CHANGE om aan listeners te melden dat de waarden van het filter zijn gewijzigd. De klasse FilterWorkbenchController, die de filters werkelijk op de gefilterde inhoud toepast, luistert naar die gebeurtenis om te bepalen wanneer deze een nieuwe kopie van het filter moet ophalen en opnieuw op de gefilterde inhoud moet toepassen.

De klasse FilterWorkbenchController hoeft geen specifieke details van elke filterfabrieksklasse te weten, maar moet wel weten dat het filter is gewijzigd en moet een kopie van het filter kunnen benaderen. Hiertoe bevat de toepassing een interface, IFilterFactory, die het gedrag definieert dat een filterfabrieksklasse moet bieden zodat de instantie FilterWorkbenchController van de toepassing correct kan functioneren. IFilterFactory definieert de methode getFilter() die wordt gebruikt in de klasse FilterWorkbenchController:

function getFilter():BitmapFilter;

De interfacemethodedefinitie getFilter() geeft op dat een instantie BitmapFilter moet worden geretourneerd in plaats van een specifiek type filter. De klasse BitmapFilter definieert geen specifiek type filter. In plaats daarvan is BitmapFilter de basisklasse voor alle filterklassen. Elke filterfabrieksklasse definieert een specifieke implementatie van de methode getFilter() waarin een verwijzing wordt geretourneerd naar het filterobject dat is gebouwd. Hier ziet u bijvoorbeeld een verkorte versie van de broncode van de klasse ConvolutionFactory:

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

In de implementatie van de klasse ConvolutionFactory van de methode getFilter() wordt een instantie ConvolutionFilter geretourneerd, hoewel elk object dat getFilter() aanroept niet noodzakelijkerwijs hoeft te weten dat (volgens de definitie van de methode getFilter() waarnaar ConvolutionFactory handelt) een instantie BitmapFilter moet worden geretourneerd, waarbij het niet uitmaakt van welke ActionScript-filterklasse deze afkomstig is.

Filters toepassen op weergaveobjecten

Zoals is beschreven in de vorige sectie, gebruikt de toepassing Filter Workbench een instantie van de klasse FilterWorkbenchController (waarnaar verder wordt verwezen als de ‘bedieningsinstantie’), die de filters daadwerkelijk op het geselecteerde zichtbare object toepast. Voordat de bedieningsinstantie een filter kan toepassen, moet deze eerst weten op welke afbeelding of zichtbare inhoud het filter moet worden toegepast. Wanneer de gebruiker een afbeelding selecteert, roept de toepassing de methode setFilterTarget() in de klasse FilterWorkbenchController aan, waarbij één van de constanten wordt doorgegeven die in de klasse ImageType is gedefinieerd:

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

Met behulp van die informatie laadt de bedieningsinstantie het opgegeven bestand en slaat dit op in een instantievariabele met de naam _currentTarget zodra het is geladen:

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

Wanneer de gebruiker een filter selecteert, roept de toepassing de methode setFilter() van de bedieningsinstantie aan en geeft hierbij een verwijzing aan de bedieningsinstantie door naar het relevante filterfabrieksobject, die het opslaat in een instantievariabele met de naam _filterFactory.

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

Zoals eerder beschreven, weet de bedieningsinstantie niet wat het specifieke gegevenstype is van de filterfabrieksinstantie die eraan wordt gegeven; de instantie weet alleen dat het object de instantie IFilterFactory implementeert, met andere woorden, het heeft een methode getFilter() en verzendt een gebeurtenis change (Event.CHANGE) wanneer het filter wordt gewijzigd.

Wanneer de gebruiker de eigenschappen van een filter wijzigt in het filterdeelvenster, ziet de bedieningsinstantie dat het filter is gewijzigd via de filterfabrieksgebeurtenis change, die de methode filterChange() van de bedieningsinstantie aanroept. Die methode roept vervolgens de methode applyTemporaryFilter() aan:

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

Het toepassen van het filter op het weergaveobject gebeurt binnen de methode applyTemporaryFilter(). De bedieningsinstantie haalt eerst een verwijzing op naar het filterobject door de filterfabrieksmethode getFilter() aan te roepen.

var currentFilter:BitmapFilter = _filterFactory.getFilter();

De bedieningsinstantie bevat een instantievariabele Array met de naam _currentFilters, waarin deze alle filters opslaat die op het weergaveobject zijn toegepast. De volgende stap bestaat uit het toevoegen van het recent bijgewerkte filter aan die array:

_currentFilters.push(currentFilter);

Vervolgens wijst de code de array van filters toe aan de eigenschap filters van het weergaveobject, die de filters daadwerkelijk op de afbeelding toepast:

_currentTarget.filters = _currentFilters;

Ten slotte, omdat het laatst toegevoegde filter nog steeds het ‘werkende’ filter is, moet het niet permanent worden toegepast op het weergaveobject, daarom wordt het verwijderd uit de array _currentFilters:

_currentFilters.pop();

Het verwijderen van dit filter uit de array heeft geen effect op het gefilterde weergaveobject, omdat een weergaveobject een kopie maakt van de array filters wanneer deze wordt toegewezen aan de eigenschap filters en het gebruikt die interne array in plaats van de oorspronkelijke array. Daarom hebben wijzigingen in de array van filters geen effect op het weergaveobject totdat de array nogmaals wordt toegewezen aan de eigenschap filters van het weergaveobject.