我相信这个函数应该可以工作,唯一的额外步骤是偏移连接矩阵,以便目标将在位图上的左上角 (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) 的原点,这显然会破坏事物。
Edit:已更换target.transform.pixelBounds
with target.getBounds(target.stage)
作为一个轻微的改进。如果有过滤器,这可以保持位置正确,但是父 DisplayObject 上的过滤器仍然不会被包含在内, and 目标上的滤镜可以与位图的边缘重叠。我不确定是否有一种简单的方法可以解决这个问题。
Update:Jimmi Heiserman 发现如果缩放 swf,此功能就会被破坏。没有stage.scaleMode = StageScaleMode.NO_SCALE;
不过,stageWidth
and stageHeight
参数似乎保持不变,所以我发现的唯一(相当hacky)的解决方法是添加一个“未缩放的”测试精灵并使用its 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;
}