使用 PixelBender 将位图大小加倍

发布于 2024-09-01 17:27:05 字数 3226 浏览 5 评论 0原文

我有一个关于像素弯曲器的性能问题。我想放大许多 BitmapData(将它们的大小加倍为新的 BitmapData)。我是用 as3 做的,但想使用 Pixel Bender 来获得更好的性能。在我的机器上,我从像素弯曲器中获得了更好的性能 演示然后是as3。

令我惊讶的是(或者糟糕的编码/理解),我的像素弯曲器的性能差很多——2 秒 vs 1/2 秒!我期望获得至少相同与 as3 的性能。我做错了什么?

我得到了简单的像素弯曲器代码 此处(为了方便参考,它包含在下面)。

package
{

import flash.display.BitmapData;
import flash.display.Shader;
import flash.display.ShaderJob;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.Matrix;

public class flashFlash extends Sprite
{


[Embed ( source="pixelbender/bilinearresample.pbj", mimeType="application/octet-stream" ) ]
private static var BilinearScaling:Class;

public function flashFlash( ):void
{
    stage.align = StageAlign.TOP_LEFT;
    stage.scaleMode = StageScaleMode.NO_SCALE;

    addEventListener( Event.ENTER_FRAME, efCb, false, 0, true );
}

private function efCb( evt:Event ):void
{
    removeEventListener( Event.ENTER_FRAME, efCb, false );

    traceTime( "init" );

    var srcBmd:BitmapData = new BitmapData( 80, 120, false, 0 );
    var destBmd:BitmapData = new BitmapData( 160, 240, false, 0 );

    var mx:Matrix = new Matrix( );
    mx.scale( 2, 2 );
    for (var i:uint = 0; i < 3000; i++)
    {   destBmd.draw( srcBmd, mx );
    }

    traceTime( "scaled with as3" );

    // create and configure a Shader object
    var shader:Shader = new Shader( );
    shader.byteCode = new BilinearScaling( );
    shader.data.scale.value = [.5];
    shader.data.src.input = srcBmd;

    for (var j:uint = 0; j < 3000; j++)
    {
        var shaderJob:ShaderJob = new ShaderJob( );
        shaderJob.shader = shader;
        shaderJob.target = destBmd;
        shaderJob.start( true );
    }

    traceTime( "scaled with pixel bender bilinearresample.pbj" );
}

private static var _lastTraceTime:Number = new Date().getTime();
public static function traceTime( note:String ):Number
{   var nowTime:Number = new Date().getTime();
    var diff:Number = (nowTime-_lastTraceTime);
    trace( "[t" + diff + "] " + note );
    _lastTraceTime = nowTime;
    return diff;
}

}
}

和像素弯曲器代码:

<languageVersion : 1.0;>

kernel BilinearResample
<   namespace : "com.brooksandrus.pixelbender";
    vendor : "Brooks Andrus";
    version : 1;
    description : "Resizes an image using bilinear resampling. Constrains aspect ratio - divide Math.max( input.width / output.width, input.height / output.height ) and pass in to the scale parameter";
>
{
    parameter float scale
    <
        minValue: 0.0;
        maxValue: 1000.0;
        defaultValue: 1.0;
    >;

    input image4 src;
    output pixel4 dst;

    void
    evaluatePixel()
    {
        // scale should be Math.max( src.width / output.width, src.height / output.height )
        dst = sampleLinear( src, outCoord() * scale ); // bilinear scaling
    }
}

I have a performance question about pixel bender. I want to enlarge many BitmapData (double their size into new BitmapData). I was doing this with as3, but wanted to use pixel bender to get better performance. On my machine, I get better performance out of pixel bender demonstrations then as3.

To my surprise (or bad coding / understanding), I am getting much worse performance out of pixel bender -- 2 seconds vs 1/2 second! I expected to get at least the same performance as as3. What am I doing wrong?

I got the straightforward pixel bender code here (and it is included below for easy reference).

package
{

import flash.display.BitmapData;
import flash.display.Shader;
import flash.display.ShaderJob;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.Matrix;

public class flashFlash extends Sprite
{


[Embed ( source="pixelbender/bilinearresample.pbj", mimeType="application/octet-stream" ) ]
private static var BilinearScaling:Class;

public function flashFlash( ):void
{
    stage.align = StageAlign.TOP_LEFT;
    stage.scaleMode = StageScaleMode.NO_SCALE;

    addEventListener( Event.ENTER_FRAME, efCb, false, 0, true );
}

private function efCb( evt:Event ):void
{
    removeEventListener( Event.ENTER_FRAME, efCb, false );

    traceTime( "init" );

    var srcBmd:BitmapData = new BitmapData( 80, 120, false, 0 );
    var destBmd:BitmapData = new BitmapData( 160, 240, false, 0 );

    var mx:Matrix = new Matrix( );
    mx.scale( 2, 2 );
    for (var i:uint = 0; i < 3000; i++)
    {   destBmd.draw( srcBmd, mx );
    }

    traceTime( "scaled with as3" );

    // create and configure a Shader object
    var shader:Shader = new Shader( );
    shader.byteCode = new BilinearScaling( );
    shader.data.scale.value = [.5];
    shader.data.src.input = srcBmd;

    for (var j:uint = 0; j < 3000; j++)
    {
        var shaderJob:ShaderJob = new ShaderJob( );
        shaderJob.shader = shader;
        shaderJob.target = destBmd;
        shaderJob.start( true );
    }

    traceTime( "scaled with pixel bender bilinearresample.pbj" );
}

private static var _lastTraceTime:Number = new Date().getTime();
public static function traceTime( note:String ):Number
{   var nowTime:Number = new Date().getTime();
    var diff:Number = (nowTime-_lastTraceTime);
    trace( "[t" + diff + "] " + note );
    _lastTraceTime = nowTime;
    return diff;
}

}
}

