Manipulation des pixels

Flash Player 9 et les versions ultérieures, Adobe AIR 1.0 et les versions ultérieures

La classe BitmapData contient des méthodes qui permettent de modifier les valeurs des données de pixels.

Manipulation individuelle de pixels

Pour modifier une image bitmap au niveau des pixels, il est d’abord nécessaire d’obtenir les valeurs colorimétriques des pixels de la zone à modifier. La méthode getPixel() permet d’obtenir ces valeurs de pixels.

La méthode getPixel() renvoie les valeurs RVB des coordonnées (de pixels) x et y qui lui sont passées en paramètres. Si l’un des pixels comporte des informations de transparence (canal alpha), il est nécessaire d’utiliser la méthode getPixel32(). Cette méthode récupère également une valeur RVB, mais contrairement à ce qui se passe avec getPixel(), la valeur renvoyée par getPixel32() contient des données supplémentaires qui représentent la valeur du canal alpha (transparence) du pixel sélectionné.

Pour simplement modifier la couleur ou la transparence d’un pixel contenu dans un bitmap, il est aussi possible d’utiliser la méthode setPixel() ou setPixel32(). Pour définir la couleur d’un pixel, il suffit de passer les coordonnées x et y et la valeur colorimétrique à l’une de ces méthodes.

Dans l’exemple suivant, setPixel() est utilisée pour tracer une croix sur un fond vert BitmapData. La méthode getPixel() permet ensuite de récupérer la valeur colorimétrique du pixel ayant les coordonnées 50, 50 et de suivre la valeur renvoyée.

import flash.display.Bitmap; 
import flash.display.BitmapData; 
 
var myBitmapData:BitmapData = new BitmapData(100, 100, false, 0x009900); 
 
for (var i:uint = 0; i < 100; i++) 
{ 
    var red:uint = 0xFF0000; 
    myBitmapData.setPixel(50, i, red); 
    myBitmapData.setPixel(i, 50, red); 
} 
 
var myBitmapImage:Bitmap = new Bitmap(myBitmapData); 
addChild(myBitmapImage); 
 
var pixelValue:uint = myBitmapData.getPixel(50, 50); 
trace(pixelValue.toString(16));

Pour lire la valeur d’un groupe de pixels, et non pas d’un pixel isolé, utilisez la méthode getPixels(). Cette méthode génère un tableau d’octets à partir d’une zone rectangulaire de données de pixels, et le passe en paramètre. Chaque élément du tableau d’octets (autrement dit, les valeurs des pixels) est un entier non signé (valeurs non multipliées sur 32 bits).

Inversement, pour modifier (ou définir) la valeur d’un groupe de pixels, utilisez la méthode setPixels(). Cette méthode attend deux paramètres (rect et inputByteArray), qui sont combinés pour produire une zone rectangulaire (rect) de données de pixels (inputByteArray).

Au fur et à mesure de la lecture (ou de l’écriture) des données dans inputByteArray, la méthode ByteArray.readUnsignedInt() est appelée pour chaque pixel du tableau. Si pour une raison quelconque inputByteArray ne contient pas un rectangle complet de données de pixels, la méthode interrompt le traitement des données de l’image.

Il est important de comprendre que pour lire ou modifier des données de pixels, le tableau d’octets attend les valeurs suivantes sur 32 octets : alpha, rouge, vert, bleu (ARVB).

L’exemple suivant utilise les méthodes getPixels() et setPixels() pour copier un groupe de pixels d’un objet BitmapData à un autre :

import flash.display.Bitmap; 
import flash.display.BitmapData; 
import flash.utils.ByteArray; 
import flash.geom.Rectangle; 
 
var bitmapDataObject1:BitmapData = new BitmapData(100, 100, false, 0x006666FF); 
var bitmapDataObject2:BitmapData = new BitmapData(100, 100, false, 0x00FF0000); 
 
var rect:Rectangle = new Rectangle(0, 0, 100, 100); 
var bytes:ByteArray = bitmapDataObject1.getPixels(rect); 
 
bytes.position = 0; 
bitmapDataObject2.setPixels(rect, bytes); 
 
var bitmapImage1:Bitmap = new Bitmap(bitmapDataObject1); 
addChild(bitmapImage1); 
var bitmapImage2:Bitmap = new Bitmap(bitmapDataObject2); 
addChild(bitmapImage2); 
bitmapImage2.x = 110;

Détection de collision au niveau des pixels

La méthode BitmapData.hitTest() effectue une détection de collision au niveau des pixels entre les données bitmap et celles d’un autre objet ou d’un point.

La méthode BitmapData.hitTest() accepte cinq paramètres :

  • firstPoint (Point) : ce paramètre référence la position du coin supérieur gauche du premier objet BitmapData sur lequel le test de collision doit être effectué.

  • firstAlphaThreshold (uint) : ce paramètre spécifie la valeur la plus élevée du canal alpha considéré comme étant opaque pour ce test de collision.

  • secondObject (Object) : ce paramètre représente la zone d’impact. L’objet secondObject peut être un objet de type Rectangle, Point, Bitmap ou BitmapData. Cet objet représente la zone dans laquelle doit être effectuée la détection de collision.

  • secondBitmapDataPoint (Point) : ce paramètre facultatif définit l’emplacement d’un pixel dans le deuxième objet BitmapData. Utilisez uniquement ce paramètre lorsque la valeur de secondObject est un objet BitmapData. La valeur par défaut est null.

  • secondAlphaThreshold (uint) : ce paramètre facultatif représente la valeur la plus élevée de canal alpha considérée comme étant opaque dans le deuxième objet BitmapData. La valeur par défaut est 1. Utilisez uniquement ce paramètre lorsque la valeur de secondObject est un objet BitmapData et que les deux objets BitmapData sont transparents.

Lors d’une détection de collision sur des images opaques, n’oubliez pas qu’ActionScript traite l’image comme si c’était un rectangle entièrement opaque (ou un cadre de sélection). Par ailleurs, lors de tests de collision au niveau des pixels pour des images qui sont transparentes, les deux images doivent être transparentes. De plus, ActionScript utilise les paramètres de seuil alpha pour déterminer le point auquel les pixels passent de transparents à opaques.

L’exemple suivant crée trois images bitmap et teste une éventuelle collision de pixels en deux différents points (l’un renvoie false, l’autre true) :

import flash.display.Bitmap; 
import flash.display.BitmapData; 
import flash.geom.Point; 
 
var bmd1:BitmapData = new BitmapData(100, 100, false, 0x000000FF); 
var bmd2:BitmapData = new BitmapData(20, 20, false, 0x00FF3300); 
 
var bm1:Bitmap = new Bitmap(bmd1); 
this.addChild(bm1); 
 
// Create a red square. 
var redSquare1:Bitmap = new Bitmap(bmd2); 
this.addChild(redSquare1); 
redSquare1.x = 0; 
 
// Create a second red square. 
var redSquare2:Bitmap = new Bitmap(bmd2); 
this.addChild(redSquare2); 
redSquare2.x = 150; 
redSquare2.y = 150; 
 
// Define the point at the top-left corner of the bitmap. 
var pt1:Point = new Point(0, 0); 
// Define the point at the center of redSquare1. 
var pt2:Point = new Point(20, 20); 
// Define the point at the center of redSquare2. 
var pt3:Point = new Point(160, 160); 
 
trace(bmd1.hitTest(pt1, 0xFF, pt2)); // true 
trace(bmd1.hitTest(pt1, 0xFF, pt3)); // false