Bitmap'leri önbelleğe alma

Karmaşık vektör içeriği için, uygun olduğu zaman bitmap'leri önbelleğe alma özelliğini kullanın.

İyi bir en iyileştirme, bitmap önbelleğe alma özelliği kullanılarak gerçekleştirilebilir. Bu özellik bir vektör nesnesini önbelleğe alır, onu dahili şekilde bir bitmap olarak oluşturur ve o bitmap’i oluşturma için kullanır. Sonuç, oluşturma için aşırı yüksek bir performans artışıdır ancak önemli miktarda bellek gerektirebilir. Karmaşık degradeler veya metin gibi karmaşık vektör içeriği için bitmap'leri önbelleğe alma özelliğini kullanın.

Karmaşık vektör grafikleri kullanan (metin veya degradeler gibi) bir hareketli nesne için bitmap'leri önbelleğe almayı açmak performansı iyileştirir. Ancak, zaman çizelgesi yürütülen bir film klibi gibi görüntüleme nesnesinde bitmap önbelleğe alımı etkinse tam tersi sonucu alırsınız. Her karede, çalışma zamanı önbelleğe alınmış bitmap'i güncellemeli ve ekranda yeniden çizmelidir ve bu çok fazla işlemci döngüsü gerektirir. Bitmap'leri önbelleğe alma özelliği, yalnızca önbelleğe alınmış bitmap bir kere oluşturulup güncellenme gereksinimi duyulmadan kullanılıyorsa yarar sağlar.

Bir Sprite nesnesi için bitmap önbelleğe alma özelliğini açarsanız; nesne çalışma zamanının önbelleğe alınan bitmap’i yeniden oluşturmasına neden olmadan taşınabilir. Nesnenin x ve y özelliklerinin değiştirilmesi yeniden oluşturmaya neden olmaz. Ancak döndürme, ölçeklendirme veya alfa değerini değiştirme, çalışma zamanının önbelleğe alınmış bitmap’i yeniden oluşturmasına neden olur ve bunun sonucunda performans zarar görür.

Not: AIR ve Packager for iPhone uygulamalarında bulunan DisplayObject.cacheAsBitmapMatrix özelliğinde bu kısıtlama yoktur. cacheAsBitmapMatrix özelliğini kullanarak, bitmap yeniden oluşturmayı tetiklemeden görüntüleme nesnesinin alfa değerini döndürebilir, ölçeklendirebilir, eğriltebilir ve değiştirebilirsiniz.

Önbelleğe alınan bir bitmap sıradan bir film klibi örneğine göre daha fazla bellek kullanabilir. Örneğin, Sahne Alanı'ndaki bir film klibi 250 x 250 piksel boyutlarına sahipse, arabelleğe alınmadığında kullanacağı 1 KB yerine, arabelleğe alındığında yaklaşık 250 KB kullanır.

Aşağıdaki örnekte elma görüntüsü içeren bir Sprite nesnesi vardır. Aşağıdaki sınıf elma sembolüne bağlıdır:

package org.bytearray.bitmap 
{     
    import flash.display.Sprite; 
    import flash.events.Event; 
     
    public class Apple extends Sprite 
    { 
        private var destinationX:Number; 
        private var destinationY:Number; 
         
        public function Apple () 
        { 
            addEventListener(Event.ADDED_TO_STAGE,activation); 
            addEventListener(Event.REMOVED_FROM_STAGE,deactivation);     
        } 
         
        private function activation(e:Event):void  
        { 
            initPos();     
            addEventListener (Event.ENTER_FRAME,handleMovement);     
        } 
         
        private function deactivation(e:Event):void  
        { 
            removeEventListener(Event.ENTER_FRAME,handleMovement);     
        } 
         
        private function initPos():void 
        { 
            destinationX = Math.random()*(stage.stageWidth - (width>>1)); 
            destinationY = Math.random()*(stage.stageHeight - (height>>1)); 
        } 
         
        private function handleMovement(e:Event):void  
        { 
            x -= (x - destinationX)*.5; 
            y -= (y - destinationY)*.5; 
             
            if (Math.abs(x - destinationX) < 1 && Math.abs(y - destinationY) < 1) 
                initPos(); 
        } 
    } 
}

