快速的方式来填充一个帆布的数组[rgba]颜色 [英] Fast way to fill a canvas with an array of [rgba] colors

查看:118
本文介绍了快速的方式来填充一个帆布的数组[rgba]颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果你有一个颜色数组,并且你想用它的内容填充一个画布,我知道最快的方式是:

Providing you have an array of colors and you want to fill a canvas with its content, the fastest way I'm aware of is:

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 ,另一个将它放在画布上。是不是有办法简单地插入原来 my_array 到元素?

This seems too slow as I'm copying the entire array twice! One to make the img_data and another to put it on the canvas. Isn't there a way to simply plug the original my_array into the element?

推荐答案

您应该直接使用类型数组而不是javascript数组来进行主要计算,所以以后不必进行转换:

You should directly make use of a typed array instead of a javascript array for your main computations, so you won't have to convert later :

var myArray = new Uint8Array(pixelCount);

var myArray = new Uint8ClampedArray(pixelCount);

访问权限与标准js数组相同:

The access is just the same as a standard js array :

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];
}

这样你只需要复制这个数组来更新屏幕:

This way you just have to copy this array to update the screen :

ctx.putImageData(my_array,0,0);

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

Notice that you can retrieve the buffer of this array, and have another view on this array.
This way you can also have, say, a 32 bit view to perform copy operations 4 bytes at a time.

var sourceBuffer32  = new UInt32Array(myArray.buffer);  

如果您使用此32视图,请记住每个系统的字节顺序可能不同,在数组中加载ABGR(PC / mac)或RGBA。
这不会改变副本,但是在某些情况下可能很烦人(: - ))。

If you are using this 32 view, remember that the endianness of each system might be different, which leads to load either ABGR ( PC / mac ) or RGBA in the array. This changes nothing for a copy, but might be annoying in some cases (:-)).

不要忘记也可以复制一个数组缓冲区与ArrayBuffer切片函数:

Don't forget also you can copy an array buffer with the ArrayBuffer slice function :

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






你可以用这个小函数知道字节序:


You can know the endianness with this small function :

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)

you can reverse a 32 bit ( ABCD -> DCBA ) with the following :

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

这篇关于快速的方式来填充一个帆布的数组[rgba]颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