Référence unique à BitmapData

Il est important d’optimiser l’utilisation de la classe BitmapData en réutilisant les occurrences autant que faire se peut. Flash Player 10.1 et AIR 2.5 proposent une nouvelle fonction de référence unique à BitmapData sur toutes les plates-formes. Lors de la création d’occurrences de BitmapData à partir d’une image intégrée, une version unique du bitmap est utilisée pour toutes ces occurrences. Si le bitmap est modifié par la suite, un bitmap qui lui est propre lui est attribué en mémoire. L’image intégrée peut provenir de la bibliothèque ou d’une balise [Embed].

Remarque : cette nouvelle fonction présente également des avantages pour le contenu existant, car Flash Player 10.1 et AIR 2.5 réutilisent automatiquement les bitmaps.

Lors de l’instanciation d’une image intégrée, un bitmap associé est créé en mémoire. Préalablement à Flash Player 10.1 et AIR  2.5, à chaque occurrence était attribué son propre bitmap en mémoire, comme illustré ci-dessous :

Bitmaps en mémoire avant Flash Player 10.1 et AIR 2.5

Dans Flash Player 10.1 et AIR 2.5, lors de la création de plusieurs occurrences d’une même image, une version unique du bitmap est utilisée pour toutes les occurrences de BitmapData. Ce concept est illustré ci-dessous :

Bitmaps en mémoire dans Flash Player 10.1 et AIR 2.5

Cette technique réduit considérablement la quantité de mémoire que nécessite une application utilisant de nombreux bitmaps. Le code suivant crée plusieurs occurrences du symbole 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) 
    } 
}

La figure suivante illustre le résultat du code :

Afficher le graphique en taille réelle
Résultat du code utilisé pour créer plusieurs occurrences du symbole

Avec Flash Player 10, par exemple, l’animation ci-dessus utilise environ 1 008 Ko de mémoire. Avec Flash Player 10.1, l’animation utilise seulement 4 Ko, que l’application soit installée sur un ordinateur de bureau ou sur un périphérique mobile.

Le code suivant modifie une seule occurrence de 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);

La figure suivante illustre le résultat de la modification d’une seule occurrence de Star :

Afficher le graphique en taille réelle
Résultat de la modification d’une occurrence unique

En interne, le moteur d’exécution attribue et crée automatiquement un bitmap en mémoire pour gérer les modifications au niveau des pixels. L’appel d’une méthode de la classe BitmapData entraîne la modification des pixels et la création d’une occurrence en mémoire, et aucune autre occurrence n’est mise à jour. La figure suivante illustre ce concept :

Résultat en mémoire de la modification d’un bitmap unique

Si une étoile est modifiée, une nouvelle copie est créée dans la mémoire. L’animation résultante utilise environ 8 Ko de mémoire dans Flash Player 10.1 et AIR 2.5.

Dans l’exemple précédent, chaque bitmap peut être transformé individuellement. Pour créer uniquement l’effet de mosaïque, la méthode beginBitmapFill() est la plus adaptée :

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

Cette technique donne le même résultat et une seule occurrence de BitmapData est créée. Pour imprimer une rotation permanente aux étoiles, plutôt que d’accéder à chaque occurrence de Star, utilisez un objet Matrix pivotant sur chaque image et transmettez-le à la méthode 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); 
}

Il est ainsi inutile de recourir à une boucle ActionScript pour créer l’effet. Le moteur d’exécution effectue toutes les opérations en interne. La figure suivante illustre le résultat de la transformation des étoiles :

Afficher le graphique en taille réelle
Résultat de la rotation des étoiles

La mise à jour de l’objet BitmapData source original est automatiquement répercutée sur son utilisation à un autre emplacement sur la scène. Cette technique peut se révéler très performante. Elle ne permet pas cependant de mettre individuellement à l’échelle chaque étoile, comme dans l’exemple précédent.

Remarque : lors de l’utilisation de plusieurs occurrences d’une même image, le dessin varie selon qu’une classe est associée au bitmap original en mémoire. Si aucune classe n’est associée au bitmap, les images sont dessinées en tant qu’objets Shape avec des remplissages de bitmap.