我需要在XUL桌面应用程序的画布上显示一个Image(~5000 * ~7000 px)。 图像数据来自C-DLL,它执行基本的图像处理操作。 到目前为止我尝试的方法存在性能问题:
我现在有以下函数调用我的C-DLL: (vars scalFactor,pageNumber和pdfFilePath与我的问题无关)
copyImageData : function(pdfFilePath, pageNumber, canvas, scaleFactor) {
var startLoad = new Date();
var ctx = canvas.getContext('2d');
var imageData = ctx.createImageData(canvas.width, canvas.height);
var buffer = new ArrayBuffer(imageData.data.length);
var buffer8 = new Uint8ClampedArray(buffer);
var bufferPtr = ctypes.uint32_t.ptr(buffer);
copyImageData(pdfFilePath, pageNumber, bufferPtr, canvas.width, canvas.height, 0, 0, scaleFactor);
imageData.data.set(buffer8);
ctx.putImageData(imageData, 0, 0);
consoleService.logStringMessage("Operation load image took: " + (new Date() - startLoad));
}
copyImageData 将信息发送到我的DLL,然后直接用C语言填充带有imagedata的Arraybuffer。这可能是因为指针: ctypes.uint32_t.ptr(buffer)< / strong>即可。
现在的问题是,标准&#34; .set&#34;函数( imagedata.data.set(buffer8); )太慢了。 &#34; .set&#34;函数将提供的数据复制到内部。(在2.6GHz CPU上大约需要0.3秒,而且速度不够快)
是否可以直接设置数据而无需复制数据? 是否可以直接填充画布的数组缓冲区?
有没有人知道我怎么能让它更快?
答案 0 :(得分:1)
确定。我已经解决了我的问题。最快的方法是不让Javascript做任何事情:D 诀窍是获取图像对象的底层缓冲区(Imagedata.data.buffer)并在其周围放置一个Uint8ClampedArray。 图像对象的缓冲区将直接填充在C-dll中,并且永远不会被&#34; set&#34;图像对象的功能。
此代码需要42毫秒才能将所需的数据放到画布上。 下面是代码:
copyImageData : function(pdfFilePath, pageNumber, canvas, offsetX, offsetY, scaleFactor) {
var startLoad = new Date();
var ctx = canvas.getContext('2d');
var imageData = ctx.createImageData(canvas.width, canvas.height);
var buffer = imageData.data.buffer;
var buffer8 = new Uint8ClampedArray(buffer);
var bufferPtr = ctypes.uint32_t.ptr(buffer);
copyImageData(pdfFilePath, pageNumber, bufferPtr, canvas.width, canvas.height, offsetX, offsetY, scaleFactor);
ctx.putImageData(imageData, 0, 0);
}