2016-10-17 134 views
1

我想通过一个在web worker上运行的asm.js代码来生成图像。我想定期将这种计算的最新状态与其他一些内容一起合成到用户可见的二维画布上。目前我有代码Safari上的createImageBitmap替代方案

  1. 构建使用its constructorImageData一个对象,基于由asm.js代码使用的阵列缓冲器的一部分,
  2. 呼叫createImageBitmap打开ImageDataImageBitmap
  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,但有很多其他的东西与手头的问题无关。

回答

1

有一些其他的方式把一个字节数组到的东西,你可以 饲料drawImage

您可以张贴Uint8ClampedArray对象主线程的ArrayBuffer;在主线程处用.putImageData()代替.drawImage()。正如@Kaiido表示,没有必要在主线程

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

+0

这从加载PNG文件的图像在Worker

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

创建一个ImageData对象。所以当它存储在一个类型数组中时,它不是原始像素数据。如果我要复制这种方法,我可能必须对像素数据进行PNG编码,这需要一些时间,并且需要一些库或一些自行编写的用于PNG头的代码,行头插入和最小缩放编码(例如,只使用未压缩的存储方法)。不过,这可能是一个可行的选择,特别是如果没有更好的变化,所以谢谢! – MvG

+0

@MvG你也可以将'imgData'的'buffer'传递给'postMessage'的主线程,用'.putImageData'替代'.drawImage';查看更新的帖子。 – guest271314

+1

如果我遵循正确的话,对于你的最后一部分,你不需要在worker中创建一个ImageData对象(https://jsfiddle.net/Kaiido/234ekx4b/) – Kaiido