この関数は機能するはずだと思います。唯一の余分なステップは、連結されたマトリックスをオフセットして、原点が別の場所にあったとしても、ターゲットがビットマップの左上 (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.pixelBounds
た。target.getBounds(target.stage)
これにより、フィルターがある場合は位置が正しく保たれますが、親 DisplayObjects のフィルターは含まれず、ターゲットのフィルターは Bitmap のエッジに重なる可能性があります。それを回避する簡単な方法があるかどうかはわかりません。
更新: Jimmi Heiserman は、swf がスケーリングされるとこの機能が壊れることを発見しました。とパラメータは変更されていないstage.scaleMode = StageScaleMode.NO_SCALE;
ように見えるので、私が見つけた唯一の (かなりハックな) 回避策は、「スケーリングされていない」テスト スプライトを追加し、それを使用してクローンの位置とスケールを調整することです。stageWidth
stageHeight
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;
}