использование PixelBender для удвоения размера растрового изображения

У меня есть вопрос о производительности пиксельного бендера. Я хочу увеличить многие BitmapData (удвоить их размер до новых BitmapData). Я делал это с as3, но хотел использовать сгибание пикселей, чтобы повысить производительность. На моей машине я получаю более высокую производительность благодаря сгибу пикселей демонстрации затем as3.

К моему удивлению (или плохому кодированию/пониманию), я получаю намного хуже производительность из-за сгибания пикселей - 2 секунды против 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
    }
}

person jedierikb    schedule 17.05.2010    source источник
comment
Проверка работоспособности: в части AS3 вы многократно увеличиваете одно и то же изображение вместо того, чтобы масштабировать его один раз и копировать результат. Это недосмотр или все они будут разными изображениями в реальном коде?   -  person fenomas    schedule 18.05.2010
comment
Хороший вопрос - все они будут разными изображениями в реальном коде. В этом примере я просто пытаюсь понять, как оптимизировать масштабирование, поэтому запускаю его через 3 тыс. итераций.   -  person jedierikb    schedule 18.05.2010
comment
Было бы интересно протестировать несколько разных изображений, чтобы увидеть, как это влияет на скорость. (или создание 1-300.png с помощью скрипта фотошопа или чего-то еще)   -  person quoo    schedule 18.05.2010
comment
Я сделал 3k случайных изображений, и результаты были такими же.   -  person jedierikb    schedule 18.05.2010


Ответы (2)


Я думаю, проблема в том, что вы действительно сравниваете Pixel Bender с собственным кодом плеера, а не с «экшнскриптом». Я сомневаюсь, что Pixel Bender когда-нибудь выиграет в этом сценарии.

Происходящее здесь масштабирование destBmd.draw( srcBmd, mx ); закодировано непосредственно в плеере; это, вероятно, так быстро, как вы можете получить (используя эквивалентный алгоритм). С другой стороны, ваше ядро ​​должно быть сначала скомпилировано (или скомпилировано JIT), чтобы работать (вероятно, есть ряд других причин, по которым оно работает медленнее, хотя я мало знаю о специфике).

Прочтите этот пост из блога разработчика Flash Player:

Давным-давно, еще во Flash Player 8, у нас появилась идея добавить общий способ создания растровых фильтров. Фильтры растровых изображений с жесткой кодировкой, как мы сделали для Flash Player 8, не только не гибки, но и требуют добавления огромного количества собственного кода в проигрыватель и необходимости его оптимизации для каждой платформы. Проблема для нас всегда заключалась в том, как вы будете создавать такие общие фильтры. Были разные идеи, но в конце концов остался один камень преткновения: у нас не было ни языка, ни компилятора. После слияния Macromedia с Adobe Flash Player и команда Adobe Pixel Bender объединились, и мы наконец получили то, что нам было нужно: язык и компилятор.

Таким образом, Pixel Bender работает быстрее, чем манипулирование пикселями непосредственно в ActionScript. Это превзойдет эквивалентное количество вызовов setPixel и getPixel. Но он не будет быстрее самого плеера (опять же по тому же алгоритму).

В некотором смысле то, что вы пытаетесь сделать, похоже на написание, скажем, фильтра свечения в PB. Конечно, это круто, и вы можете многому у него научиться, если вас интересует обработка изображений. Но если ваш фильтр предназначен для работы так же, как и нативный фильтр, то в нем нет особого смысла, кроме образовательных целей: нативный фильтр будет быстрее и уже доступен, без дополнительной строки кода.

person Juan Pablo Califano    schedule 18.05.2010

Я смутно припоминаю, что слышал, что хотя процесс подключения к файлу сгибателя пикселей и т. д. медленнее, сама обработка выполняется быстрее. Итак, я предполагаю, что вы увидите, что по мере увеличения размера изображения фильтр сгибания пикселей может в конечном итоге стать более эффективным. Или, может быть, PixelBender лучше сохранить для более сложных манипуляций с изображениями.

person quoo    schedule 18.05.2010