Webworker OffscreenCanvas 绘制常规图像

itu*_*tuy 2 javascript canvas web-worker

Webworkers 可以通过 获取常规图像XMLHttpRequest,对吧?那么工作人员如何将这些图像绘制到 OffscreenCanvas 上呢?大概想用XMLHttp.responseType = 'blob'

另一种方法是设置src图像元素的 ,然后将该元素传输给工作人员,但我的工作人员总是拒绝此类图像。

谢谢

Kai*_*ido 7

ImageBitmap API就是为了这个目的(以及其他目的)而存在的。

注意:此演示目前仅在 Chrome 上运行...

const offcanvas = canvas.transferControlToOffscreen();
const worker = new Worker(getWorkerURL());
worker.onmessage = e => console.log(e.data);
worker.postMessage(offcanvas, [offcanvas]);


function getWorkerURL() {
  return URL.createObjectURL(
    new Blob([
      worker_script.textContent
    ])
  );
}
Run Code Online (Sandbox Code Playgroud)
<canvas id="canvas" height="450"></canvas>

<script id="worker_script" type="ws">
onmessage = async (evt) => {
  try {
    const canvas = evt.data;
    const ctx = canvas.getContext('2d');
    if(!ctx) {
      postMessage('unsupported browser');
      return;
    }
    const imgblob = await fetch('https://upload.wikimedia.org/wikipedia/commons/5/55/John_William_Waterhouse_A_Mermaid.jpg')
      .then(r => r.blob());
    const img = await createImageBitmap(imgblob);
    ctx.drawImage(img, 0,0, canvas.width, canvas.height);
 }
 catch(e) {
  postMessage('unsupported browser');
  throw e;
  }
};
</script>
Run Code Online (Sandbox Code Playgroud)

  • @ituy 当然,这需要内存,您正在初始化 120 个 2000x2000px 画布!这大约是 4*4*8*2000*2000,每个画布 5MB 原始图像数据,**并且**您每次迭代都会创建一个新的 ImageBitmap。Web Workers 只允许在其他 CPU 线程中运行脚本,但它们并不神奇,仍然需要分配内存。你的第二个小提琴使用 300x150px 画布(每个画布 500KB),并且浏览器每次都会使用相同的位图(由于缓存)。第一个小提琴的更公平版本是 https://jsfiddle.net/rza8f6nv/ 但它仍然会明显消耗内存。 (4认同)