【问题标题】:AS3 - Check if BitmapData is completely obscured by other BitmapDataAS3 - 检查 BitmapData 是否被其他 BitmapData 完全遮挡
【发布时间】:2012-04-30 22:47:22
【问题描述】:

我正在检查 BitmapData 对象是否完全被 BitmapData 对象遮挡。有没有类似 hitTest 函数的东西,但它确保每个像素都被覆盖而不是任何像素?

编辑:在检查对象是否被遮挡时不包括透明像素是很重要的。

【问题讨论】:

    标签: actionscript-3 bitmapdata hittest


    【解决方案1】:

    毕竟这实际上是一个非常简单的解决方案!基本上你所做的只是在重叠位图占据的矩形区域中捕获重叠位图的像素值。然后您遍历该值向量,只要您没有 0(完全透明的像素),那么您就已经完全覆盖了下面的位图。

    这是我在这个测试中使用的两个位图:

    重叠位图:

    重叠位图:

    代码:

    import flash.display.BitmapData;
    import flash.display.Bitmap;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.utils.ByteArray;
    import flash.geom.Rectangle;
    
    var coveredBitmapData:BitmapData = new CoveredBitmapData();
    var coveringBitmapData:BitmapData = new CoveringBitmapData();
    
    
    var coveringBitmap:Bitmap = new Bitmap(coveringBitmapData, "auto", true);
    var coveredBitmap:Bitmap = new Bitmap(coveredBitmapData, "auto", true);
    
    coveredBitmap.x = Math.random() * (stage.stageWidth - coveredBitmap.width);
    coveredBitmap.y = Math.random() * (stage.stageHeight - coveredBitmap.height);
    
    stage.addChild(coveredBitmap);
    stage.addChild(coveringBitmap);
    
    stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMovement);
    
    function onMouseMovement(e:MouseEvent):void
    {
        coveringBitmap.x = mouseX - (coveringBitmap.width * .5);
        coveringBitmap.y = mouseY - (coveringBitmap.height * .5);
    
        checkIfCovering(coveringBitmap, coveredBitmap);
    }
    
    function checkIfCovering(bitmapA:Bitmap, bitmapB:Bitmap):Boolean
    {
        //bitmapA is the covering bitmap, bitmapB is the bitmap being overlapped
    
        var overlappedBitmapOrigin:Point = new Point(bitmapB.x, bitmapB.y);
    
        var localOverlappedBitmapOrigin:Point = bitmapA.globalToLocal(overlappedBitmapOrigin);
    
        var overlappingPixels:Vector.<uint> = bitmapA.bitmapData.getVector(new Rectangle(localOverlappedBitmapOrigin.x, localOverlappedBitmapOrigin.y, bitmapB.width, bitmapB.height));
    
        if(overlappingPixels.length == 0) {
            //This means that there is no bitmap data in the rectangle we tried to capture. So we are not at all covering the underlying bitmap.
            return false;
        }
    
        var i:uint = 0;
        for(i; i < overlappingPixels.length; ++i) {
            if(overlappingPixels[i] == 0) {
                return false;
            }
        }
    
        return true;
    }
    

    【讨论】:

    • 我想知道,代码是否还关注 50% 透明或 25% 透明等像素?抗锯齿位图通常具有这样的像素。那些呢?
    • 顺便说一句,我尝试了代码,但对我不起作用。它总是显示 false ?我在我的库中使用了 2 个 png。我有什么遗漏吗?
    • 是的,先生,如果您阅读我代码中的 cmets,我正在检查绝对 100% 透明像素。您将不得不相应地调整代码。
    • 我相信向量中的 uint 值是 RRGGBBAA,所以在这种情况下,您可以使用最后 2 位数字根据您希望遵守的阈值来确定您的 alpha 值。
    • 如果您正在检查 alpha 数字,请务必使用无符号移位 (>>>),否则您会得到让您发疯的疯狂结果。所以像 alphaComp = myColor >>> 24;
    【解决方案2】:

    所以你想看看object2 是否完全覆盖object1(两个位图)?

    var left:Boolean = object2.x <= object1.x;
    var top:Boolean = object2.y <= object1.y;
    var right:Boolean = object2.x + object2.width >= object1.x + object1.width;
    var bottom:Boolean = object2.y + object2.height >= object1.y + object1.height;
    
    
    if(left && right && top && bottom)
    {
        // Completely covered.
    }
    

    【讨论】:

    • +1,但是如果覆盖位图有一个带有完全透明像素的 alpha 通道呢? :O 我认为您需要将两个位图都绘制到第三个位图并进行一些填充技巧和像素采样,或者将覆盖位图的 Alpha 通道复制到第二个位图并检查是否保留任何原始像素?
    • 我忘了说透明像素的大小写很重要。
    • @Anonymous1 你是说知道透明像素是否覆盖第二个位图很重要,还是说你只关心位图对象的边界是否覆盖了第二个位图的边界?第二个位图?
    • @Anonymous1 你看似很小的编辑提供了太多的额外信息和篡改,我今晚才有时间。
    • @AscensionSystems 重要的是,如果一个像素是透明的,则它不会被视为遮挡另一个对象或被另一个对象遮挡。
    猜你喜欢
    • 2011-11-09
    • 2012-07-17
    • 2012-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    • 1970-01-01
    相关资源
    最近更新 更多