Filtreler oluşturma ve uygulama

Flash Player 9 ve üstü, Adobe AIR 1.0 ve üstü

Filtreler, bitmap ve görüntüleme nesnelerine, gölge, eğim ve bulanıklaştırma gibi çeşitli efektler uygulamanıza olanak sağlar. Her filtre bir sınıf olarak tanımlanır, bu nedenle filtre uygulanması kapsamında filtre nesnelerinin örnekleri oluşturulur; bu işlem herhangi bir nesne oluşturulmasından farklı değildir. Filtre nesnesinin bir örneği oluşturulduktan sonra, nesnenin filters özelliği kullanılarak veya BitmapData nesnesi olması durumunda applyFilter() yöntemi kullanılarak bu kolayca bir görüntüleme nesnesine uygulanabilir.

Filtre oluşturma

Bir filtre nesnesi oluşturmak için, seçtiğiniz filtre sınıfınızın yapıcı yöntemini çağırmanız yeterlidir. Örneğin, bir DropShadowFilter nesnesi oluşturmak için şu kodu kullanın:

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

Burada gösterilmese de, DropShadowFilter() yapıcısı (filtre sınıfının diğer tüm yapıcıları gibi), filtre efektinin görünümünü özelleştirmek için kullanılabilen birçok isteğe bağlı parametreyi kabul eder.

Filtre uygulama

Bir filtre nesnesi oluşturduktan sonra, bunu bir görüntüleme nesnesine veya BitmapData nesnesine uygulayabilirsiniz; filtreyi uygulama şekliniz, filtreyi uyguladığınız nesneye bağlıdır.

Görüntüleme nesnesine filtre uygulama

Bir görüntüleme nesnesine filtre efektleri uyguladığınızda, bunları filters özelliği üzerinden uygularsınız. Görüntüleme nesnesinin filters özelliği, özellikleri, görüntüleme nesnesine uygulanan filtre nesneleri olan bir Array örneğidir. Bir görüntüleme nesnesine tek bir filtre uygulamak için, filtre örneğini oluşturun, bir Array örneğine ekleyin ve bu Array nesnesini görüntüleme nesnesinin filters özelliğine atayın:

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;

Nesneye birden çok filtre atamak istiyorsanız, Array örneğini filters özelliğine atamadan önce filtrelerin tümünü Array örneğine ekleyin. Nesneleri Array öğesinin yapıcısına parametreler olarak ileterek birden çok nesneyi Array öğesine ekleyebilirsiniz. Örneğin, bu kod, bir önceki oluşturulan görüntüleme nesnesine bir eğim filtresi ve ışıma filtresi uygular:

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;

Filtreleri içeren dizi oluştururken, new Array() yapıcısını kullanarak (önceki örneklerde gösterildiği gibi) diziyi oluşturabilir veya Array değişmez sözdizimini kullanarak filtreleri köşeli ayraçlar ([]) içine sarabilirsiniz. Örneğin, bu kod satırı:

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

bu kod satırıyla aynı şeyi yapar:

var filters:Array = [dropShadow, blur];

Görüntüleme nesnelerine birden çok filtre uygularsanız, bunlar birikimli olarak art arda uygulanır. Örneğin, bir filtreler dizisi iki öğe içeriyorsa ve ilk olarak bir eğim filtresi eklenip ikinci olarak bir gölge filtresi eklenirse, gölge filtresi hem eğim filtresine hem de görüntüleme nesnesine uygulanır. Bu, gölge filtresinin filtreler dizisindeki ikinci konumundan kaynaklanır. Filtreleri birikimli şekilde uygulamak istemiyorsanız, her filtreyi, görüntüleme nesnesinin yeni bir kopyasına uygulayın.

Bir görüntüleme nesnesine yalnızca bir filtre veya birkaç filtre atıyorsanız, tek bir deyimde filtre örneğini oluşturabilir ve nesneye atayabilirsiniz. Örneğin, şu kod satırı, myDisplayObject adındaki bir görüntüleme nesnesine bulanıklaştırma filtresi uygular:

myDisplayObject.filters = [new BlurFilter()];

