2017-03-15 75 views
1

是否有可能從web程序有效地修改html5畫布?修改從wasm的畫布

更新:

var imageData = context.getImageData(x, y, w, h) 
var buffer = imageData.data.buffer; // ArrayBuffer 

可能是途中如果緩衝區是可寫的。

+0

可能使用[使用WebAssembly調用Web API方法]的副本(http://stackoverflow.com/questions/40904053/using-webassembly-to-call-web-api-methods) –

+1

因爲您忘記了,所以出現該錯誤寫出情況和你所嘗試的。只用一句話提出問題是不夠的,沒有任何研究證明 – Jer

回答

1

不,不在WebAssembly和web-api開發的這個階段。 使用context.getImageData您將得到一個帶有新緩衝區的新對象ImageData,該緩衝區必須在您的WebAssembly實例的內存緩衝區中再次被複制。 但是,如果您不需要從畫布中讀取,只需要寫入,就可以在您的WebAssembly實例的內存中分配ImageData.data。使用ImageData構造函數

imageData = new ImageData(new Uint8ClampedArray(waInstance.export.memory.buffer, byteOffset, width*height*4), width, height) 

imageData有一個指向您的數據的指針。在每次渲染時,請在WebAssembly中進行工作,並在context.putImageData(imageData)中使用相同的imageData,每個週期只進行一次大數據複製。

4

WebAssembly實例通常具有一個線性內存區域,它以JavaScript緩衝區的形式公開給JavaScript API。這可以在JS中分配並在創建WebAssembly實例時傳入,或者WebAssembly實例可以創建它並將其導出到JS代碼。無論哪種方式,可以使用arraybuffer將數據有效地複製到Canvas元素中(使用createImageData,getImageData和putImageData)。

+0

因此,內存必須被複制,而不是直接寫入位圖那麼有效,對嗎? – Anona112

+0

@ Anona112我懷疑現在你需要複製(TypedArray.of和/或TypedArray.set應該是非常有效的)。我懷疑在某種程度上,類似於結構化克隆的方法可以在Canvas和WebAssembly之間使用(現在實際上它可以工作,但如果是的話,它沒有很好的文檔) – kanaka

1
  1. 無論如何,你將不得不復制像素到WebAssembly.Memory實例。然後修改並複製回來。
  2. 我不知道爲什麼,但Uint8Array.set()在最新的Chrome中並不快。最好將數據重新發送到32位(new Uint32Array(your_uint8array)),然後使用Uint32Array.set()進行復制。
  3. 請記住,該canva的.getImageData()/.setImageData()並不快。可能是因爲他們做了alpha預乘和其他事情。

總結一下:你最大的速度損失是在.getImageData/.setImageData中,這是無法避免的。其他的東西都有解決方法。

如果與優化的JS相比,wasm會給你10-20%的好處,而不是太多。