处理像素

Flash Player 9 和更高版本,Adobe AIR 1.0 和更高版本

BitmapData 类包含一组用于处理像素数据值的方法。

处理单个像素

在像素级别更改位图图像的外观时,您首先需要获取要处理的区域中包含的像素的颜色值。使用 getPixel() 方法可读取这些像素值。

getPixel() 方法从作为参数传递的一组 x, y(像素)坐标中检索 RGB 值。如果您要处理的像素包括透明度(Alpha 通道)信息,则需要使用 getPixel32() 方法。此方法也可以检索 RGB 值,但与 getPixel() 不同,getPixel32() 返回的值包含表示所选像素的 Alpha 通道(透明度)值的附加数据。

或者,如果只想更改位图中包含的某个像素的颜色或透明度,则可以使用 setPixel()setPixel32() 方法。若要设置像素的颜色,只需将 x、y 坐标和颜色值传递给这两种方法之一即可。

以下示例使用 setPixel() 在绿色 BitmapData 背景上绘制交叉形状。然后,此示例使用 getPixel() 从坐标 50, 50 处的像素中检索颜色值并跟踪返回的值。

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

如果要读取一组像素而不是单个像素的值,请使用 getPixels() 方法。此方法从作为参数传递的矩形像素数据区域中生成字节数组。字节数组的每个元素(即像素值)都是无符号的整数(32 位未经相乘的像素值)。

相反,若要更改(或设置)一组像素的值,请使用 setPixels() 方法。此方法需要联合使用两个参数(rectinputByteArray)来输出像素数据 (inputByteArray) 的矩形区域 (rect)。

inputByteArray 中读取(或写入)数据时,会为数组中的每个像素调用 ByteArray.readUnsignedInt() 方法。如果由于某些原因,inputByteArray 未包含像素数据的整个矩形,则该方法会停止处理该点处的图像数据。

必须记住的是,对于获取和设置像素数据,字节数组需要有 32 位 Alpha、红、绿、蓝 (ARGB) 像素值。

以下示例使用 getPixels()setPixels() 方法将一组像素从一个 BitmapData 对象复制到另一个对象:

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;

像素级别冲突检测

BitmapData.hitTest() 方法可以在位图数据和另一个对象或点之间执行像素级别冲突检测。

BitmapData.hitTest() 方法接受五个参数:

  • firstPoint (Point):此参数指在其上执行点击测试的第一个 BitmapData 的左上角的像素位置。

  • firstAlphaThreshold (uint):此参数指定对于此点击测试视为不透明的最高 Alpha 通道值。

  • secondObject (Object):此参数表示影响区域。secondObject 对象可以是 Rectangle、Point、Bitmap 或 BitmapData 对象。此对象表示在其上执行冲突检测的点击区域。

  • secondBitmapDataPoint (Point):此可选参数用于在第二个 BitmapData 对象中定义像素位置。只有当 secondObject 的值为 BitmapData 对象时,才使用此参数。默认值为 null

  • secondAlphaThreshold (uint):此可选参数表示在第二个 BitmapData 对象中视为不透明的最高 Alpha 通道值。默认值为 1。仅当 secondObject 的值是 BitmapData 对象并且这两个 BitmapData 对象都透明时,才使用此参数。

在不透明图像上执行冲突检测时,请牢记,ActionScript 会将图像视为完全不透明的矩形(或边框)。或者,在透明的图像上执行像素级别点击测试时,需要两个图像都是透明的。除此之外,ActionScript 还使用 Alpha 阈值参数来确定像素在哪点开始从透明变为不透明。

以下示例创建三个位图图像并使用两个不同冲突点(一个返回 false,另一个返回 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