我想使用 AS3 检查(32 位 ARGB)PNG 图像,看看它是否包含任何(半)透明像素(返回true
或false
)。最快的方法是什么?
问问题
2706 次
2 回答
5
很久以前,我一直在寻找相同的东西,并尝试使用循环来检查每个像素。但这需要花费大量时间并消耗大量 CPU。幸运的是,我们有一个BitmapData.compare()
方法,如果比较的 BitmapData 对象有任何差异,它会输出一个 Bitmapdata。
还有一个BitmapData.transparent
属性,它实际上直接给你一个布尔值的答案。但是我自己从来没有直接在加载的图像上使用它。
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.geom.Point;
var ldr:Loader = new Loader();
var req:URLRequest = new URLRequest('someImage.png');
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,imgLoaded);
ldr.load(req);
function imgLoaded(e:Event):void {
var l:Loader = e.target.loader,
bmp:Bitmap = l.content as Bitmap,
file:String = l.contentLoaderInfo.url.match(/[^\/\\]+$/)[0];
trace(bmp.bitmapData.transparent);
// I think this default property should do it but
// in case it does not, here's another approach:
var trans:Boolean = isTransparent(bmp.bitmapData);
trace(file,'is'+(trans ? '' : ' not'),'transparent');
}
function isTransparent(bmpD:BitmapData):Boolean {
var dummy:BitmapData = new BitmapData(bmpD.width,bmpD.height,false,0xFF6600);
// create a BitmapData with the size of the source BitmapData
// painted in a color (I picked orange)
dummy.copyPixels(bmpD,dummy.rect,new Point());
// copy pixels of the original image onto this orange BitmapData
var diffBmpD:BitmapData = bmpD.compare(dummy) as BitmapData;
// this will return null if both BitmapData objects are identical
// or a BitmapData otherwise
return diffBmpD != null;
}
于 2012-11-26T17:33:54.240 回答
2
不幸的是,我知道的唯一方法是手动操作。可能有一种内置的方法,但我猜它会使用下面描述的相同方法
var bytes:ByteArray = ( loader.content as Bitmap ).bitmapData.getPixels(); //that getter may be incorrect. I'd verify the property names are correct first
var bLength:Number = bytes.length; //you'll gain considerable speed by saving the length to memory rather than accessing it repeatedly
for ( var i:Number = 0; i < bLength; i++ ) {
var alpha:uint = bytes[i] >> 24 & 255;
if ( alpha > 0 && alpha < 255 ) {
//put code in here that will run if it is semi transparent
}
if ( alpha == 255 ) {
//put code in here that will run if it is entirely opaque
}
if ( alpha == 0 ) {
//put code in here that will run if it is entirely transparent
}
}
请记住,ByteArray
每个像素都有 32 位(或 4 字节(每字节 8 位))的数据。bytes.clear();
循环完成后,为了记忆,你绝对应该做一个循环,你也应该break;
在你达到你想要的第二个循环(否则它将继续运行,直到它检查图像中的每个像素。一个 256x256 的图像将运行 65,536次,为了比较)。
只是为了清楚起见:
- RGBA/ARGB 的测量值为 0-255
- 0 为黑色 (0x000000),255 为白色 (0xffffff)
- alpha 字节越黑,越透明
- 我们使用简单的按位移位来获取该字节的实际值(位 24-32)并将其设置为 0 到 255 之间的值
- 您也可以对 RGB 通道执行此操作。B 是
>> 0 & 255
, G 是>> 8 & 255
, R 是>> 16 & 255
于 2012-11-26T17:09:04.377 回答