And the pixel bender code:

<languageVersion : 1.0;>

kernel BilinearResample
<   namespace : "com.brooksandrus.pixelbender";
    vendor : "Brooks Andrus";
    version : 1;
    description : "Resizes an image using bilinear resampling. Constrains aspect ratio - divide Math.max( input.width / output.width, input.height / output.height ) and pass in to the scale parameter";
>
{
    parameter float scale
    <
        minValue: 0.0;
        maxValue: 1000.0;
        defaultValue: 1.0;
    >;

    input image4 src;
    output pixel4 dst;

    void
    evaluatePixel()
    {
        // scale should be Math.max( src.width / output.width, src.height / output.height )
        dst = sampleLinear( src, outCoord() * scale ); // bilinear scaling
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

帅气尐潴 2024-09-08 17:27:05

我认为问题在于您实际上是将 Pixel Bender 与本机播放器代码进行比较,而不是与“actionscript”进行比较。我怀疑 Pixel Bender 是否会在这种情况下获胜。

此处发生的缩放 destBmd.draw( srcBmd, mx ); 直接在播放器中编码;这可能是您能达到的最快速度(使用等效算法)。另一方面,您的内核至少必须首先编译(或 JIT 编译)才能运行(可能还有许多其他原因导致它变慢;不过,我不太了解具体细节)。

查看 Flash Player 工程师的博客中的这篇文章:

很久以前,回到Flash Player
8天后我们有了添加一个的想法
进行位图过滤器的通用方法。难的
像我们一样编码位图过滤器
Flash Player 8 不仅不是
灵活,但有添加的负担
大量的本机代码到
播放器并必须对其进行优化
每个平台。问题为
我们一直都是你想要的样子
创建这样的通用过滤器。各种各样的
想法四处流传,但在
最后有一个症结:我们
没有语言,也没有编译器。后
Macromedia 与 Adob​​e 合并
Flash Player 和 Adob​​e Pixel
本德团队聚集在一起,我们
终于有了我们需要的东西:一种语言
和编译器。

因此,基本上,Pixel Bender 比直接在 Actionscript 中操作像素更快。它将胜过无数次 setPixel 和 getPixel 调用。但它不会比玩家本身更快(同样,使用相同的算法)。

在某种程度上,您想要做的事情就像在 PB 中编写辉光滤镜一样。当然,它很酷,如果您对图像处理感兴趣,您可以从中学到很多东西。但是,如果您的过滤器旨在像本机过滤器一样工作,那么除了教育目的之外,它没有太多意义:本机过滤器会更快并且它已经可用,无需额外的代码行。

I think the problem is that you are really comparing Pixel Bender against native player code, not against "actionscript". I doubt Pixel Bender will ever win on that scenario.

The scaling that takes place here destBmd.draw( srcBmd, mx ); is coded directly in the player; that's probably as fast as you can get (using an equivalent algorithm). Your kernel on the other hand has at least to be compiled (or JIT compiled) first in order to run (probably there are a number of other reasons for it to be slower; I don't know much about the specifics, though).

Check out this post from the blog of a Flash Player engineer:

A long time ago, back in Flash Player
8 days we had the idea of adding a
generic way to do bitmap filters. Hard
coding bitmap filters like we did for
Flash Player 8 is not only not
flexible, but has the burden of adding
huge amounts of native code into the
player and having to optimize it for
each and every platform. The issue for
us has always been how you would
author such generic filters. Various
ideas were floating around but in the
end there was one sticking point: we
had no language and no compiler. After
Macromedia’s merger with Adobe the
Flash Player and the Adobe Pixel
Bender team came together and we
finally had what we needed: a language
and a compiler.

So, basically, Pixel Bender is faster than manipulating pixels directly in Actionscript. It will outperform an equivalent zillion of setPixel and getPixel calls. But it won't be faster than the player itself (again, using the same algorithm).

In a way, what you're trying to do is like writting, say, a glow filter in PB. Sure, it's cool and you can learn a lot from it if you're interested in image processing. But if your filter is meant to work just like the native filter, there's not much point in it, aside from educational purposes: the native filter will be faster and it's already available, without an extra line of code.

め可乐爱微笑 2024-09-08 17:27:05

我隐约记得听说虽然连接到像素弯曲器文件等的过程较慢,但处理本身却更快。所以我想你会看到随着图像尺寸变大,像素弯曲滤波器最终可能会变得更加高效。或者,也许 PixelBender 最适合稍微复杂的图像处理。

I vaguely remember hearing that while the process of connecting to a pixel bender file etc is slower, the processing itself is faster. So I imagine what you'd see is that as image size gets larger, the pixel bender filter may eventually get more efficient. Or maybe PixelBender is best saved for slightly more complex image manipulations.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文