AS3如何检查的BitmapData是空的BitmapData

2023-09-08 14:12:20 作者:清欢一刻

我有一个code删除屏蔽的影片剪辑。 (学分这里) 我想知道我可以检查整个影片剪辑中被删除。 所以我想我必须检查的BitmapData是空的,但我可能是可怕的错误! 如何检查,如果影片剪辑的每个像素被删除? 当然,我下面的例子是错误的,但我认为它是类似的东西。

 如果(erasableBitmapData =空)
    {
    跟踪(空)
    }
 

  VAR LINESIZE:数= 40;
    VAR doDraw:布尔= FALSE;
    VAR resumeDrawing:布尔= FALSE;

    VAR erasableBitmapData:的BitmapData =新的BitmapData(700,500,真实,0xFFFFFFFF的);
    VAR erasableBitmap:位图=新位图(erasableBitmapData);
    erasableBitmap.cacheAsBitmap = TRUE;
    的addChild(erasableBitmap);

    maskee.cacheAsBitmap = TRUE;
    maskee.mask = erasableBitmap;

    VAR eraserClip:雪碧=新的Sprite();
    initEraser();
    功能initEraser():无效{
        eraserClip.graphics.lineStyle(LINESIZE,为0xFF0000);
        eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
    }

    VAR drawnBitmapData:的BitmapData =新的BitmapData(700,500,真实,00000000);
    VAR drawnBitmap:位图=新位图(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);

    功能startDrawing(E:的MouseEvent):无效{
        eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
        doDraw = TRUE;
    }

    功能stopDrawing(E:的MouseEvent):无效{
        doDraw = FALSE;
        resumeDrawing = FALSE;
    }

    功能maskOut(五:事件):无效{
        如果(doDraw){
            resumeDrawing = TRUE;
        }
    }

    功能maskOver(E:的MouseEvent):无效{
        如果(resumeDrawing){
            resumeDrawing = FALSE;
            eraserClip.graphics.moveTo(stage.mouseX,stage.mouseY);
        }
    }

    功能maskMove(E:的MouseEvent):无效{
        如果(doDraw&安培;&安培;!resumeDrawing){
            eraserClip.graphics.lineTo(stage.mouseX,stage.mouseY);
            drawnBitmapData.fillRect(drawnBitmapData.rect,00000000);
            drawnBitmapData.draw(eraserClip,新的Matrix(),空,BlendMode.NORMAL);
            erasableBitmapData.fillRect(erasableBitmapData.rect,0xFFFFFFFF的);
            erasableBitmapData.draw(drawnBitmap,新的Matrix(),空,BlendMode.ERASE);
        }
            e.updateAfterEvent();
    }


    reset_btn.addEventListener(MouseEvent.CLICK,复位);

    功能复位(五:事件):无效{
        eraserClip.graphics.clear();
        initEraser();
        erasableBitmapData.fillRect(erasableBitmapData.rect,0xFFFFFFFF的);
    }
 

解决方案 F5 从传统ADC迈向Cloud Native ADC 第五篇F5 NGINX与云原生之PaaS平台暴露

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

真正的 findColor 参数的默认值给你围住的所有像素的(pixelColor&安培;面罩)的矩形== emptyColor 是真实的。当alpha值处理, 0xFF000000 的面具可以用来忽略像素的RGB值的,并只检查其alpha值。所以面膜 0xFF000000 和颜色 0xFF000000 将匹配一切完全不透明的像素,而面具 0xFF000000 和颜色 00000000 将匹配所有的完全透明的像素。由于 meddlingwithfire 指出,这不会在这里做的工作。通过 findColor 设置为false,这个过程是一种颠倒,使得矩形将附上所有那些的没有的像素用空的颜色。为不含有其它颜色的位图,其结果将与面积 0 长方形。

  VAR maskColor:UINT = 0xFF000000;
VAR emptyColor:UINT = 00000000;
VAR边界:矩形= erasableBitmapData.getColorBoundsRect(maskColor,emptyColor,假);
如果(bounds.width == 0安培;&安培; bounds.height == 0){
    跟踪(空); //无肉眼可见的像素
}
 

在技术上有一个黑色的透明像素之间的差异 00000000 键,例如红色透明像素 0x00FF0000 - 但没有明显的区别(两者都是不可见的),所以你应该完全忽略的RGB值,像我一样在这个例子中通过使用特殊的面具。

I have a code to erase a masked movieclip. (credits here) I would like to know how I can check if the whole movieclip is been erased. So I thought I had to check if the BitmapData is empty, but I could be terribly wrong! How can I check if every pixel of the movieclip has been erased? Of course my example below is wrong, but I think it has to be something like that.

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);
    }

解决方案

You can check if getColorBoundsRect returns an rectangle with an width and height of 0 for the colour you consider as 'empty', setting the findColor argument to false. There are other ways to do this, but this is at least many times faster than checking every single pixel.

The default value of true for the findColor argument gives you an rectangle that encloses all pixels for those (pixelColor & mask) == emptyColor is true. When dealing with alpha values, a mask of 0xFF000000 can be used to ignore rbg values of a pixel and to only check its alpha value. So the mask 0xFF000000 and the colour 0xFF000000 would match all fully opaque pixels, while the mask 0xFF000000 and the colour 0x00000000 would match all fully transparent pixels. As meddlingwithfire pointed out, this won't do the job here. By setting findColor to false, this process is kind of reversed so that the rectangle will enclose all pixels that are not using the empty colour. For bitmaps containing no other colours, the result will be a rectangle with an area of 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
}

Technically there is a difference between a black transparent pixel 0x00000000 and for example a red transparent pixel 0x00FF0000 - but there is no visible difference (both are invisible) so you should ignore the rgb values completely, as I did in the example by using that particular mask.