javascript - 用 [rgba] 颜色数组填充 Canvas 的快速方法

标签 javascript canvas getimagedata

如果您有一组颜色并且您想用它的内容填充 Canvas ,我知道最快的方法是:

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);

这似乎太慢了,因为我要复制整个数组两次!一个用于制作 img_data,另一个用于将其放在 Canvas 上。有没有一种方法可以简单地将原始 my_array 插入到元素中?

最佳答案

你应该直接使用类型化数组而不是 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);

请注意,您可以检索此数组的缓冲区,并对此数组有另一个 View 。
这样你也可以有一个 32 位 View 来一次执行 4 个字节的复制操作。

var sourceBuffer32  = new UInt32Array(myArray.buffer);  

如果您使用这个 32 位 View ,请记住每个系统的字节顺序可能不同,这会导致在数组中加载 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);
};

关于javascript - 用 [rgba] 颜色数组填充 Canvas 的快速方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20811194/

相关文章:

javascript - 如何在谷歌图表中刷新页面后停止 x 轴文本相互重叠

javascript - 国家地理编码边界 - 摆脱国家线

javascript - 非法使用 undefined variable 、类或 'void' 文字

javascript - 为绘画程序创建 'History Panel'

javascript - Jquery Ajax .done() 行为

html - 如果我在 toDataURL() 中传递 "image/jpeg"我失去了质量?

java - Canvas 上的 KeyListener : keyReleased triggering, 但没有 keyPressed 或 keyTyped

javascript - 本地跨源数据错误

使用 getImageData() 时,html5 Canvas 总是返回 8 位颜色

javascript - 使用 getImageData 时遇到问题