가능한 한 많은 인스턴스를 다시 사용하여 BitmapData 클래스의 사용을 최적화하는 것이 중요합니다. Flash Player 10.1 및 AIR 2.5에는 모든 플랫폼에서 사용 가능한 BitmapData 단일 참조라는 새 기능이 추가되었습니다. 포함된 이미지에서 BitmapData 인스턴스를 만들 때 모든 BitmapData 인스턴스에 대해 단일 버전의 비트맵이 사용됩니다. 나중에 비트맵이 수정되면 메모리에 고유한 비트맵이 제공됩니다. 포함된 이미지는 라이브러리 또는 [Embed] 태그에서 가져올 수 있습니다.
참고:
Flash Player 10.1 및 AIR 2.5에서는 비트맵을 자동으로 재사용하기 때문에 기존 내용도 이 새로운 기능으로 인해 이점을 얻을 수 있습니다.
포함된 이미지를 인스턴스화할 때 연결된 비트맵이 메모리에 만들어집니다. Flash Player 10.1 및 AIR 2.5 이전에는 다음 다이어그램에서처럼 인스턴스별로 각각의 비트맵이 메모리에 제공되었습니다.
Flash Player 10.1 및 AIR 2.5 이전의 경우 메모리의 비트맵
Flash Player 10.1 및 AIR 2.5에서는 같은 이미지에 대한 인스턴스를 여러 개 만들 경우 단일 버전의 비트맵이 모든 BitmapData 인스턴스에 사용됩니다. 다음 다이어그램에서는 이러한 개념을 보여 줍니다.
Flash Player 10.1 및 AIR 2.5의 경우 메모리의 비트맵
이 방법은 비트맵이 많은 응용 프로그램에서 사용하는 메모리의 양을 크게 줄여줍니다. 다음 코드는
Star
기호에 대한 인스턴스를 여러 개 만듭니다.
const MAX_NUM:int = 18;
var star:BitmapData;
var bitmap:Bitmap;
for (var i:int = 0; i<MAX_NUM; i++)
{
for (var j:int = 0; j<MAX_NUM; j++)
{
star = new Star(0,0);
bitmap = new Bitmap(star);
bitmap.x = j * star.width;
bitmap.y = i * star.height;
addChild(bitmap)
}
}
다음 이미지는 코드의 결과를 보여 줍니다.
예를 들어 위 애니메이션은 Flash Player 10에서 약 1008KB의 메모리를 사용하지만 Flash Player 10.1에서는 데이크톱이나 휴대 장치에서 단지 4KB만 사용합니다.
다음 코드에서는 한 BitmapData 인스턴스를 수정합니다.
const MAX_NUM:int = 18;
var star:BitmapData;
var bitmap:Bitmap;
for (var i:int = 0; i<MAX_NUM; i++)
{
for (var j:int = 0; j<MAX_NUM; j++)
{
star = new Star(0,0);
bitmap = new Bitmap(star);
bitmap.x = j * star.width;
bitmap.y = i * star.height;
addChild(bitmap)
}
}
var ref:Bitmap = getChildAt(0) as Bitmap;
ref.bitmapData.pixelDissolve(ref.bitmapData, ref.bitmapData.rect, new Point(0,0),Math.random()*200,Math.random()*200, 0x990000);
다음 이미지는
Star
인스턴스 하나를 수정한 결과를 보여 줍니다.
내부적으로 런타임에서 비트맵을 메모리에 자동으로 할당하고 만들어 픽셀 수정을 처리합니다. BitmapData 클래스의 메서드가 호출되면 픽셀이 수정되어 새 인스턴스가 메모리에 만들어지며 다른 모든 인스턴스는 업데이트되지 않습니다. 다음 그림에서는 이 개념을 보여 줍니다.
메모리에서 비트맵 하나를 수정한 결과
별 하나가 수정되면 메모리에 새로운 사본이 만들어집니다. 결과적으로 Flash Player 10.1 및 AIR 2.5에서 애니메이션은 메모리 8KB를 사용합니다.
이전 예제에서 변형에 각 비트맵을 개별적으로 사용할 수 있습니다. 타일링 효과만 만들려면
beginBitmapFill()
메서드가 가장 적절한 메서드입니다.
var container:Sprite = new Sprite();
var source:BitmapData = new Star(0,0);
// Fill the surface with the source BitmapData
container.graphics.beginBitmapFill(source);
container.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
addChild(container);
이 방법은 단일 BitmapData 인스턴스만 만들었을 때와 같은 결과를 생성합니다. 별을 지속적으로 회전하려면 각 Star 인스턴스에 액세스하는 대신에 각 프레임에서 회전되는 Matrix 객체를 사용하십시오. 다음과 같이 Matrix 객체를
beginBitmapFill()
메서드에 전달합니다.
var container:Sprite = new Sprite();
container.addEventListener(Event.ENTER_FRAME, rotate);
var source:BitmapData = new Star(0,0);
var matrix:Matrix = new Matrix();
addChild(container);
var angle:Number = .01;
function rotate(e:Event):void
{
// Rotate the stars
matrix.rotate(angle);
// Clear the content
container.graphics.clear();
// Fill the surface with the source BitmapData
container.graphics.beginBitmapFill(source,matrix,true,true);
container.graphics.drawRect(0,0,stage.stageWidth,stage.stageHeight);
}
이 기법을 사용하면 효과를 만드는 데 ActionScript 루프가 필요하지 않습니다. 런타임은 모든 작업을 내부적으로 수행합니다. 다음 이미지는 별을 변환한 결과를 보여 줍니다.
이 방법을 사용하면 원래 소스 BitmapData 객체를 업데이트할 경우 스테이지에서 사용된 다른 모든 곳에서 자동으로 업데이트되므로 이 기술은 매우 유용하게 사용할 수 있습니다. 그러나 이 방식을 사용하면 이전 예제에서처럼 각 별의 크기를 개별적으로 조절할 수 없습니다.
참고:
같은 이미지에 대한 인스턴스를 여러 개 사용할 경우 클래스가 메모리의 원래 비트맵과 연관되는지 여부에 따라 그리기가 달라집니다. 클래스가 비트맵과 연관되지 않으면 이미지는 비트맵 채우기가 포함된 Shape 객체로 그려집니다.