2017-03-15 38 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%的好处,而不是太多。