Search code examples
javascriptcanvasweb-worker

Webworker OffscreenCanvas draw regular image


Webworkers can fetch regular images through XMLHttpRequest, right? How can the workers then draw these images to OffscreenCanvas? Probably want to use XMLHttp.responseType = 'blob'?

Another way would be to set the src of an image element and then transfer the element to worker, but my workers always reject such images.

Thanks


Solution

  • The ImageBitmap API is here for this purpose (among others).

    Note: this demo will currently run only on 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>