1

私は現在、JavaScriptで水平ブラーアルゴリズムに取り組んでいますが、言語が重要かどうかは疑問です。

基本的に4つごとの(RGBA)値が1ピクセルを表す巨大な配列であるキャンバスからデータを取得します。値には、0〜255の範囲のintを含めることができます。

画像をぼかすと、2つの異なる色の間の領域が奇妙な色に変わります!黒の背景に赤い長方形を描きました。以下のアルゴリズムを使用すると、次の結果が得られます(4pxサイズ)。

4pxの望ましくない結果

ただし、1または2ピクセルのサイズを使用すると、すべてが正常に機能しているように見えます。

2pxの望ましい結果

これはやや厄介な蓄積であることに注意してください。これをすべてOOPにする予定です!

// s: size
// w: width
// h: height
function blur( s, w, h ) {
    var src = ctx.getImageData( 0, 0, w, h ); // get imagedata from source
    var dst = ctx.createImageData( w, h );    // create imagedata for dest
    var x, y, xo, index, rgb; // predefine vars

    // loop through y axis
    for( y = 0; y < h; y++ ) {
        // loop through x axis
        for( x = 0; x < w; x++ ) {
            rgb = 0; // set total to 0

            // loop through area around current pixel
            for( xo = 0 - s; xo <= s; xo++ ) {
                // get specific index
                index = getIndex( x + xo, y, w );

                // add nothing if the value doesn't exist (borders)
                // if( isNaN( src.data[index] ) ) continue;
                if( typeof src.data[index] === 'undefined' ) continue;

                // add the values to total
                rgb += ( src.data[index] << 16 ) + ( src.data[index + 1] << 8 ) + src.data[index + 2];
            }

            // get the average of all pixels in that area
            rgb = rgb / ( s * 2 + 1);

            // get index of current pixel
            index = getIndex( x, y, w );

            // set pixel in dest
            dst.data[index] = ( rgb & 0xff0000 ) >> 16;    // red
            dst.data[index + 1] = ( rgb & 0x00ff00 ) >> 8; // green
            dst.data[index + 2] = ( rgb & 0x0000ff );      // blue
            dst.data[index + 3] = 255; // alpha
        }
    }

    // add the new image data
    ctx.putImageData( dst, 0, 0 );
}

function getIndex( x, y, w ) {
    // calculate the appropriate index, since every pixel has 4 array values
    return ( y * ( w * 4 ) + ( x * 4 ) );
}

では、私のアルゴリズムの何が問題になっていますか?私は少し迷っています。キャンバスブラー用の既存のオブジェクト/ライブラリ/ファイルを探していないことに注意してください。私は自分自身を教育するためにすべてを再発明するのが好きです。


編集:私が返す値は、実際にはキャンバスに表示されている色を表す値であることも付け加えたいと思います。これは、私のアルゴリズムでは間違いなく誤算であることを意味します。

4

2 に答える 2

2

チャンネルを個別に平均化する必要があります。パックされた3チャネル値を分割しても、各チャネルがそのバイト内に保持される可能性はほとんどありません。

于 2012-06-18T12:31:56.103 に答える
2

0x030000(濃い赤)と0x000000(黒)の平均が0x018000になり、多くの緑(0x80)が得られます。チャネルを個別に平均する必要があります。

于 2012-06-18T12:34:08.253 に答える