Önceki kod, Array değişmez sözdizimini (köşeli ayraçlar) kullanarak bir Array örneği oluşturur, Array öğesinde bir öğe olarak yeni bir BlurFilter örneği oluşturur ve bu Array öğesini myDisplayObject adındaki görüntüleme nesnesinin filters özelliğine atar.

Görüntüleme nesnesinden filtreleri kaldırma

Bir görüntüleme nesnesindeki tüm filtrelerin kaldırılması, filters özelliğine null değeri atanması kadar kolaydır:

myDisplayObject.filters = null;

Bir nesneye birden çok filtre uyguladıysanız ve filtrelerden yalnızca birini kaldırmak istiyorsanız, filters özelliği dizisini değiştirmek için birçok adım uygulamanız gerekir. Daha fazla bilgi için, bkz. Filtrelerle çalışırken karşılaşılabilecek sorunlar.

BitmapData nesnesine filtre uygulama

Bir BitmapData nesnesine filtre uygulanması için, BitmapData nesnesinin applyFilter() yönteminin kullanılması gerekir:

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

applyFilter() yöntemi, kaynak BitmapData nesnesine bir filtre uygulayarak yeni ve filtre uygulanmış bir görüntü oluşturur. Bu yöntem, orijinal kaynak görüntüyü değiştirmez; kaynak görüntüye uygulanan filtrenin sonucu, applyFilter() yönteminin çağrıldığı BitmapData örneğinde saklanır.

Filtreler nasıl çalışır

Görüntüleme nesnesine filtre uygulama, orijinal nesnenin bir kopyasının saydam bitmap olarak önbelleğe alınmasıyla gerçekleşir.

Görüntüleme nesnesine filtre uygulandıktan sonra, nesne geçerli bir filtre listesine sahip olduğu sürece, çalışma zamanı nesneyi bitmap olarak önbelleğe alır. Ardından kaynak bitmap, sonradan uygulanan filtre efektlerinin tümü için orijinal görüntü olarak kullanılır.

Her görüntüleme nesnesi genellikle iki bitmap içerir: biri orijinal filtre uygulanmamış kaynak görüntüleme nesnesi ile ve diğeri filtre uygulamanın ardından elde edilen son görüntü için. Son görüntü, oluşturma sırasında kullanılır. Görüntüleme nesnesi değişmediği sürece, son görüntünün güncellenmesi gerekmez.

Filtrelerle çalışırken karşılaşılabilecek sorunlar

Filtrelerle çalışırken dikkate almanız gereken birkaç kafa karıştırıcı veya sorun çıkarıcı nokta vardır.

Filtreler ve bitmap önbelleğe alma

Görüntüleme nesnesine bir filtre uygulamak üzere, o nesne için bitmap önbelleğe almanın etkinleştirilmesi gerekir. cacheAsBitmap özelliği false değerine ayarlanmış olan bir görüntüleme nesnesine bir filtre uyguladığınızda, nesnenin cacheAsBitmap özelliği otomatik olarak true olur. Daha sonra görüntüleme nesnesinden tüm filtreleri kaldırırsanız, cacheAsBitmap özelliği daha önce ayarlandığı değere döndürülür.

Çalışma zamanında filtreleri değiştirme

Bir görüntüleme nesnesi önceden kendisine uygulanmış bir veya birkaç filtreye sahipse, filters özellik dizisine ek filtreler ekleyerek veya bu özellik dizisinden filtreleri kaldırarak filtre kümesini değiştiremezsiniz. Bunun yerine, uygulanan filtre kümesine ekleme yapmak veya bu filtre kümesini değiştirmek için, ayrı bir dizi üzerinde kendi değişikliklerinizi yapmanız ve daha sonra bu diziyi, nesneye uygulanacak filtrelerin görüntüleme nesnesinin filters özelliğine atamanız gerekir. Bunu yapmanın en kolay yolu, filters özellik dizisini bir Array değişkenine okumak ve bu geçici dizi üzerinde değişikliklerinizi yapmaktır. Bu diziyi daha sonra görüntüleme nesnesinin filters özelliğine yeniden atayabilirsiniz. Daha karmaşık durumlarda, ayrı bir ana filtre dizisi tutmanız gerekebilir. Bu ana filtre dizisi üzerinde değişikliklerinizi yapar ve her değişiklikten sonra ana diziyi görüntüleme nesnesinin filters özelliğine yeniden atarsınız.

