【发布时间】:2017-03-01 18:37:44
【问题描述】:
大家好,就我而言,我有一个大的目标画布和一个小的屏幕外画布。
屏幕外的一个小于 100x100,而目标的一个是 5000x5000。当我调用 drawImage 将较小的画布复制到目标画布中时,我得到了一个巨大的内存峰值并且性能很糟糕。
我尝试将较小的画布转换为图像,这使得实际可用的性能更快。唯一的问题是图像需要时间来加载,因此当调用 onload 时,我的画布上下文发生了变化。 --- exif 数据也可能被忽略,这将解释图像的不同方向。
有没有办法从画布上下文中剥离属性,以便我可以保存和重置 onload 中的所有上下文属性?
我试图做 object.keys 但它总是返回一个空数组。我认为我剩下的唯一方法是直接在目的地上绘制而不是在屏幕外进行。它似乎更快,但我需要重做所有计算。
还有其他我可以尝试做的选择吗?
谢谢!
下面的渲染函数每秒调用几次。
fabObject._render = function(ctx) {
var canvas = document.createElement('canvas');
canvas.width = 100;
canvas.height = 100;
var ctx2 = canvas.getContext('2d');
myDrawFn() //this function draws to the new canvas. Performance is the same with this function commented or uncommented
ctx.drawImage(ctx2, 0,0)// This line causes performance to be terrible. I tried converting ctx2 to an image first and passing it in but the onload places the image in the wrong orientation. I'm guessing its not using the exif data.
}
更新: 我也尝试过每像素填充矩形,这也快了很多。然而,当我应用阴影属性时,它变得超级慢。我假设这是由于阴影具有高像素密度,但我不确定。
所以我做了进一步的测试,当我使用按像素绘图的方法时,实际上是阴影模糊导致速度变慢。没有模糊,有阴影很快。
【问题讨论】:
-
您不应该一开始就出现这种内存峰值。这里可能有问题。你能分享一个minimal reproducible example重现这个问题吗? drawImage 是在另一个画布上绘制一个画布的自然且最优化的方式。
-
所以我把整个函数注释掉了。我只用 document.createElement('canvas') 创建了第二个画布。然后我设置它的大小并直接调用drawImage()。即使没有调用任何其他绘图函数,将空画布复制到目标画布也非常慢。
-
可以显示您的代码的工作示例吗?在您的问题中,您可以添加一个有效的 sn-p。或者有一些在线服务,比如jsfiddle。
-
@user6728767 您是否考虑过在将较小的画布复制到目标画布fabricjs.com/docs/fabric.Canvas.html#renderOnAddRemove 时禁用
renderOnAddRemove? -
是的,我会在几分钟后发布一个示例 sn-p。 renderOnAddRemove 是只能在织物对象上设置的标志吗?这个函数特别是对我的织物对象渲染函数的覆盖。该渲染函数每隔几秒调用一次。这是我在实例化对象时必须设置的东西,还是可以在调用 drawImage 然后取消设置之前设置它?
标签: javascript canvas fabricjs