我有一个代码来擦除蒙面动画片段。 (学分here) 我想知道如何检查整个动画片段是否已被删除。 所以我认为我必须检查BitmapData是否为空,但我可能非常错! 如何检查动画片段的每个像素是否已被删除? 当然,下面的例子是错误的,但我认为必须是这样的。
if (erasableBitmapData = empty)
{
trace("empty")
}
var lineSize:Number=40;
var doDraw:Boolean=false;
var resumeDrawing:Boolean=false;
var erasableBitmapData:BitmapData = new BitmapData(700, 500, true, 0xFFFFFFFF);
var erasableBitmap:Bitmap = new Bitmap(erasableBitmapData);
erasableBitmap.cacheAsBitmap = true;
addChild(erasableBitmap);
maskee.cacheAsBitmap = true;
maskee.mask = erasableBitmap;
var eraserClip:Sprite = new Sprite();
initEraser();
function initEraser():void {
eraserClip.graphics.lineStyle(lineSize,0xff0000);
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
}
var drawnBitmapData:BitmapData = new BitmapData(700, 500, true, 0x00000000);
var drawnBitmap:Bitmap = new Bitmap(drawnBitmapData);
stage.addEventListener(MouseEvent.MOUSE_MOVE,maskMove);
stage.addEventListener(MouseEvent.ROLL_OUT, maskOut);
stage.addEventListener(MouseEvent.ROLL_OVER,maskOver);
stage.addEventListener(MouseEvent.MOUSE_DOWN,startDrawing);
stage.addEventListener(MouseEvent.MOUSE_UP,stopDrawing);
function startDrawing(e:MouseEvent):void {
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
doDraw=true;
}
function stopDrawing(e:MouseEvent):void {
doDraw=false;
resumeDrawing = false;
}
function maskOut(e:Event):void {
if (doDraw){
resumeDrawing = true;
}
}
function maskOver(e:MouseEvent):void {
if (resumeDrawing){
resumeDrawing = false;
eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
}
}
function maskMove(e:MouseEvent):void {
if (doDraw && !resumeDrawing){
eraserClip.graphics.lineTo(stage.mouseX,stage.mouseY);
drawnBitmapData.fillRect(drawnBitmapData.rect, 0x00000000);
drawnBitmapData.draw(eraserClip , new Matrix(), null, BlendMode.NORMAL);
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
erasableBitmapData.draw(drawnBitmap, new Matrix(), null, BlendMode.ERASE);
}
e.updateAfterEvent();
}
reset_btn.addEventListener(MouseEvent.CLICK,reset);
function reset(e:Event):void {
eraserClip.graphics.clear();
initEraser();
erasableBitmapData.fillRect(erasableBitmapData.rect, 0xFFFFFFFF);
}
答案 0 :(得分:6)
您可以检查getColorBoundsRect
是否为您认为为“空”的颜色返回宽度和高度为0
的矩形,并将findColor
参数设置为false。还有其他方法可以做到这一点,但这比检查每个像素要快很多倍。
findColor
参数的默认值true为您提供了一个矩形,其中包含(pixelColor & mask) == emptyColor
的所有像素为真。处理alpha值时,0xFF000000
的掩码可用于忽略像素的rbg值,并仅检查其alpha值。因此,蒙版0xFF000000
和颜色0xFF000000
将匹配所有完全不透明的像素,而蒙版0xFF000000
和颜色0x00000000
将匹配所有完全透明的像素。正如meddlingwithfire指出的那样,这不会起到作用。通过将findColor
设置为false,此过程可以反转,以便矩形将使用空颜色包围所有非的像素。对于不包含其他颜色的位图,结果将是面积为0
的矩形。
var maskColor:uint = 0xFF000000;
var emptyColor:uint = 0x00000000;
var bounds:Rectangle = erasableBitmapData.getColorBoundsRect(maskColor, emptyColor, false);
if (bounds.width == 0 && bounds.height == 0){
trace("empty"); // no visible pixels
}
从技术上讲,黑色透明像素0x00000000
与红色透明像素0x00FF0000
之间存在差异 - 但没有明显差异(两者都不可见),因此您应该完全忽略rgb值正如我在示例中通过使用该特定掩码所做的那样。
答案 1 :(得分:1)
创建基线“空”BitmapData实例。使用BitmapData的比较方法,传入“可能为空”的BitmapData。您将获得一个新的BitmapData引用,它具有两者之间的像素差异。使用新的BitmapData参考,您可以访问直方图方法以获取每个通道的所有计数列表。如果空的BitmapData实例和“可能为空”的BitmapData实例完全相同,那么您的直方图通道将使BitmapData中的像素总数作为每个通道的零索引中的计数(因为在这种情况下BitmapData的差异)等数据将填充0x00000000像素)。
也应该相对较快,因为您可以依靠AS引擎查看每个像素,而不必手动调用昂贵的getPixel()方法。
使用颜色边界方法可能会导致误报。如果你的位图在左上角和左下角位置相同,那么你的颜色边界rect将包含整个区域,即使它们之间的所有像素都可能完全不同。
答案 2 :(得分:1)
BitmapData.compare(BitmapData)
函数返回一个新的BitmapData
,其中包含调用两个BitmapData
之间的差异,或者BitmapData
个对象是否相同(宽度相同) ,高度和相同的像素值),该方法返回数字0.意思是您可以使用以下内容来检查DisplayObject
是否包含图形
var eraseableBitmapData:BitmapData = new BitmapData(264,864,true,0xFFFFFFFF);
//initialise the eraseableBitmapData
eraseableBitmapData.draw(someDisplayOject)
//draw your object's bitmap data
var emptyBitmapData:BitmapData = new BitmapData(264,864,true,0xFFFFFFFF);
//create an identical but empty BitmapData object
if( erasableBitmapData.compare ( emptyBitmapData ) == 0 ) {
trace("empty");//object is completely empty
} else {
trace("not empty");//object still has stuff in
}