ImageData на холст - PullRequest
       7

ImageData на холст

0 голосов
/ 02 мая 2020

Я пытаюсь поместить данные изображения на холст c / ctx, вот мой текущий код:

console.log('Worker said: '+ e.data[1]);
var image = ctx.createImageData(20,300);
image.data = e.data[1];
ctx.putImageData(image,e.data[0],0);

Да, работник выводит правильную информацию (e.data [1] = image массив данных [r, g, b, прозрачность, ...], e.data [0] = xpos для импорта)

Не могу понять, почему это не работает?

Вот мои настройки холста на всякий случай

var c = document.getElementById("myCanvas")
var ctx = c.getContext('2d', { alpha: false });
c.width = 300;
c.height = 300;

Ответы [ 2 ]

0 голосов
/ 02 мая 2020

В современных браузерах (все, кроме IE) вы можете использовать конструктор ImageData , который принимает Uint8ClampedArray в качестве входных данных.

Итак, если ваш работник отправляет Uint8Array , все, что вам нужно сделать - это сначала создать новый Uint8ClampedArray вид того же ArrayBuffer как отправленный TypedArray , а затем используйте это представление для инициализации ImageData :

const worker = new Worker( generateWorkerURL() );
worker.onmessage = (evt) => {
  // first a new view (same ArrayBuffer)
  const clampedView = new Uint8ClampedArray( evt.data.buffer );
  const imageData = new ImageData( clampedView, 500, 300 );
  const ctx = document.getElementById( 'canvas' ).getContext( '2d' );
  ctx.putImageData( imageData, 0, 0 );
};



// helper to integrate Worker in a Snippet
function generateWorkerURL() {
  const content = document.querySelector('[type="worker-script"]').textContent;
  const blob = new Blob( [ content ], { type: "text/javascript" }  );
  return URL.createObjectURL( blob );
}
<script type="worker-script">
  // fake worker code, generates noise
  const data = Uint8Array.from(
    { length: 500 * 300 * 4 },
    () => Math.random() * 0xFF
  );
  // We 'transfer' the TypedArray's buffer so that it's not copied
  // by passing it in an Array as the second argument of postMessage
  postMessage( data, [ data.buffer ] );
</script>
<canvas id="canvas" width="500" height="300"></canvas>

Теперь вы даже можете начать работать с ImageData непосредственно в рабочем потоке и перенести его в основной поток, когда это будет сделано:

const worker = new Worker( generateWorkerURL() );
worker.onmessage = (evt) => {
  const ctx = document.getElementById( 'canvas' ).getContext( '2d' );
  // put directly the imageData sent by the Worker
  ctx.putImageData( evt.data, 0, 0 );
};



// helper to integrate Worker in a Snippet
function generateWorkerURL() {
  const content = document.querySelector('[type="worker-script"]').textContent;
  const blob = new Blob( [ content ], { type: "text/javascript" }  );
  return URL.createObjectURL( blob );
}
<script type="worker-script">
  // fake worker code, generates noise
  const imageData = new ImageData( 500, 300 );
  for( let i=0; i<imageData.data.length; i++ ) {
    imageData.data[ i ] = Math.random() * 0xFF;
  }
  // we transfer the ImageData's buffer
  postMessage( imageData, [ imageData.data.buffer ] );
</script>
<canvas id="canvas" width="500" height="300"></canvas>
0 голосов
/ 02 мая 2020

Вы не можете присвоить массив атрибуту .data, вы должны скопировать значения, это должно работать

var image = ctx.createImageData(20,300);
var length = e.data[1].length;

for (var i = 0; i < length; i++) {
    image.data[i] = e.data[1][i];
}
ctx.putImageData(image,e.data[0],0);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...