Het is belangrijk het gebruik van de BitmapData-klasse te optimaliseren door instanties zoveel mogelijk opnieuw te gebruiken. In Flash Player 10.1 en AIR 2.5 wordt een nieuwe functie geïntroduceerd voor alle platforms: de enkele BitmapData-referentie. Wanneer u BitmapData-instanties maakt van een ingesloten afbeelding, wordt één versie van de bitmap gebruikt voor alle BitmapData-instanties. Als een bitmap later wordt aangepast, krijgt deze een eigen unieke bitmap in het geheugen. De ingesloten afbeelding kan afkomstig zijn uit de bibliotheek of uit een [Embed]-tag.
Opmerking:
De bestaande inhoud profiteert ook van deze nieuwe functie, omdat Flash Player 10.1 en AIR 2.5 deze bitmaps automatisch opnieuw gebruiken.
Wanneer u een ingesloten afbeelding instantieert, wordt een bijbehorende bitmap gemaakt in het geheugen. Vóór Flash Player 10.1 en AIR 2.5 kreeg elke instantie een aparte bitmap in het geheugen, zoals wordt weergegeven in het volgende diagram:
Bitmaps in het geheugen vóór Flash Player 10.1 en AIR 2.5
Wanneer er in Flash Player 10.1 en AIR 2.5 meerdere instanties van dezelfde afbeelding worden gemaakt, wordt er een enkele versie van de bitmap gebruikt voor alle BitmapData-instanties. het volgende diagram illustreert dit concept:
Bitmaps in het geheugen van Flash Player 10.1 en AIR 2.5
Deze aanpak vermindert aanzienlijk de hoeveelheid geheugen die een toepassing met veel bitmaps gebruikt. De volgende code maakt meerdere instanties van een
Star
-symbool:
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)
}
}
In de volgende afbeelding ziet u het resultaat van de code:
Met Flash Player 10 gebruikt de bovenstaande animatie bijvoorbeeld ongeveer 1008 kB geheugen. Met Flash Player 10.1 gebruikt de animatie op een desktopcomputer en op een mobiel apparaat slechts 4 kB.
De volgende code past één BitmapData-instantie aan:
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);
In de volgende afbeelding ziet u het resultaat na het aanpassen van één
Star
-instantie:
Intern wijst de runtime automatisch een bitmap aan het geheugen toe of maakt een bitmap in het geheugen om de pixelwijzigingen te verwerken. Wanneer een methode van de BitmapData-klasse wordt aangeroepen die tot pixelwijzigingen leidt, wordt er een nieuwe instantie gemaakt in het geheugen en worden er geen andere instanties bijgewerkt. De onderstaande afbeelding illustreert het concept:
Resultaat in het geheugen van het aanpassen van één bitmap.
Als er één ster wordt gewijzigd, wordt er een nieuwe kopie in het geheugen gemaakt. De animatie die daarvan het resultaat is, gebruikt ongeveer 8 kB geheugen met Flash Player 10.1 en AIR 2.5.
In het vorige voorbeeld is elke bitmap afzonderlijk beschikbaar voor transformatie. De
beginBitmapFill()
-methode is het geschiktst als u alleen een naast-elkaareffect wilt bereiken.
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);
Deze aanpak produceert hetzelfde resultaat met slechts één BitmapData-instantie. Als u sterren voortdurend wilt roteren in plaats van elke sterinstantie afzonderlijk te openen, gebruikt u een Matrix-object dat op elk frame wordt geroteerd. Geef dit Matrix- object door aan de methode
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);
}
Met deze techniek hebt u geen ActionScript-loop nodig om het effect te bereiken. De runtime doet alles intern. In de volgende afbeelding ziet u het resultaat van de transformatie van de sterren:
Met deze aanpak wordt tijdens het bijwerken van de oorspronkelijke bron, het BitmapData-object, zijn gebruik op een andere plek in het werkgebied automatisch bijgewerkt. Dit is een krachtige techniek. Deze aanpak staat echter niet toe dat de schaal van elke ster afzonderlijk wordt aangepast, zoals in het vorige voorbeeld.
Opmerking:
Wanneer u meerdere instanties van dezelfde afbeelding gebruikt, hangt het tekenen af van het feit of er een klasse aan de oorspronkelijke bitmap in het geheugen is gekoppeld. Als er geen klasse aan de bitmap is gekoppeld, worden afbeeldingen getekend als Shape-objecten met bitmapinvullingen.