Ek filtre ekleme

Aşağıdaki kod, önceden kendisine bir veya birkaç filtre uygulanmış bir görüntüleme nesnesine ek bir filtre ekleme işlemini göstermektedir. İlk olarak, myDisplayObject adındaki görüntüleme nesnesine bir ışıma filtresi uygulanır; daha sonra görüntüleme nesnesi tıklatıldığında, addFilters() işlevi çağrılır. Bu işlevde, myDisplayObject öğesine iki ek filtre uygulanır:

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

Filtreler kümesinden tek bir filtreyi kaldırma

Bir görüntüleme nesnesine birden çok filtre uygulanmışsa ve tek bir filtreyi kaldırırken diğer filtrelerin nesneye uygulanmaya devam etmesini istiyorsanız, filtreleri geçici bir diziye kopyalarsınız, o diziden istenmeyen filtreyi kaldırırsınız ve geçici diziyi görüntüleme nesnesinin filters özelliğine yeniden atarsınız. Herhangi bir diziden bir veya birkaç öğenin kaldırılmasına yönelik birkaç yöntem Değerleri alma ve dizi öğelerini kaldırma bölümünde açıklanmaktadır.

En basit yol, nesnede en üstte bulunan filtrenin (nesneye en son uygulanan filtrenin) kaldırılmasıdır. Diziden filtreyi kaldırmak için Array sınıfının pop() yöntemini kullanırsınız:

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

Aynı şekilde, en alttaki filtreyi (nesneye ilk uygulanan filtreyi) kaldırmak için de aynı kodu kullanırsınız, böylece pop() yönteminin yerine Array sınıfının shift() yöntemini getirirsiniz.

