4

我不认为 Fabric.js 是这里的罪魁祸首,因为当我添加时间警报时,它只需要 2-3 秒。但是,这是它使用的代码:

 applyTo: function(canvasEl) {
    var context = canvasEl.getContext('2d'),
        imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
        data = imageData.data,
        len = imageData.width * imageData.height * 4,
        index = 0,
        average;

    while (index < len) {
      average = (data[index] + data[index + 1] + data[index + 2]) / 3;
      data[index]     = average;
      data[index + 1] = average;
      data[index + 2] = average;
      index += 4;
    }

    context.putImageData(imageData, 0, 0);
  },

因此,如果不是罪犯,那么罪犯就是putImageData功能。

有什么方法可以增加/优化该功能,使其在不到 15 秒的时间内处理 5000x5000 图像?

如果没有,有没有办法设置一个“工作”图标,只有在 putImageData 通过 jQuery 完成后才会被删除,因为目前,它会在 2 秒后被删除,因为 Fabric.js 代码完成得更快?

4

2 回答 2

1

如果putImageData花费的时间最多,则无法提高其速度,因为它是浏览器提供的低级功能。

您可以做的是逐渐处理图像并将其显示给用户,而不会连续 15 秒阻塞浏览器。

提示:我建议不要使用时间警报来计时脚本的执行,而是使用 Chrome 开发人员工具。他们有一个很棒的javascript分析工具,更具体地说,是画布绘图。

谷歌开发者工具火焰图

于 2014-01-04T03:35:02.877 回答
0

我对fabric.js 不是很熟悉,但是您对画布进行优化的选择非常有限。将您的变量一个接一个地放置,而不是创建一个平均变量,这将为您节省一点时间:

data[index] = data[index+1] = data[index+2] = (data[index] + data[index + 1] + data[index + 2]) / 3;
index+=4;

您可能还想尝试将数据按行放在画布上。它不会加快速度,但如果你有这么大的画布,向用户展示一些进展会很好。在下面的示例中,我这样做并将您的 while 循环更改为两个 for 循环,因为我更喜欢 for 循环 :)

for(var i=0;i<imageData.height;i++) {
    var row = context.getImageData(0, i, canvasEl.width, 1);
    for(var j=0;j<imageData.width*4;j+=4) {
        row.data[index] = row.data[index+1] = row.data[index+2] = (row.data[index] + row.data[index + 1] + row.data[index + 2]) / 3;
        context.putImageData(row, 0, i);
    }
}
于 2014-01-03T23:27:40.553 回答