2016-10-17 67 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