代码之家  ›  专栏  ›  技术社区  ›  BladePoint

AS3:创建位图数据着色副本的最有效方法

  •  0
  • BladePoint  · 技术社区  · 6 年前

    我有一个 BitmapData 由生成 draw ing a公司 DisplayObject 我想做一个纯白的剪影 位图数据 。似乎有两种方法可以做到这一点:

    1. 应用 ColorTransform 显示对象 然后有一个新的 位图数据 具有相同的尺寸 信息技术
    2. 新建 位图数据 然后 copyPixels 原始,然后应用 颜色变化 通过 BitmapData.colorTransform

    也不 位图数据 将显示在 Bitmap ,因此应用 颜色变化 这不是一种选择。它们会变成椋鸟 Texture

    哪种方法更有效?我会自己运行一些基准测试,但我担心答案将取决于正在绘制的DisplayObject的大小和复杂性。也许 复制像素 当尺寸较小时,方法会更好;如果尺寸较大,方法会更差,并且 如果要绘制的DisplayObject简单,方法会更好;如果复杂,方法会更差。还有copyPixels和BitmapData。在GPU上完成的颜色转换方法?如果是这样的话,我想这会使事情变得对他们有利。

    1 回复  |  直到 6 年前
        1
  •  1
  •   BladePoint    6 年前

    所以我做了一些基准测试,在draw方法的最佳情况下 DisplayObject 要绘制的只是一个彩色矩形,无论大小,绘制总是比复制像素快33%左右。然后我试着用一些复杂的 显示对象 里面有很多形状,在这种情况下,绘制速度要慢300%到400%。所以答案是“视情况而定”。但我不得不说,使用draw方法的速度最多可以提高33%,但如果 显示对象 是复杂的。

    我对copyPixels/colorTransform方法和getPixels/setPixels方法做了一些额外的测试,值得注意的是,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