2011-09-02 148 views
3

我有一个代码可以擦除蒙版的动画片段。 (学分here) 我想知道如何检查整个动画片段是否被删除。 所以我想我不得不检查BitmapData是否为空,但我可能是非常错误的! 如何检查动画片的每个像素是否已被擦除?
当然我下面的例子是错误的,但我认为它应该是这样的。AS3如何检查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); 
    } 

回答

6

您可以检查是否getColorBoundsRect返回与您认为是“空”的颜色的宽度和高度0的矩形,设置findColor参数为false。还有其他的方法可以做到这一点,但这至少比检查每一个像素要快很多倍。

findColor参数的默认值为true将为您提供一个包含所有像素的矩形,其中(pixelColor & mask) == emptyColor为true。在处理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值,和我一样在示例中通过使用该特定掩码。

+0

非常感谢您的回答,我尝试了很多东西,这是朝着正确的方向? ------------------------------------- var colorBoundsRect:Rectangle = erasableBitmapData.getColorBoundsRect(0x00FFFFFF, 0x00FF0000,true); if(colorBoundsRect。?= 0){trace(“empty”);} – Opoe

+0

@Opoe更新了答案。 – Kapep

+0

谢谢,你的解释是非常可以理解和清楚的。我得到一个1152错误,因为; 'var mask。这可能是因为我已经在这行代码中使用了'mask' maskee.mask = erasableBitmap; ? – Opoe

1

创建基准“空”BitmapData实例。使用该BitmapData的比较方法,传入“可能为空”的BitmapData。您将获得一个新的BitmapData引用,它具有两者之间的像素差异。使用新的BitmapData参考,您可以访问直方图方法以获取每个通道的所有计数列表。如果空的BitmapData实例和“可能为空”的BitmapData实例完全相同,那么您的直方图通道将会将BitmapData中的像素总数作为每个通道的零索引中的计数(因为情况中的BitmapData差异的相同数据将被填充0x00000000像素)。

应该相对较快,因为您可以依靠AS引擎来查看每个像素,而不必手动调用昂贵的getPixel()方法。

使用颜色边界方法会导致误报。如果您的位图在左上角和左下角位置相同,那么您的颜色边界矩形将包含整个区域,即使中间的所有像素可能完全不同。

+0

谢谢你的回答 – Opoe

1

BitmapData.compare(BitmapData)函数返回包含该主叫2个BitmapData S之间的差的新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 
} 

draw() documentation

compare() documentation

+0

谢谢你,克里斯!我会尽快尝试这个答案,并让你知道它是如何:) – Opoe

+0

它没有工作,我认为这是因为我用一个面具'重新安置'擦除的像素,你怎么看? – Opoe