рендеринг на холст с использованием необработанных значений UInt16Array javascript - PullRequest
1 голос
/ 29 марта 2020

Я пытаюсь визуализировать изображение из массива Uint16 в javascript. Я не получаю никаких обнаруженных ошибок, но ничего не отображается на холсте.


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 выводит на консоль ::

  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_

это было то, что я использовал не 4-х цветную матрицу, а бинарный канал для цвета. Решение заключалось в том, чтобы увеличить размер записанного цвета до 4 байт и просмотреть его в основном потоке как 1 байт. однако: если я пытаюсь получить доступ к SharedMemory с помощью
new Uint8ClampedArray (data.buffer), я получаю следующее предупреждение консоли:

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

, поэтому следующим шагом было создание временного массива на главном 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);

, но это буквально просто повторная архивация информации из sharedMememory в новый слот памяти для каждого рендера ... фактически дважды выводит одну и ту же информацию в массив. Есть ли более быстрый способ для меня, чтобы получить pixelData из sharedMemory и на холст?

1 Ответ

1 голос
/ 29 марта 2020

Если у вас есть необработанные данные пикселей RGBA, то все что вам нужно - создать ImageData из вашего Uint16Array и поместить его на холст .

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>

Ваш код не выдал ошибку, потому что вы ее не слушали. Если вы добавите прослушиватель к событию error вашего imageObject, вы увидите, что ему не удалось загрузить то, чем вы его кормили, потому что изображение - это не просто необработанные данные пикселей, оно также имеет заголовки, по крайней мере, чтобы сказать, размер изображения.

...