为imageData分配一个缓冲区位置.数据,而不是用循环赋值

Assign a buffer location to imageData.data instead of assigning values with loop

本文关键字:数据 赋值 循环 位置 缓冲区 分配 imageData 一个      更新时间:2023-09-26

我使用emscripten在c++中创建位图,并将其传递给我的javascript代码

const int COMP = 4;
long createBitmap(int DIM)
{
    srand(NULL);
    // create buffer
    long buffer = EM_ASM_INT(
    {
        var buffer = Module._malloc($0 * 1);
        return buffer;
    }, DIM*DIM*COMP);
    uint8_t* bitmap = (uint8_t*)buffer;
    //just randomly fill the buffer
    for (int i = 0; i < DIM*DIM*COMP; i++)
    {
        if (i%4==3)
            bitmap[i] = 128;
        else
            bitmap[i] = rand()%256;
    }
    return buffer;
}

和在javascript我有以下代码:

var dim = 1080;
var buffer = Module.createBitmap(dim);
var c = document.getElementById("bitmap");
var ctx = c.getContext("2d");
var imgData = ctx.createImageData(dim,dim);
for (var i = 0; i < dim*dim*4; i++) {
    imgData.data[i] = Module.HEAPU8[buffer+i];
}
ctx.putImageData(imgData, 0, 0)

这工作得很好,但我不喜欢循环将缓冲区的所有元素分配给imgData.data数组。我知道我在c++中使用的uint8_t数据类型对应于imgData.dataUint8ClampedArray。对我来说,这似乎是一个很好的机会,只是分配缓冲区的开始到这个imgData.data,我不需要复制任何东西-这是可能的吗?

我从emscripten google组得到了这个答案。

答案其实很简单。

var mappedBuffer= new Uint8ClampedArray(Module.HEAPU8.buffer, buffer, dim * dim * 4)

所以HEAPU8.buffer访问底层缓冲区,我可以创建一个Uint8ClampedArray类型的数组。

那么你可以直接写

imgData.data.set(mappedBuffer)
ctx.putImageData(imgData, 0, 0)