AS3:创建BitmapData的有色副本的最有效方法

时间:2018-05-21 16:13:34

标签: actionscript-3 optimization textures bitmapdata

我有一个由BitmapData draw生成的DisplayObject。我想创建一个BitmapData的纯白色轮廓副本。似乎有两种方法可以做到这一点:

  1. ColorTransform应用于DisplayObject,然后使用相同尺寸BitmapData的新draw
  2. 创建新的BitmapData,然后copyPixels原始文件,然后通过ColorTransform申请BitmapData.colorTransform
  3. BitmapData中不会显示Bitmap,因此将ColorTransform应用于此Texture不是一种选择。相反,他们会变成Starling copyPixels

    哪种方法更有效?我自己会运行一些基准测试,但我担心答案取决于所绘制的DisplayObject的大小和复杂程度。也许draw方法在大小较小时会更好,如果大,则更差;如果要绘制的DisplayObject很简单,Please use dropna() to drop rows with missing target values. 方法会更好,如果它很复杂则更差。还有,在GPU上完成copyPixels和BitmapData.colorTransform方法吗?如果是这样,我认为这会使事情倾向于他们的利益。

1 个答案:

答案 0 :(得分:1)

所以我做了一些基准测试,并且在绘制方法的最佳场景中,要绘制的DisplayObject只是一个彩色矩形,绘制总是比copyPixels快33%左右,无论大小。然后我尝试使用一些内部有很多形状的复杂DisplayObject,在这些情况下,绘制速度慢了300%到400%。所以答案是"它取决于"。但我不得不说,使用draw方法可以获得最多33%的速度提升,但如果DisplayObject很复杂,则存在巨大的下行潜力。

我针对getPixels / setPixels方法对copyPixels / colorTransform方法进行了一些额外的测试,显然getPixels / setPixels方法慢了20倍!这是我的copyPixels方法:

var start_time:int = getTimer();
var s1:S1 = new S1(); //S1 is simply a 100x100 red circle
var bmd1:BitmapData = new BitmapData(s1.width,s1.height,true,0x00000000);
bmd1.drawWithQuality(s1,null,null,null,null,false,StageQuality.HIGH);
var bmd2:BitmapData;
var sourceRect:Rectangle = new Rectangle(0,0,bmd1.width,bmd1.height);
var point00:Point = new Point();
var colorTransform:ColorTransform = new ColorTransform(0,0,0,1,255,255,255,0);
var w:uint = bmd1.width,
    h:uint = bmd1.height,
    pixelHex:uint,
    pixelAlpha:uint;
var ba:ByteArray;
for (var i:uint=0; i<1000; i++) {
    bmd2 = new BitmapData(w,h,true,0x00000000);
    bmd2.copyPixels(bmd1,sourceRect,point00);
    bmd2.colorTransform(sourceRect,colorTransform);
}
trace("execution time: ", getTimer()-start_time); //execution time:  74

这是我的循环getPixels方法:

for (var i:uint=0; i<1000; i++) {
    ba = bmd1.getPixels(sourceRect);
    ba.position = 0;
    while (ba.bytesAvailable > 0) {
        pixelHex = ba.readUnsignedInt();
        pixelAlpha = pixelHex >>> 24;
        if (pixelAlpha > 0) {
            ba.position -= 4;
            ba.writeUnsignedInt((pixelAlpha<<24)|0xffffff);
        }
    }
    ba.position = 0;
    bmd2 = new BitmapData(w,h,true,0x00000000);
    bmd2.setPixels(sourceRect,ba);
}
trace("execution time: ", getTimer()-start_time); //execution time:  1349