Pojedyncze odwołanie do obiektu BitmapData

Jak najczęstsze ponowne wykorzystywanie instancji umożliwia zoptymalizowanie użycia klasy BitmapData. W programie Flash Player 10.1 i środowisku AIR 2.5 wprowadzono dla wszystkich platform nową funkcję określaną jako pojedyncze odwołanie do obiektu BitmapData. W przypadku tworzenia instancji BitmapData z osadzonego obrazu dla wszystkich instancji BitmapData używana jest jedna wersja bitmapy. Jeśli później bitmapa zostanie zmodyfikowana, otrzyma w pamięci osobną unikalną bitmapę. Osadzony obraz może pochodzić z biblioteki lub ze znacznika [Embed].

Uwaga: Nowa funkcja jest przydatna również w przypadku istniejącej zawartości, ponieważ program Flash Player 10.1 i środowisko AIR 2.5 automatycznie ponownie używają bitmap.

Podczas tworzenia wystąpienia osadzonego obrazu w pamięci tworzona jest powiązana bitmapa. W wersjach oprogramowania wcześniejszych niż Flash Player 10.1 i AIR 2.5 każde wystąpienie otrzymywało osobną bitmapę w pamięci, co przedstawia poniższy diagram.

Bitmapy w pamięci — w wersji oprogramowania wcześniejszej niż Flash Player 10.1 i AIR 2.5

Jeśli w programie Flash Player 10.1 lub środowisku AIR 2.5 tworzonych jest wiele wystąpień tego samego obrazu, wówczas dla wszystkich wystąpień klasy BitmapData jest stosowana jedna wersja bitmapy. Poniższy diagram ilustruje tę koncepcję:

Bitmapy w pamięci w wersji Flash Player 10.1 i AIR 2.5

Taka metoda znacząco zmniejsza ilość pamięci wykorzystywanej przez aplikację z wieloma bitmapami. Poniższy kod tworzy wiele instancji symbolu Star :

const MAX_NUM:int = 18; 
 
var star:BitmapData; 
var bitmap:Bitmap; 
 
for (var i:int = 0; i<MAX_NUM; i++) 
{ 
    for (var j:int = 0; j<MAX_NUM; j++) 
    { 
        star = new Star(0,0); 
        bitmap = new Bitmap(star); 
        bitmap.x = j * star.width; 
        bitmap.y = i * star.height; 
        addChild(bitmap) 
    } 
}

Poniższy obraz prezentuje wynik działania kodu:

Powiększ obraz
Wynik działania kodu tworzącego wiele instancji symbolu

Na przykład w programie Flash Player 10 powyższa animacja zajmuje około 1008 KB pamięci. W programie Flash Player 10.1 (na komputerze stacjonarnym i na urządzeniu przenośnym) animacja ta zajmuje tylko 4 KB.

Poniższy kod modyfikuje jedną instancję klasy BitmapData:

const MAX_NUM:int = 18; 
 
var star:BitmapData; 
var bitmap:Bitmap; 
 
for (var i:int = 0; i<MAX_NUM; i++) 
{ 
    for (var j:int = 0; j<MAX_NUM; j++) 
    { 
        star = new Star(0,0); 
        bitmap = new Bitmap(star); 
        bitmap.x = j * star.width; 
        bitmap.y = i * star.height; 
        addChild(bitmap) 
    } 
} 
 
var ref:Bitmap = getChildAt(0) as Bitmap; 
 
ref.bitmapData.pixelDissolve(ref.bitmapData, ref.bitmapData.rect, new Point(0,0),Math.random()*200,Math.random()*200, 0x990000);

Poniższy obraz prezentuje wynik modyfikacji jednej instancji Star :

Powiększ obraz
Wynik modyfikacji instancji

Środowisko automatycznie przypisuje i tworzy w pamięci bitmapę służącą do obsługi modyfikacji pikseli. Po wywołaniu metody klasy BitmapData, co powoduje modyfikacje pikseli, w pamięci tworzona jest nowa instancja, a żadne inne instancje nie są aktualizowane. Poniższy rysunek ilustruje tę koncepcję:

Wynik modyfikacji jednej bitmapy w pamięci

Zmodyfikowanie jednej gwiazdki powoduje utworzenie nowej kopii w pamięci. Uzyskana w ten sposób animacja zajmuje około 8 KB w pamięci programu Flash Player 10.1 i środowiska AIR 2.5.

W poprzednim przykładzie każda bitmapa jest dostępna osobno dla transformacji. Metoda beginBitmapFill() jest najbardziej odpowiednią metodą do utworzenia mozaiki:

var container:Sprite = new Sprite(); 
 
var source:BitmapData = new Star(0,0); 
 
// Fill the surface with the source BitmapData 
container.graphics.beginBitmapFill(source); 
container.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight); 
 
addChild(container);

Ten sposób postępowania zapewnia uzyskanie tego samego wyniku, ale tworzona jest tylko jedna instancja klasy BitmapData. W celu ciągłego obracania gwiazd - zamiast uzyskiwać dostęp do każdej instancji Star - należy użyć obiektu Matrix, który będzie obracany w każdej klatce. Obiekt Matrix należy przekazać do metody beginBitmapFill() :

var container:Sprite = new Sprite(); 
 
container.addEventListener(Event.ENTER_FRAME, rotate); 
 
var source:BitmapData = new Star(0,0); 
var matrix:Matrix = new Matrix(); 
 
addChild(container); 
 
var angle:Number = .01; 
 
function rotate(e:Event):void 
{ 
    // Rotate the stars 
    matrix.rotate(angle); 
 
    // Clear the content 
    container.graphics.clear(); 
  
    // Fill the surface with the source BitmapData 
    container.graphics.beginBitmapFill(source,matrix,true,true); 
    container.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight); 
}

Gdy stosowana jest ta technika, żadna pętla ActionScript nie jest wymagana do utworzenia tego efektu. Środowisko wykonawcze realizuje wszystkie operacje wewnętrznie. Poniższy obraz prezentuje wynik transformacji gwiazdek:

Powiększ obraz
Wynik obracania gwiazdek

W tym przypadku aktualizacja oryginalnego obiektu źródłowego BitmapData powoduje aktualizację jego wystąpienia na stole montażowym, co może w praktyce okazać się bardzo wydajną techniką programistyczną. Takie podejście nie umożliwia jednak skalowania poszczególnych gwiazdek, jak w poprzednim przykładzie.

Uwaga: W przypadku stosowania wielu instancji tego samego obrazu sposób rysowania jest zależny od tego, czy jakakolwiek klasa jest powiązana z oryginalną bitmapą w pamięci. Jeśli żadna klasa nie jest powiązana z bitmapą, obrazy są rysowane jako obiekty Shape z wypełnieniami w postaci bitmapy.