在 web-worker 中将 ImageBitMap/Image 绘制到 OffScreenCanvas

Posted

技术标签:

【中文标题】在 web-worker 中将 ImageBitMap/Image 绘制到 OffScreenCanvas【英文标题】:Drawing ImageBitMap/Image to OffScreenCanvas in a web-worker 【发布时间】:2020-07-01 07:07:01 【问题描述】:

我有一个 vue.js 应用程序,我在其中设置 vue-workers/web-workers 以在用户上传几张图像后在后台执行一些图像处理(缩放/裁剪)。

我决定使用 ImageBitMpas 和 OffScreenCanvas,因为 Web Worker 不支持 Canvas 和 Image Object。我可以使用 CreateImageBitMap() 方法从我的图像文件创建一个 ImageBitMap。它成功返回了一个承诺,然后解析为一个 ImageBitMap。我可以将它打印到我的控制台并查看 ImageBitMap 已创建!我在下面的控制台添加了一张 ImageBitmap 打印的图片。

ImageBitmap is created and error is thrown

var loadingImage = new Image();
loadingImage.onload = () => 

    console.log(createImageBitmap(loadingImage)); // I can see the ImageBitmap logged to console
    const canvas = new OffscreenCanvas(100,100);
    const ctx = canvas.getContext('2d');

    Promise.all([
        createImageBitmaps(loadingImage);
    ]).then(function(result)
        console.log("printing promise resolved");
        console.log(result);
        ctx.drawImage(result,0,0,200,200);  /// <-- this is where error is thrown
    )  

    // other code here .... 

;
loadingImage.src = base64Src; 

问题: 我遇到问题的地方是,当我将此 ImageBitMap 传递给 OffScreenCanvas.draw() 方法时,我收到一条错误消息“无法在 OffscreenCanvasRenderer 上执行 drawImage ...”您可以在打印 ImageBitMap 后在控制台中看到确切的错误下图。

有没有人成功地将图像绘制到 vue-worker/web-worker 中的 OffScreenCanvas 上?任何工作代码示例将不胜感激!

根据我的研究,似乎只有 Chrome 支持 createImageBitMap()?!除了使用 ImageBitMap 绘制到 OffScreenCanvas 之外,还有其他方法可以在 chrome 和 Safari 上运行吗???

【问题讨论】:

请直接在问题中发布代码,而不是截图。另外,如果你在 Worker 中,这个 Image 构造函数是什么?不仅 Safari 中的 Worker 还不能使用 createImageBitmap,而且除了 Chrome 之外的任何其他浏览器上的 OffscreenCanvas 的 2d 上下文也一样。最后,您可以在此 Q/A 中看到一个工作示例:***.com/a/56553680/3702797 另外,如果你在 Worker 中,这个 Image 构造函数是什么? - 我没有为 web worker 添加代码,因为我无法让它工作在主线程中。理想情况下,一旦我有了一个工作模型,我才会尝试在单独的线程/网络工作者中运行它。 感谢回复,我已经添加了我的JS代码并删除了我的截图。 不仅 Safari 中的 Worker 还不能使用 createImageBitmap,而且除了 Chrome 之外的任何其他浏览器上的 OffscreenCanvas 的 2d 上下文也没有。 还有其他网站能够非常加载和裁剪多个图像在 Safari 中也很快,知道他们会怎么做吗?有没有办法将图像绘制到画布上(这在 chrome 和 safari 中都支持,并且可以在 web worker 中工作)也许使用 Uint8ClampedArray 或 ImageData 对象?? 是什么让您认为他们使用了屏幕外画布? OffscreenCanvas 旨在通过在其他线程上执行 CPU 密集型操作来卸载主线程 CPU。裁剪图像不是 CPU 密集型的,你赢不了多少。从您的代码中,我已经可以看到您通过将二进制文件作为 base64 数据 URL 读取来执行过多的 CPU 密集型操作,而您应该刚刚完成 createImageBitmap(input.files[n])(这是可填充的,使用 blob URL)。 【参考方案1】:

您是否尝试过使用ImageBitmapRenderingContext

canvas.getContext('bitmaprenderer').transferFromImageBitmap(bitmap);

【讨论】:

以上是关于在 web-worker 中将 ImageBitMap/Image 绘制到 OffScreenCanvas的主要内容,如果未能解决你的问题,请参考以下文章

web-worker 可运行在浏览器以及node 的web worker

2021长城杯线下 Web-Work 复现

使用 GWT 的 Web Worker

深入理解JavaScript事件循环机制

JavaScript的执行机制

JavaScript库中的阻塞/非阻塞函数?