Manipolazione dei pixel

Flash Player 9 e versioni successive, Adobe AIR 1.0 e versioni successive

La classe BitmapData contiene una serie di metodi che consentono di manipolare i valori dei dati pixel.

Manipolazione dei singoli pixel

Nel modificare l'aspetto di un'immagine bitmap a livello di pixel, è necessario innanzi tutto ottenere i valori di colore dei pixel contenuti all'interno dell'area che si desidera manipolare. Per leggere questi valori di pixel, utilizzate il metodo getPixel() .

Il metodo getPixel() recupera un valore RGB da una serie di coordinate x, y (pixel) che vengono assegnate come parametro. Se uno dei pixel che desiderate manipolare include delle informazioni sulla trasparenza (canale alfa), utilizzate il metodo getPixel32() . Questo metodo recupera un valore RGB, ma a differenza di getPixel() , il valore restituito da getPixel32() contiene dei dati aggiuntivi che rappresentano il valore del canale alfa (trasparenza) del pixel selezionato.

In alternativa, se desiderate semplicemente modificare il colore o la trasparenza di un pixel contenuto all'interno di una bitmap, utilizzate il metodo setPixel() o setPixel32() . Per impostare il colore di un pixel, è sufficiente assegnare le coordinate x, y e il valore di colore a uno di questi metodi.

Nell'esempio seguente viene utilizzato il metodo setPixel() per disegnare una croce su uno sfondo BitmapData verde. Quindi, viene utilizzato getPixel() per recuperare il valore di colore dal pixel in corrispondenza della coordinata 50, 50 e viene tracciato il valore restituito.

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

Se desiderate leggere il valore di un gruppo di pixel, anziché quello di un pixel singolo, utilizzate il metodo getPixels() . Questo metodo genera un array di byte da un'area rettangolare di dati pixel che viene assegnato come parametro. Ognuno degli elementi dell'array di byte (in altre parole, ognuno dei valori di pixel) è un intero senza segno, cioè un valore di pixel a 32 bit non moltiplicato.

Al contrario, per modificare (o impostare) il valore di un gruppo di pixel, utilizzate il metodo setPixels() . Questo metodo prevede due parametri ( rect e inputByteArray ), che vengono combinati per produrre un'area rettangolare ( rect ) di dati pixel ( inputByteArray ).

Quando i dati vengono letti (e scritti) da inputByteArray , il metodo ByteArray.readUnsignedInt() viene chiamato per ognuno dei pixel nell'array. Se per qualche motivo inputByteArray non contiene un rettangolo intero di dati pixel, il metodo interrompe in quel punto l'elaborazione dei dati dell'immagine.

È importante ricordare che, sia per ottenere che per impostare i dati pixel, l'array di byte prevede valori di pixel a 32 bit per l'alfa, il rosso, il verde e il blu (ARGB).

Nell'esempio seguente vengono utilizzati i metodi getPixels() e setPixels() per copiare un gruppo di pixel da un oggetto BitmapData a un altro.

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;

Rilevamento di collisioni a livello di pixel

Il metodo BitmapData.hitTest() effettua il rilevamento delle collisioni a livello di pixel tra i dati bitmap e un altro oggetto o punto.

Il metodo BitmapData.hitTest() accetta cinque parametri:

  • firstPoint (Point): questo parametro fa riferimento alla posizione in pixel dell'angolo superiore sinistro del primo BitmapData su cui viene effettuata la verifica di rilevamento delle zone attive.

  • firstAlphaThreshold (uint): questo parametro specifica il valore di canale alfa più alto che viene considerato opaco per la verifica di rilevamento delle zone attive.

  • secondObject (Object): questo parametro rappresenta l'area di impatto. L'oggetto secondObject può essere un oggetto Rectangle, Point, Bitmap o BitmapData. Questo oggetto rappresenta l'area attiva su cui viene eseguito il rilevamento delle collisioni.

  • secondBitmapDataPoint (Point): questo parametro opzionale viene utilizzato per definire la posizione di un pixel nel secondo oggetto BitmapData. Utilizzate questo parametro solo quando il valore di secondObject è un oggetto BitmapData. Il valore predefinito è null .

  • secondAlphaThreshold (uint): questo parametro opzionale rappresenta il valore di canale alfa più alto che viene considerato opaco per il secondo oggetto BitmapData. Il valore predefinito è -1. Utilizzate questo parametro solo quando il valore di secondObject è un oggetto BitmapData ed entrambi gli oggetti BitmapData sono trasparenti.

Quando eseguite il rilevamento delle collisioni sulle immagini opache, tenete conto del fatto che ActionScript considera l'immagine come se fosse un rettangolo (o un riquadro di delimitazione) completamente opaco. In alternativa, quando effettuate il rilevamento per zone a livello di pixel su immagini trasparenti, è necessario che entrambe le immagini siano trasparenti. Inoltre, ActionScript utilizza i parametri di soglia dell'alfa per determinare in quale punto l'aspetto dei pixel passa da trasparente a opaco.

Nell'esempio seguente vengono create tre immagini bitmap e verificata la collisione dei pixel utilizzando due punti di collisione diversi (uno restituisce false, l'altro 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