简体   繁体   English

使用原始 UInt16Array 值 javascript 渲染到画布

[英]rendering to the canvas usiing raw UInt16Array values javascript

I'm trying to render an image from a Uint16Array in javascript.我正在尝试从 javascript 中的 Uint16Array 渲染图像。 I am not getting any caught errors, but nothing is rendering to the canvas.我没有收到任何捕获的错误,但没有渲染到画布。


const canvas = document.querySelector('canvas');
const ctx = canvas.getContext('2d');
const bufferMemoryAllocation = cellCount*2; //double the size 2bytes--16bits--per memory slot
const bitArray = new SharedArrayBuffer(bufferMemoryAllocation); // double the number of cells
const pixelData = new SharedArrayBuffer(bufferMemoryAllocation);
const pixelDataCanvas =  new Uint16Array(pixelData);

const videoResolutions = [{name: "test", height: 1000, width:1000},{name:"1080", height: 1080, width:1920},{name:"4k", height: 2160, width:3840}];
canvas.height = videoResolutions[2].height;
canvas.width =  videoResolutions[2].width;

const cellScale = 2;
const drawHeight = Math.floor(canvas.height/cellScale);

const drawWidth = Math.floor(canvas.width/cellScale);
const cellCount=drawHeight*drawWidth;




function renderToCanvas()
    {
    ctx.drawImage(renderToImage(pixelDataCanvas),0,0,drawWidth,drawHeight); 
}
function renderToImage(pixelDataReffernce)
    {let imageObject = new Image(canvas.height,canvas.width);
    let imageString = 'data:image/bmp;base64,'+btoa(pixelDataReffernce);
    imageObject.src = imageString;
    // console.log(imageObject);
    return imageObject;
}

pixelDataReffernce consoles out to:: pixelDataReference 控制台输出到:

  Uint16Array(2073600) [0, 0, 0, 0, 0, 0, 0, 0, 1024, 1024, 1024, 0, 0, 0, 0, 1024, 0, 0, 0, 1024, 1024, 1024, 0, 0, 0, 0, 0, 1024, 0, 0, 0, 0, 1024, 0, 1024, 1024, 1024, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1024, 0, 0, 0...

EDIT_编辑_

it was that I wasn't using a 4 channel color array, but a binary channel for color.这是因为我没有使用 4 通道颜色数组,而是使用二进制颜色通道。 the solution was to increase the size of recorded color to 4 bytes long, and view it on the main thread as 1byte long.解决方案是将记录颜色的大小增加到 4 个字节长,并在主线程上查看它为 1 个字节长。 however: if i try to access the SharedMemory with但是:如果我尝试访问 SharedMemory
new Uint8ClampedArray(data.buffer), i get the following console warning. new Uint8ClampedArray(data.buffer),我收到以下控制台警告。

Uncaught TypeError: Failed to construct 'ImageData': The provided ArrayBufferView value must not be shared.

so the next step around was to make temp array on the main thread;所以下一步是在主线程上创建临时数组;

    const pixelTransViewer = new Uint8Array(pixelData);
    const tA = new Uint8ClampedArray(data.buffer);
    for(let i=0;i<tA.length;i++)
        {   
        for(let j=0;j < 8;j++)
            {
            tA[i]=setBitState(tA[i],j,checkBit(pixelTransViewer[i],j));
        }
    }
    const img = new ImageData(tA, span);

but that's literally just rezipping information from sharedMememory to a new memory slot for every render... effectively drawing the same information to an array twice.但这实际上只是将信息从 sharedMememory 重新压缩到每个渲染的新内存插槽......有效地将相同的信息绘制到数组两次。 is there a faster way for me to get the pixelData out of sharedMemory and onto the canvas?有没有更快的方法让我从 sharedMemory 中获取 pixelData 并放到画布上?

If what you have are raw RGBA pixel data, then all you need is to create an ImageData from your Uint16Array and put it on your canvas .如果您拥有的是原始 RGBA 像素数据,那么您只需要从 Uint16Array 创建一个 ImageData 并将其放在画布上

 const img_width = 50; const img_height = 50; const data = new Uint16Array((img_width * img_height) * 2 ); // make some noise crypto.getRandomValues(data); const canvas = document.getElementById('canvas'); canvas.width = img_width; canvas.height = img_height; const ctx = canvas.getContext('2d'); const img = new ImageData( new Uint8ClampedArray(data.buffer), img_width, img_height ); ctx.putImageData( img, 0, 0 );
 <canvas id="canvas"></canvas>

Your code did not produce any error because you were not listening to it.你的代码没有产生任何错误,因为你没有听它。 If you add a listener to the error event of your imageObject , you'll see it failed to load what you fed it with, because an image is not just raw pixel data, it also has headers, at least to tell the size of the image.如果您向imageObjecterror事件添加一个侦听imageObject ,您将看到它无法加载您提供给它的内容,因为图像不仅仅是原始像素数据,它还具有标题,至少可以告诉它的大小图片。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM