gpt4 book ai didi

performance - 为什么 putImageData 这么慢?

转载 作者:技术小花猫 更新时间:2023-10-29 11:39:34 26 4
gpt4 key购买 nike

我正在使用一个相对较大的 Canvas ,其中绘制了各种(复杂的)东西。然后我想保存 Canvas 的状态,以便稍后可以快速将其重置为现在的状态。我为此使用 getImageData 并将数据存储在变量中。然后,我在 Canvas 上绘制了更多内容,稍后将使用 putImageData 将 Canvas 重置为我保存它的状态时的状态。

但是,事实证明,putImageData 非常慢。事实上,它比简单地从头开始重新绘制整个 Canvas 要慢,后者涉及覆盖大部分表面的多个 drawImage,以及超过 40,000 次 lineTo 操作,然后是描边和填充。

从头开始重新绘制大约 2000 x 5000 像素的 Canvas 大约需要 170 毫秒,而使用 putImageData 则需要高达 240 毫秒。为什么 putImageData 与重绘 Canvas 相比如此慢,尽管重绘 Canvas 涉及用 drawImage 填充几乎整个 Canvas ,然后再次使用 lineTo、描边和填充用多边形填充大约 50% 的 Canvas 。所以基本上每个像素在重绘时至少被触及一次。

因为 drawImage 似乎比 putImageData 快得多(毕竟,重新绘制 Canvas 的 drawImage 部分只需要不到 30 毫秒)。我决定尝试不使用 getImageData 来保存 Canvas 的状态,而是使用 canvas.toDataURL,然后从数据 URL 创建一个图像,我会将其粘贴到 drawImage 中以将其绘制到 Canvas 上。事实证明,整个过程要快得多,只需要大约 35 毫秒即可完成。

那么为什么 putImageData 比替代方法(使用 getDataURL 或简单地重绘)慢得多?我怎样才能进一步加快速度?是否存在,如果存在,通常存储 Canvas 状态的最佳方式是什么?

(所有数字均使用 Firefox 中的 Firebug 测量)

最佳答案

只是关于执行此操作的最佳方法的小更新。我实际上在 High Performance ECMAScript and HTML5 Canvas 上写了我的学士论文(pdf,德语;密码:stackoverflow),所以我现在已经收集了一些关于这个主题的专业知识。显然最好的解决方案是使用多个 Canvas 元素。从一个 Canvas 绘制到另一个 Canvas 与将任意图像绘制到 Canvas 一样快。因此,当使用两个 Canvas 元素时,“存储” Canvas 的状态与稍后再次恢复它一样快。

This jsPerf testcase非常清楚地展示了各种方法及其优缺点。

只是为了完整起见,这里是您应该真正做到的:

// setup
var buffer = document.createElement('canvas');
buffer.width = canvas.width;
buffer.height = canvas.height;


// save
buffer.getContext('2d').drawImage(canvas, 0, 0);

// restore
canvas.getContext('2d').drawImage(buffer, 0, 0);

根据浏览器的不同,此解决方案比获得赞成票的解决方案快 5000 倍。

关于performance - 为什么 putImageData 这么慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3952856/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com