BitmapData med en referens

Det är viktigt att optimera användningen av klassen BitmapData genom att återanvända instanser så mycket som möjligt. Flash Player 10.1 och AIR 2.5 innehåller också en ny funktion för alla plattformar, som kallas BitmapData med en referens. När du skapar BitmapData-instanser av en inbäddad bild, används en version av bitmappen för alla BitmapData-instanser. Om en bitmapp ändras senare tilldelas den en egen unik bitmapp i minnet. Den inbäddade bilden kan komma från ett bibliotek eller en [Embed]-tagg.

Obs! Även befintligt innehåll kan dra nytta av den här nya funktionen, eftersom Flash Player 10.1 och AIR 2.5 automatiskt återanvänder bitmappar.

När en inbäddad bild instansieras skapas en associerad bitmapp i minnet. Före Flash Player 10.1 och AIR 2.5 fick varje instans en separat bitmapp i minnet, som följande diagram visar:

Bitmappar i minnet före Flash Player 10.1 och AIR 2.5

När flera instanser av samma bild skapas i Flash Player 10.1 och AIR 2.5 används en enda version av bitmappen för alla BitmapData-instanser. I följande bild visas detta:

Bitmappar i minnet i Flash Player 10.1 och AIR 2.5

Det här sättet minskar drastiskt mängden minne som används i program med många bitmappar. I följande kod skapas flera instanser av en Star -symbol:

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

I följande bild visas resultatet av koden:

Visa grafik i full storlek
Resultat av kod som skapar flera instanser av en symbol

I Flash Player 10 använder animeringen ovan ungefär 1 008 kB minne. I Flash Player 10.1 använder animeringen, på stationära datorer och på mobilenheter, bara 4 kB.

I följande kod ändras en BitmapData-instans:

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

I bilden nedan visas resultatet av att en Star -instans ändras:

Visa grafik i full storlek
Resultatet av att ändra en instans

Internt tilldelar och skapar körningsmiljön automatiskt en bitmapp i minnet för att hantera pixelförändringarna. När en metod för klassen BitmapData anropas, skapas en ny instans i minnet och inga andra instanser uppdateras. I bilden nedan illustreras detta:

Resultatet i minnet av att en bitmapp ändras

Om en stjärna ändras skapas en ny kopia i minnet. Den slutliga animeringen använder ungefär 8 kB minne i Flash Player 10.1 och AIR 2.5.

I det tidigare exemplet är varje enskild bitmapp tillgänglig för omformningar. När du vill skapa en indelningseffekt är metoden beginBitmapFill() den som lämpar sig bäst:

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

Detta tillvägagångssätt ger samma resultat fast endast en BitmapData-instans skapas. Om du vill rotera stjärnorna kontinuerligt, i stället för varje Star-instans, ska du använda ett Matrix-objekt som roteras i varje bildruta. Skicka detta Matrix-objekt till metoden 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); 
}

När du använder den här tekniken behövs ingen ActionScript-slinga för att skapa effekten. Miljön hanterar allt internt. I följande bild visas resultatet sedan stjärnorna omformats:

Visa grafik i full storlek
Resultatet av roterade stjärnor

När du använder detta kommer uppdateringen av det ursprungliga BitmapData-källobjektet att automatiskt uppdatera objektet var helst det används på scenen, vilket gör att det här kan vara en användbar teknik. Det här innebär emellertid inte att varje stjärna kan skalförändras var och en för sig som i det tidigare exemplet.

Obs! När du använder flera instanser av samma bild, beror uppritningen på om en klass är kopplad till originalbitmappen i minnet. Om ingen klass är kopplad till bitmappen, kommer bilder att ritas upp som Shape-objekt med bitmappsfyllningar.