我想使用AS3检查(32位ARGB)PNG图像,看它是否包含任何(半)透明像素(返回true
或false
)。最快的方法是什么?
答案 0 :(得分: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;
}
答案 1 :(得分: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();
做一个内存,你应该{@ 1}}你想要的第二个循环(否则它会一直运行,直到它检查每个像素在你的图像中。为了比较,256x256图像将运行65,536次。
为了清楚起见:
break;
,G为>> 0 & 255
,R为>> 8 & 255