Kod, her elma için bir zaman çizelgesi gerekmediğinden MovieClip sınıfı yerine Sprite sınıfını kullanır. En iyi performans için, mümkün olan en hafif nesneyi kullanın. Sonra, sınıf aşağıdaki kod ile başlatılır:

import org.bytearray.bitmap.Apple; 
 
stage.addEventListener(MouseEvent.CLICK,createApples); 
stage.addEventListener(KeyboardEvent.KEY_DOWN,cacheApples); 
 
const MAX_NUM:int = 100; 
var apple:Apple; 
var holder:Sprite = new Sprite(); 
 
addChild(holder); 
 
function createApples(e:MouseEvent):void 
{ 
    for (var i:int = 0; i< MAX_NUM; i++) 
    { 
        apple = new Apple(); 
         
        holder.addChild(apple); 
    } 
} 
 
function cacheApples(e:KeyboardEvent):void 
{ 
    if (e.keyCode == 67) 
    { 
        var lng:int = holder.numChildren; 
         
        for (var i:int = 0; i < lng; i++) 
        { 
            apple = holder.getChildAt (i) as Apple; 
             
            apple.cacheAsBitmap = Boolean(!apple.cacheAsBitmap); 
        } 
    } 
}

Kullanıcı fareyi tıklattığında, elmalar arabelleğe alınmadan oluşturulur. Kullanıcı C (tuş kodu 67) tuşuna bastığında, elma vektörleri bitmap'ler olarak arabelleğe alınır ve ekran üzerinde görüntülenir. Bu teknik CPU yavaş olduğunda hem masaüstü hem de mobil cihazlar için oluşturma performansını büyük ölçüde iyileştirir.

Ancak, bitmap'leri arabelleğe alma özelliği oluşturma performansını iyileştirse de, hızla büyük miktarda bellek tüketebilir. Bir nesne önbelleğe alındığı anda, yüzeyi aşağıdaki şemada gösterildiği gibi saydam bitmap olarak yakalanır ve bellekte saklanır.

Bellekte saklanan nesne ve bu nesnenin yüzey bitmap’i

Flash Player 10.1 ve AIR 2.5, Filtreleri ve dinamik bitmap'i kaldırma bölümünde anlatılan yaklaşımı uygulayarak bellek kullanımını en iyi hale getirir. Önbelleğe alınmış görüntüleme nesnesi ekranda değilse ya da gizliyse, bir süre kullanılmadığında bellekteki bitmap serbest bırakılır.

Not: Görüntüleme nesnesinin opaqueBackground özelliği belirli bir renge ayarlanırsa, çalışma zamanı görüntüleme nesnesini opak olarak varsayar. cacheAsBitmap özelliği ile birlikte kullanıldığında, çalışma zamanı bellekte saydam olmayan bir 32 bit bitmap oluşturur. Alfa kanalı 0xFF olarak ayarlanır, bu da ekran üzerindeki bitmap’in çizilmesi için saydamlık gerekmediğinden performansı iyileştirir. Alfa karıştırmayı önlemek oluşturma işlemini daha da hızlandırır. Geçerli ekran derinliği 16 bit ile sınırlıysa, bellekteki bitmap 16 bit’lik bir görüntü olarak saklanır. opaqueBackground özelliğinin kullanılması bitmap'leri artalanda önbelleğe alma işlemini başlatmaz.

Bellekten tasarruf etmek için, cacheAsBitmap özelliğini kullanın ve onu kap yerine her görüntüleme nesnesinde etkinleştirin. Kaptaki bitmap'leri önbelleğe almayı etkinleştirme işlemi, 211 x 279 piksel boyutlarında saydam bitmap oluşturarak son bitmap’in bellekte çok daha fazla yer kaplamasına yol açar. Görüntü yaklaşık 229 KB'lık bellek kullanır:

Grafiği tam boyut görüntüle
Kapta bitmap'leri arabelleğe almayı etkinleştirme

Ayrıca, kabı önbelleğe alarak, herhangi bir elmanın bir karede hareket etmeye başlaması durumunda bellekte bitmap’in tamamının güncellenmesi riskini de alırsınız. Bağımsız örneklerde bitmap'leri arabelleğe almayı etkinleştirmek bellekte yalnızca 42 KB kullanmak demek olan 7 KB'lık yüzeyleri arabelleğe almayla sonuçlanır.

