2

我希望能够抓取嵌套在其他转换后的DisplayObject(旋转、缩放、拉伸的对象)中的 DisplayObject 的副本,并能够将其标记回相同的视觉位置,但在舞台层上。本质上,能够克隆嵌套的 DisplayObject,但能够将克隆添加到舞台层,但使其与原始对象(相同的位置、比例、旋转)完美对齐(视觉上)

我一直在从事以下工作:

// draw the pixels of a displayobject into a new bitmap object
var bitmapData:BitmapData = new BitmapData(nestedSprite.width, nestedSprite.height, true, 0xFFFFFF);
var bitmap:Bitmap = new Bitmap(bitmapData);
bitmapData.draw(nestedSprite);

// put the copy on the top most layer
stage.addChild(bitmap);

// position the copy to perfectly overlay the original, but on the top stage layer
var point:Point = nestedSprite.localToGlobal(new Point(0, 0));
bitmap.x = point.x;
bitmap.y = point.y;

但这仅适用于父母未转换的 displayObjects;(0,0)对于完全位于原点的 displayObjetcs 。对于居中对齐的对象或缩放的父对象等,它会崩溃。

我知道我可以在.draw()方法中添加一个矩阵参数,以及一个剪切矩形,然后缩放我的位图,或者将一个对象的变换设置为另一个,或者使用.transform.concatenatedMatrix,或者使用nestedObject.getBounds(null),或者nestedSprite.getBounds(nestedSprite),等等。但我有不幸的是,陷入了对这个问题进行试错编程,并且有很多变量,这从来都不是解决编程问题的好方法。

4

2 回答 2

1

我相信这个函数应该可以工作,唯一的额外步骤是偏移连接矩阵,以便目标将在位图的左上角 (0, 0) 处绘制,即使它的原点在其他地方。希望其余部分是不言自明的,但如果有什么没有意义,我可以添加更多评论。

function createBitmapClone(target:DisplayObject):Bitmap {
    var targetTransform:Matrix = target.transform.concatenatedMatrix;
    var targetGlobalBounds:Rectangle = target.getBounds(target.stage);
    var targetGlobalPos:Point = target.localToGlobal(new Point());

    // Calculate difference between target origin and top left.
    var targetOriginOffset:Point = new Point(targetGlobalPos.x - targetGlobalBounds.left, targetGlobalPos.y - targetGlobalBounds.top);

    // Move transform matrix so that top left of target will be at (0, 0).
    targetTransform.tx = targetOriginOffset.x;
    targetTransform.ty = targetOriginOffset.y;

    var cloneData:BitmapData = new BitmapData(targetGlobalBounds.width, targetGlobalBounds.height, true, 0x00000000);
    cloneData.draw(target, targetTransform);
    var clone:Bitmap = new Bitmap(cloneData);

    // Move clone to target's global position, minus the origin offset.
    clone.x = targetGlobalPos.x - targetOriginOffset.x;
    clone.y = targetGlobalPos.y - targetOriginOffset.y;

    return clone;
}

不幸的是,如果 DisplayObjects 上有任何过滤器,pixelBounds 似乎返回 (0, 0) 的原点,这显然会破坏事情。

编辑:替换target.transform.pixelBoundstarget.getBounds(target.stage)略有改进。如果有过滤器,这可以保持位置正确,但仍不会包含父 DisplayObjects上的过滤器,并且目标上的过滤器可以与 Bitmap 的边缘重叠。我不确定是否有一种简单的方法可以解决这个问题。

更新: Jimmi Heiserman 发现如果 swf 被缩放,这个函数就会被破坏。没有stage.scaleMode = StageScaleMode.NO_SCALE;stageWidthandstageHeight参数似乎保持不变,所以我发现的唯一(相当hacky)解决方法是添加一个“未缩放”测试Sprite并使用 concatenatedMatrix来调整克隆的位置和比例:

function createScaledBitmapClone(target:DisplayObject):Bitmap {
    var targetTransform:Matrix = target.transform.concatenatedMatrix;
    var targetGlobalBounds:Rectangle = target.getBounds(target.stage);
    var targetGlobalPos:Point = target.localToGlobal(new Point());

    // Calculate difference between target origin and top left.
    var targetOriginOffset:Point = new Point(targetGlobalPos.x - targetGlobalBounds.left, targetGlobalPos.y - targetGlobalBounds.top);

    // Create a test Sprite to check if the stage is scaled.
    var testSprite:Sprite = new Sprite();
    target.stage.addChild(testSprite);
    var testMatrix:Matrix = testSprite.transform.concatenatedMatrix;
    target.stage.removeChild(testSprite);

    // Move transform matrix so that top left of target will be at (0, 0).
    targetTransform.tx = targetOriginOffset.x * testMatrix.a;
    targetTransform.ty = targetOriginOffset.y * testMatrix.d;

    var cloneData:BitmapData = new BitmapData(targetGlobalBounds.width * testMatrix.a, targetGlobalBounds.height * testMatrix.d, true, 0x00000000);
    cloneData.draw(target, targetTransform);
    var clone:Bitmap = new Bitmap(cloneData);

    // Move clone to target's global position, minus the origin offset, and cancel out stage scaling.
    clone.x = targetGlobalPos.x - targetOriginOffset.x;
    clone.y = targetGlobalPos.y - targetOriginOffset.y;
    clone.scaleX = 1 / testMatrix.a;
    clone.scaleY = 1 / testMatrix.d;

    return clone;
}
于 2013-01-25T13:09:16.560 回答
0

您是否尝试过将父母转换为画图?draw将变换矩阵作为第二个参数。

如果你对父母有一个句柄,你可以使用这样的东西

bitmapData.draw(nestedSprite, parent.transform.matrix);
于 2013-01-24T03:26:39.740 回答