Manipulowanie pikselami

Flash Player 9 i nowsze wersje, Adobe AIR 1.0 i nowsze wersje

Klasa BitmapData zawiera zestaw metod umożliwiających manipulowanie wartościami danych pikseli.

Manipulowanie poszczególnymi pikselami

Podczas zmiany wyglądu obrazu bitmapowego na poziomie pikseli konieczne jest najpierw pobranie wartości koloru pikseli z obszaru, którym chce się manipulować. Metoda getPixel() służy do odczytu tych wartości pikseli.

Metoda getPixel() umożliwia pobieranie wartości RGB z zestawu współrzędnych x, y (piksel) przekazywanych w postaci parametru. Jeśli dowolny z pikseli, którym użytkownik chce manipulować, obejmuje informacje o przezroczystości (kanał alfa), konieczne jest zastosowanie metody getPixel32() . Metoda ta umożliwia również pobranie wartości RGB, lecz w przeciwieństwie do metody getPixel() , wartość zwracana przez metodę getPixel32() zawiera dane dodatkowe reprezentujące wartość kanału alfa (przezroczystości) wybranego piksela.

Alternatywnie, w przypadku potrzeby zmiany koloru lub przezroczystości piksela zawartego w bitmapie, można również użyć metody setPixel() lub setPixel32() . W celu ustawienia koloru piksela należy po prostu przekazać współrzędne x, y oraz wartości kolorów do jednej z tych metod.

W poniższym przykładzie opisano wykorzystanie metody setPixel() do wykreślania symbolu krzyża na zielonym tle BitmapData. Następnie używana jest metoda getPixel() umożliwiająca pobranie wartości koloru z piksela o współrzędnych 50, 50 i prześledzenia zwróconej w ten sposób wartości.

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

W celu odczytania wartości grupy pikseli, nie zaś pojedynczego piksela, należy skorzystać z metody getPixels() . Metoda ta umożliwia generowanie tablicy bitowej danych z obszaru danych pikseli w kształcie prostokąta, i przekazaniu go jako parametru. Każdy z elementów tablicy bitowej (innymi słowy, wartości pikseli) to niepodpisane wartości całkowite — 32-bitowe, nieprzemnożone wartości pikseli.

I odwrotnie, w celu zmiany (lub ustawienia) wartości dla grupy pikseli, należy skorzystać z metody setPixels() . Metoda ta wymaga udostępnienia dwu parametrów: ( rect i inputByteArray ), których połączenie daje obszar w kształcie prostokąta ( rect ) danych pikseli ( inputByteArray ).

W miarę odczytu (i zapisu) danych z tablicy inputByteArray wywoływana jest metoda ByteArray.readUnsignedInt() dla każdego piksela w tablicy. Jeśli, z pewnych przyczyn, tablica inputByteArray nie zawiera pełnego prostokąta wartościowych danych pikseli, metoda przerywa w tym punkcie przetwarzanie danych.

Ważne jest, aby pamiętać, że zarówno w przypadku pobierania, jak i ustawiania danych pikseli, tablica bajtowa wymaga udostępnienia następujących wartości 32-bitowych pikseli: alfa, czerwony, zielony, niebieski (ang. ARGB).

W poniższych przykładach zilustrowane jest wykorzystanie metod getPixels() oraz setPixels() do skopiowania grupy pikseli z jednego obiektu BitmapData do drugiego:

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;

Wykrywanie kolizji na poziomie pikseli

Metoda BitmapData.hitTest() wykrywa kolizje na poziomie pikseli między danymi bitmapy a danymi innego obiektu lub punktu.

Metoda BitmapData.hitTest() przyjmuje pięć parametrów:

  • firstPoint (punkt): Ten parametr odnosi się do położenia piksela w lewym górnym rogu pierwszego obiektu BitmapData, na którym wykonywany jest test zderzenia.

  • firstAlphaThreshold (uint): ten parametr określa najwyższą wartość kanału alfa, która na potrzeby tego testu zderzenia jest uznawana za wartość nieprzezroczystości.

  • secondObject (obiekt): Ten parametr reprezentuje obszar uderzenia. Obiekt secondObject może być obiektem Rectangle, Point, Bitmap lub BitmapData. Ten obiekt reprezentuje obszar zderzenia, na którym wykrywana jest kolizja.

  • secondBitmapDataPoint (punkt): Ten parametr opcjonalny służy do definiowania lokalizacji piksela w drugim obiekcie BitmapData. Ten parametr jest wykorzystywany tylko w przypadku, gdy wartością właściwości secondObject jest obiekt BitmapData. Wartość domyślna to null .

  • secondAlphaThreshold (uint): Ten parametr domyślny reprezentuje najwyższą wartość kanału alfa, uznawaną za wartość nieprzezroczystości, w drugim obiekcie BitmapData. Wartością domyślną jest 1. Ten parametr jest używany wyłącznie, jeśli wartość secondObject jest obiektem BitmapData, a oba obiekty BitmapData są przezroczyste.

W przypadku wykrywania kolizji dla obrazów nieprzezroczystych należy pamiętać, że w języku ActionScript obrazy te są traktowane tak, jak gdyby były prostokątami w pełni nieprzezroczystymi (lub jak gdyby były ujęte w obwiednie). Z kolei wykonując test zderzenia na poziomie piksela dla obrazów przezroczystych, należy pamiętać, że oba z nich muszą być przezroczyste. Ponadto w języku ActionScript używane są parametry progowe alfa w celu określenia, w jakim punkcie następuje zmiana przezroczystego piksela na nieprzezroczysty.

W poniższym przykładzie opisano tworzenie trzech obrazów bitmapowych oraz proces sprawdzania pod kątem kolizji w dwu różnych punktach (z których jeden zwraca fałsz, drugi prawdę):

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