【问题标题】:createImageBitmap alternative on SafariSafari 上的 createImageBitmap 替代方案
【发布时间】:2017-02-26 21:37:37
【问题描述】:

我想用一些在 web worker 上运行的 asm.js 代码生成图像。而且我想定期将该计算的最新状态与其他一些内容一起合成到用户可见的 2d 画布上。目前我有代码

  1. 根据 asm.js 代码使用的数组缓冲区的一部分,使用 its constructor 构造一个 ImageData 对象,
  2. 调用createImageBitmapImageData变成ImageBitmap
  3. transfers 从工作线程到 GUI 线程的图像位图和
  4. 使用ImageBitmap 作为CanvasRenderingContext2D.drawImage 的参数。

在最近的 Chrome 和 Firefox 中运行良好,但 Safari 9.1.3 显然没有createImageBitmap 功能。 如何以适用于 Safari 的方式执行上述操作?

除了为它创建一个data:image/png…之外,是否有一些低成本的图像编码?有没有其他方法可以将字节数组转换为可以提供给drawImage 的东西?

顺便说一句:http://caniuse.com/ 目前没有列出这个功能。有a feature request 可以吗????如果您想在此处看到此功能的监控。


如果您希望查看我当前方法的代码,以下是我的工作人员的相关部分:

var buffer = new ArrayBuffer(bufferSize);
var asm = Module.asm(self, {}, buffer);
var imgBytes = new Uint8ClampedArray(buffer, offset);
var imgData = new ImageData(imgBytes, width, height);
createImageBitmap(imgData).then(function(bmp) { // Not available on Safari!
    postMessage(bmp, [bmp]);
});

这里是对应的GUI线程代码:

var worker = new Worker(‹url of worker›);
worker.onmessage = function(msg) {
    var img = msg.data;
    context2d.drawImage(img, 0, 0, width, height);
};

实际的未删节代码在this GitHub pull request 中,但还有很多其他内容与手头的问题无关。

【问题讨论】:

    标签: javascript html image safari web-worker


    【解决方案1】:

    有没有其他方法可以将字节数组变成你可以的东西 喂给drawImage

    您可以将Uint8ClampedArray对象的ArrayBuffer发布到主线程;在主线程使用.putImageData() 替换.drawImage()。正如@Kaiido 所指出的,没有必要在Worker 处创建ImageData 对象

    var imgBytes = new Uint8ClampedArray(buffer, offset);
    postMessage(imgBytes.buffer, [imgBytes.buffer]);
    

    在主线程

    worker.onmessage = function(e) {
      console.log(e.data); // `ArrayBuffer`
      ctx.putImageData(new ImageData(new Uint8ClampedArray(e.data), width, height), 0, 0);
    }
    

    http://plnkr.co/edit/N0v1YQHQX2rdFfHcOKeR?p=preview

    【讨论】:

    • 这会从 PNG 文件加载图像。因此,虽然它存储在类型化数组中,但它不是原始像素数据。如果我要复制这种方法,我可能不得不对像素数据进行 PNG 编码,这需要一些时间,并且需要一些库或一些用于 PNG 标头、行标头插入和最小放气编码的自写代码(例如,使用只有未压缩的存储方法)。不过,这可能是一个可行的选择,特别是如果没有更好的选择,那么谢谢!
    • @MvG 你也可以将imgDatabuffer转移到postMessage的主线程,用.putImageData代替.drawImage;查看更新后的帖子。
    • 如果我没听错的话,对于您的最后一部分,您不需要在工作人员中创建 ImageData 对象 (jsfiddle.net/Kaiido/234ekx4b)
    • @Kaiido 是的,你是对的。 plnkr.co/edit/N0v1YQHQX2rdFfHcOKeR?p=preview\
    • 这听起来很有趣。由于我需要与其他内容合成,我需要drawImage,但我可以putImageData 到屏幕外的画布,然后drawImage 到主要的。
    猜你喜欢
    • 2023-03-17
    • 2015-06-13
    • 2019-09-09
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    • 2019-04-22
    • 2018-08-07
    • 1970-01-01
    相关资源
    最近更新 更多