投稿者 tel | 2014年6月22日

CanvasのImageDataへの書き込み速度

CanvasのImageDataへのアクセス方法を変えて速度アップできるか試してみる。

 手法

ImageDataのバッファはUint8ClampedArray 型なので0~255範囲外の値をいれてもクランプされる。つまり値を代入するときに通常よりもコストがかかっているはず。

そこでUint32Arrayでアクセスするようにすれば速度アップが図れるという思惑。ImageDataのバッファを別の型としてアクセスするには目的のTyped Array(Uint32Arrayとか)のコンストラクタ関数の引数にImageData.data.bufferを渡せばいい。新しく作られたTyped ArrayはImageData.dataを別の型として参照するようになる。

ただし古いブラウザではImageDataのバッファがCanvasPixelArrayかもしれないので使えない。

実験コード

ImageDataに対して単色で塗りつぶす処理を通常の場合とUint32Array、Uint8Arrayでアクセする場合とで比べる。

function draw0(image, r, g, b, a) {
    var data = image.data,
        w = image.width,
        h = image.height;
    for(var k = 0, l = data.length; k < l; k += 4) {
        data[k + 0] = r;
        data[k + 1] = g;
        data[k + 2] = b;
        data[k + 3] = a;
    }
}
function draw1(image, abgr) {
    var data = new Uint32Array(image.data.buffer),
        w = image.width,
        h = image.height;				
    for(var i = 0, l = data.length; i < l; i++) {
        data[i] = abgr;
    }
}
function draw2(image, r, g, b, a) {
    var data = new Uint8Array(image.data.buffer),
        w = image.width,
        h = image.height;

    for(var k = 0, l = data.length; k < l; k += 4) {
        data[k + 0] = r;
        data[k + 1] = g;
        data[k + 2] = b;
        data[k + 3] = a;
    }
}

速度

デスクトップChrome 36でそれぞれ10回測ってみた。

 http://jsdo.it/sapphire_al2o3/bygJ

  • draw0: 11~15ms
  • draw1: 2~3ms
  • draw2: 12~15ms

まとめ

ImageDataをUint32Arrayでアクセスしたほうが速くなる。Uint8Arrayにしても速度差はないのでクランプするのが遅いというよりも1ピクセルを4byte一気に書き込んだほうが速いみたい。


コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

カテゴリー

%d人のブロガーが「いいね」をつけました。