3

我有一个代码可以删除蒙面的影片剪辑。(这里的学分)我想知道如何检查整个电影剪辑是否被删除。所以我想我必须检查 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);
    }
4

3 回答 3

6

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

参数的默认值 true 为findColor您提供了一个包含所有像素的矩形,这些像素为(pixelColor & mask) == emptyColortrue。在处理 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 值,就像我在示例中使用该特定蒙版所做的那样。

于 2011-09-02T13:04:07.980 回答
1

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

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

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

于 2011-09-02T18:22:59.843 回答
1

BitmapData.compare(BitmapData)函数返回一个包含调用两个sBitmapData之间差异的新值,或者如果对象是等效的(具有相同的宽度、高度和相同的像素值),则该方法返回数字 0。这意味着您可以使用以下内容检查 a 是否包含图形BitmapDataBitmapDataDisplayObject

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
}

绘制()文档

比较()文档

于 2013-04-21T12:19:12.220 回答