2

色の配列があり、キャンバスをそのコンテンツで塗りつぶしたい場合、私が知っている最速の方法は次のとおりです。

var my_array = /* already have it */;
var img_data = ctx.createImageData(canvas.width, canvas.height);
for (var i=0; i<canvas.width*canvas.height; ++i)
    img_data[i] = my_array[i];
ctx.putImageData(img_data,0,0);

配列全体を 2 回コピーしているので、これは遅すぎるようです。1 つは を作成しimg_data、もう 1 つはキャンバスに配置します。my_arrayオリジナルを要素に単純に差し込む方法はありませんか?

4

2 に答える 2

5

主な計算には JavaScript 配列の代わりに型指定された配列を直接使用する必要があるため、後で変換する必要はありません。

var myArray = new Uint8Array(pixelCount);

また

var myArray = new Uint8ClampedArray(pixelCount);

アクセスは、標準の js 配列とまったく同じです。

for (var pxIndex = 0; pxIndex<myArray.length; pxIndex+=4 ) {
    // component for the (pxIndex >>2)th pixel :
    var r = myArray[pxIndex  ];
    var g = myArray[pxIndex+1];
    var b = myArray[pxIndex+2];
    var a = myArray[pxIndex+3];
}

このように、この配列をコピーして画面を更新するだけです:

ctx.putImageData(my_array,0,0);

この配列のバッファを取得して、この配列に別のビューを表示できることに注意してください。
このようにして、一度に 4 バイトずつコピー操作を実行する 32 ビット ビューを使用することもできます。

var sourceBuffer32  = new UInt32Array(myArray.buffer);  

この 32 ビューを使用している場合は、各システムのエンディアンが異なる可能性があることに注意してください。これにより、アレイに ABGR ( PC / mac ) または RGBA がロードされます。これはコピーでは何も変わりませんが、場合によっては面倒かもしれません (:-))。

ArrayBuffer スライス関数を使用して配列バッファをコピーできることも忘れないでください。

var myArrayCopy = new  new Uint8ClampedArray(myArray.buffer.slice(0));

この小さな関数でエンディアンを知ることができます:

function isLittleEndian() {     
// from TooTallNate / endianness.js.   https://gist.github.com/TooTallNate/4750953
    var b = new ArrayBuffer(4);
    var a = new Uint32Array(b);
    var c = new Uint8Array(b);
    a[0] = 0xdeadbeef;
    if (c[0] == 0xef) { isLittleEndian = function() {return true }; return true; }
    if (c[0] == 0xde) { isLittleEndian = function() {return false }; return false; }
    throw new Error('unknown endianness');
}

次のようにして、32 ビット ( ABCD -> DCBA ) を逆にすることができます。

function reverseUint32 (uint32) {
    var s32 = new Uint32Array(4);
    var s8 = new Uint8Array(s32.buffer);
    var t32 = new Uint32Array(4);
    var t8 = new Uint8Array(t32.buffer);        
    reverseUint32 = function (x) {
        s32[0] = x;
        t8[0] = s8[3];
        t8[1] = s8[2];
        t8[2] = s8[1];
        t8[3] = s8[0];
        return t32[0];
    }
    return reverseUint32(uint32);
};
于 2013-12-28T12:35:41.820 に答える