Safari 上的 createImageBitmap 替代方案

createImageBitmap alternative on Safari

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

  1. 根据 asm.js 代码使用的数组缓冲区的一部分构造一个 ImageData object using its constructor
  2. 调用 createImageBitmap to turn the ImageData into an ImageBitmap,
  3. transfers 从工作者到 GUI 线程的图像位图和
  4. 使用 ImageBitmap 作为 CanvasRenderingContext2D.drawImage 的参数。

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

是否有一些低成本的图像编码,而不是为其创建 data:image/png…?有没有其他方法可以将字节数组转换为可以提供给 drawImage 的内容?

顺便说一下:http://caniuse.com/ currently doesn't list this feature. There is 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 中,但还有很多其他内容与手头的问题无关。

Is there some other way to turn a byte array into something you can feed to drawImage?

你可以postUint8ClampedArray对象的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