Filtreler dizisinin ortasından bir filtreyi kaldırmak için (dizide ikiden fazla filtre olduğu varsayılarak), splice() yöntemini kullanmanız gerekir. Kaldırmak istediğiniz filtrenin dizinini (dizideki konumunu) bilmeniz gerekir. Örneğin, aşağıdaki kod, görüntüleme nesnesinden ikinci filtreyi (dizin 1'deki filtreyi) kaldırır:

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

Filtrenin dizinini belirleme

Filtrenin dizinini bilmeniz için, diziden hangi filtreyi kaldırmak istediğinizi bilmeniz gerekir. Kaldırılacak filtrenin dizinini bilmeniz (uygulamanın tasarlanma yolundan) veya hesaplamanız gerekir.

En iyisi, kaldırmak istediğiniz filtre her zaman filtre kümesinde aynı konumda olacak şekilde uygulamanızı tasarlamaktır. Örneğin, evrişim filtresi ve gölge filtresi uygulanmış (bu sırayla) tek bir görüntüleme nesneniz varsa ve gölge filtresini kaldırmak ancak evrişim filtresini tutmak istiyorsanız, filtre bilinen bir konumda (filtrenin en üstünde) olduğundan, hangi Array yönteminin kullanılacağını (bu durumda gölge filtresini kaldırmak için Array.pop()) önceden bilebilirsiniz.

Kaldırmak istediğiniz filtre her zaman belirli bir türde olup mutlaka filtre kümesinde aynı konumda değilse, hangisinin kaldırılacağını belirlemek için dizide her filtrenin veri türünü kontrol edebilirsiniz. Örneğin, aşağıdaki kod hangi filtre kümesinin ışıma filtresi olduğunu belirler ve bu filtreyi kümeden kaldırır.

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

Daha karmaşık bir durumda (örneğin, kaldırılacak filtre çalışma zamanında seçilirse), en iyisi, ana filtre listesi görevi görecek ayrı ve kalıcı bir filtre dizisi kopyasının saklanmasıdır. Filtre kümesi üzerinde herhangi bir değişiklik yaptığınızda, ana listeyi değiştirin, sonra bu filtre dizisini, görüntüleme nesnesinin filters özelliği olarak uygulayın.

Örneğin, aşağıdaki kod listesinde, farklı görsel efektler oluşturmak için görüntü nesnesine birden çok evrişim filtresi uygulanır ve uygulamanın ilerleyen bir noktasında bu filtrelerden biri kaldırılırken diğerleri saklanır. Bu durumda kod, filtreler dizisinin ana kopyasını ve kaldırılacak filtreye başvuruyu saklar. Belirli bir filtrenin bulunup kaldırılması, önceki yaklaşıma benzer, tek farkı filtreler dizisinin geçici bir kopyasının yapılması yerine ana kopyanın işlenmesi ve sonra görüntüleme nesnesine uygulanmasıdır.

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

Bu yaklaşımda (hangi filtrenin kaldırılacağını belirlemek için, saklanan filtre başvurusunu, filtreler dizisindeki öğelerle karşılaştırdığınızda), filtreler dizisinin ayrı bir kopyasını tutmanız gerekir—saklanan filtre başvurusunu, görüntüleme nesnesinin filters özelliğinden kopyalanmış geçici bir dizideki öğelerle karşılaştırırsanız, kod çalışmaz. Bunun nedeni, filters özelliğine bir dizi atadığınızda dahili olarak çalışma zamanının dizideki her filtre nesnesinin bir kopyasını oluşturmasıdır. Görüntüleme nesnesine bu kopyalar (orijinal nesneler değil) uygulanır ve filters özelliğini geçici bir diziye okuduğunuzda, geçici dizi, orijinal filtre nesnelerine başvuruları değil, kopyalanan filtre nesnelerine başvuruları içerir. Sonuç olarak, önceki örnekte, filterToRemove öğesinin dizinini geçici filtreler dizisindeki filtrelerle karşılaştırarak belirlemeyi denerseniz herhangi bir eşleşme bulunmaz.

Filtreler ve nesne dönüştürmeleri

Vuruşun algılanması (bir örneğin başka bir örnekle örtüşmesinin veya kesişmesinin belirlenmesi) amacıyla, görüntüleme nesnesinin sınırlama kutusu dikdörtgeninin dışında kalan filtre uygulanmış hiçbir bölge (örneğin, gölge), yüzeyin bir bölümü olarak değerlendirilmez. DisplayObject sınıfının vuruş algılama yöntemleri vektör tabanlı olduğundan, bitmap sonucu üzerinde vuruş algılaması gerçekleştiremezsiniz. Örneğin, bir düğme örneğine eğim filtresi uygularsanız, örneğin eğim uygulanmış kısmında vuruş algılama kullanılamaz.

Ölçekleme, döndürme ve eğme, filtreler tarafından desteklenmez; filtre uygulanmış görüntüleme nesnesi ölçeklenirse (scaleX ve scaleY %100 olmazsa), filtre efekti, örnekle ölçeklenmez. Başka bir deyişle, örneğin orijinal şekli döner, ölçeklenir veya eğrilir ancak filtre örnekle birlikte dönmez, ölçeklenmez veya eğrilmez.

Gerçekçi efektler oluşturmak için, filtre içeren bir örneğe animasyon uygulayabilirsiniz veya örnekleri yuvalayabilir ve bu efekti elde etmek üzere filtrelere animasyon uygulamak için BitmapData sınıfını kullanabilirsiniz.

Filtreler ve Bitmap nesneleri

Bir BitmapData nesnesine herhangi bir filtre uyguladığınızda, cacheAsBitmap özelliği otomatik olarak true değerine ayarlanır. Bu şekilde, orijinal nesneye değil, nesnenin kopyasına filtre gerçekten uygulanır.

Daha sonra bu kopya, olabildiğince en yakın pikselle ana görüntüye (orijinal nesnenin üzerine) yerleştirilir. Orijinal bitmap'in sınırları değişirse, filtre uygulanan kopya bitmap, uzatılmak veya deforme edilmek yerine, yeniden orijinalden oluşturulur.

Görüntüleme nesnesinin tüm filtrelerini temizlerseniz, cacheAsBitmap özelliği, filtre uygulanmadan önce bulunduğu değere sıfırlanır.