Grafiği tam boyut görüntüle
Örneklerde bitmap'leri arabelleğe almayı etkinleştirme

Her elma örneğine görüntüleme listesi üzerinden erişilmesi ve getChildAt() yönteminin kullanılması başvuruları daha kolay erişim için bir Vector nesnesinde saklar:

import org.bytearray.bitmap.Apple; 
 
stage.addEventListener(KeyboardEvent.KEY_DOWN, cacheApples); 
 
const MAX_NUM:int = 200; 
var apple:Apple; 
var holder:Sprite = new Sprite(); 
 
addChild(holder); 
 
var holderVector:Vector.<Apple> = new Vector.<Apple>(MAX_NUM, true); 
 
for (var i:int = 0; i< MAX_NUM; i++) 
{ 
    apple = new Apple(); 
     
    holder.addChild(apple); 
     
    holderVector[i] = apple; 
} 
 
function cacheApples(e:KeyboardEvent):void 
{ 
    if (e.keyCode == 67) 
    { 
        var lng:int = holderVector.length 
         
        for (var i:int = 0; i < lng; i++) 
        { 
            apple = holderVector[i]; 
             
            apple.cacheAsBitmap = Boolean(!apple.cacheAsBitmap); 
        } 
    } 
}

Her karede önbelleğe alınmış içerik döndürülmüyor, ölçeklendirilmiyor veya değiştirilmiyorsa bitmap'leri önbelleğe almanın oluşturma işlemini iyileştireceğini unutmayın. Ancak, oluşturma x ve y eksenlerinde çevrilme haricindeki herhangi bir dönüştürme için iyileştirilmez. Bu durumlarda, Flash Player görüntüleme nesnesinde oluşan her dönüştürme için önbelleğe alınan bitmap kopyasını günceller. Önbelleğe alınan kopyanın güncellenmesi işlemcinin fazla kullanımı, yavaş performans ve yüksek pil kullanımına neden olabilir. AIR veya Packager for iPhone uygulamalarında bulunan cacheAsBitmapMatrix özelliğinde bu kısıtlama yoktur.

Aşağıdaki kod hareket yöntemindeki alfa değerini değiştirir, bu da her karede elmanın opaklığını değiştirir.

private function handleMovement(e:Event):void  
{ 
        alpha = Math.random(); 
        x -= (x - destinationX)*.5; 
        y -= (y - destinationY)*.5; 
             
        if (Math.abs(x - destinationX) < 1 && Math.abs(y - destinationY) < 1) 
            initPos(); 
}

Bitmap'leri arabelleğe alma performansta bir yavaşlamaya sebep olur. Alfa değerinin değiştirilmesi, çalışma zamanını her alfa değeri değişiminde bellekte arabelleğe alınan bitmap'i güncellemeye zorlar.

Filtreler önbelleğe alınan bir film klibi oynatma kafasının her hareket edişinde güncellenen bitmap'lere bağlıdır. Bu nedenle, bir filtre kullanılması, otomatik olarak cacheAsBitmap özelliğini true değerine ayarlar. Aşağıdaki şekilde hareketli bir film klibi gösterilmektedir:

Hareketli film klibi

Performansta sorunlara yol açacağından, hareketli içerikte filtre kullanımından kaçının. Aşağıdaki şekilde, tasarımcı bir alt gölge filtresi ekler:

Alt gölge filtresiyle hareketli film klibi

Sonuç olarak, film klibinin içindeki zaman çizelgesi oynatılıyorsa, bitmap yeniden oluşturulmalıdır. Basit bir x veya y dönüşümü haricinde içerik değiştirilmişse de bitmap yeniden oluşturulmalıdır. Her kare, çalışma zamanını bitmap’i yeniden çizmeye zorlar, bu da daha fazla işlemci kaynağı kullanımı gerektirir, düşük performansa neden olur ve daha fazla pil ömrü tüketir.

Paul Trani aşağıdaki eğitim videolarında bitmap kullanarak grafikleri en iyi duruma getirmek için Flash Professional ve ActionScript kullanımının örneklerini sağlar: