【问题标题】:Webworker OffscreenCanvas draw regular imageWebworker OffscreenCanvas 绘制常规图像
【发布时间】:2019-10-26 10:35:41
【问题描述】:

网络工作者可以通过XMLHttpRequest 获取常规图像,对吗?工人如何将这些图像绘制到 OffscreenCanvas 上?大概想用XMLHttp.responseType = 'blob'

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

谢谢

【问题讨论】:

    标签: javascript canvas web-worker


    【解决方案1】:

    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
        ])
      );
    }
    <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>

    【讨论】:

    • 谢谢。我认为您在r.blob() 之前错过了return。除此之外,我注意到经过数百次迭代(即使只有一张图像)会消耗大量内存。如果我排除画布,那么内存至少会自动释放。你能建议如何解决画布的内存问题吗?
    • 不,只包含一个语句的箭头函数不需要return。对于您的内存问题,我不确定您的意思...您可以设置minimal reproducible example 吗?但请注意,它占用内存是很正常的(像素必须存储在某个地方),但它应该在 GC 进来后自行释放(如果你有足够的可用内存,这可能永远不会释放)。
    • An iteration of 120 times. 如果我们注释掉 drawImage,那么 RAM 将恢复正常。这很可悲,因为使用多个OffscreenCanvas 的工人没有任何好处。即使我将屏幕外传递给工人,ram 保持不变。 (A quick example without workers)
    • @ituy 当然这需要内存,你正在初始化 120 个 2000x2000px 的画布!这大约是 4*4*8*2000*2000,每个画布原始图像数据 5MB,并且您每次迭代都会创建一个新的 ImageBitmap。 Web Worker 只允许在其他 CPU 线程中运行脚本,但它们并不神奇,仍然需要分配内存。您的第二把小提琴使用 300x150px 画布(每个画布 500KB),并且浏览器每次都会使用相同的位图(因为缓存)。第一个小提琴的一个更公平的版本是jsfiddle.net/rza8f6nv,但它显然仍然会消耗内存。
    猜你喜欢
    • 2020-04-23
    • 2020-07-01
    • 2022-06-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-27
    • 1970-01-01
    相关资源
    最近更新 更多