javascript - 最佳像素绘制速度?

标签 javascript canvas

我在 javascript 中使用 Canvas 对象。只是做一些测试,看看我在绘制循环中设置像素的速度有多快。

在 mac 上,它在 FF、safari、chrome 中运行良好。在 Windows 上,我对 FF 和 chrome 有闪烁的效果。对于不同的浏览器,windows 上的 Canvas 实现似乎与 mac 上的不同? (不确定这是不是真的)。​​

这是我用来绘图的基本代码(摘自下面的文章 - 我已经优化了下面的内容以收紧绘图循环,它现在运行得非常流畅):

var canvas = document.getElementById('myCanvasElt');
var ctx = canvas.getContext('2d');
var canvasData = ctx.getImageData(0, 0, canvas.width, canvas.height);
for (var x = 0; x < canvasData.width; x++) {
    for (var y = 0; y < canvasData.height; y++) {
        // Index of the pixel in the array
        var idx = (x + y * canvas.width) * 4;
        canvasData.data[idx + 0] = 0;
        canvasData.data[idx + 1] = 255;
        canvasData.data[idx + 2] = 0;
        canvasData.data[idx + 3] = 255;
    }
}
ctx.putImageData(canvasData, 0, 0);

同样,Windows 上的浏览​​器会有点闪烁。看起来 Canvas 实现试图在下一次绘图操作发生之前将 Canvas 清除为白色(这在 mac 上不会发生)。我想知道是否可以在 Canvas 对象中更改设置以修改该值(双缓冲、绘制前清除等)?

这是我用作引用的文章: http://hacks.mozilla.org/2009/06/pushing-pixels-with-canvas/

谢谢

最佳答案

我认为很明显,实现 Canvas 对象的浏览器使用 DIBS(设备独立位图)。您无需先锁定句柄就可以访问像素缓冲区这一事实证明了这一点。可以肯定的是,Direct2D 与浏览器中的 JS 无关。 GDI 是不同的,因为它使用 DDB(设备相关的位图,即从视频内存而不是传统的 ram 分配)。然而,所有这些都与最佳 JS 渲染速度无关。我认为按照您的方式编写 RGBA 值可能是最好的方法。

上述代码中的关键因素是对 putImageData() 的调用。这是浏览器在实现上可能有所不同的地方。您实际上是直接写入 DIB,而 putImageData 只是 InvalidateRect 的包装器吗?或者您实际上是在写入内存中的副本,然后将其复制到 Canvas 设备上下文中?如果您使用 linux 或 mac,那么这仍然是一个有效的问题。尽管设备上下文等通常是“windows”术语,但大多数操作系统以几乎相同的方式处理句柄或结构。但是,我们再次受到浏览器 vendor 的摆布。

我认为可以这样说:

如果您一次绘制许多像素,那么直接写入像素缓冲区可能是最好的方法。在 X 次操作后一次“bitblt”(复制)像素缓冲区会更快。这样做的原因是像 FillRect 这样的原生图形函数也调用“无效矩形”,它告诉系统如果屏幕需要重新绘制(刷新)那一部分。因此,如果您调用 100 行命令,则会发出 100 次更新 - 减慢进程。除非(这很重要)您使用应该使用的 beginPath/EndPath 方法。然后这是一个完全不同的球赛。

正是在这里开始/结束路径“系统”发挥作用,还有描边/轮廓命令。它们允许您在一次更新中执行 X 次绘图操作。但是很多人弄错了,每次调用 line/fillrect 等都会重绘。

此外,您是否尝试过创建一个不可见的 Canvas 对象,绘制到该对象上,然后复制到一个可见的 Canvas 上?这可能会更快(适当的双缓冲)。

关于javascript - 最佳像素绘制速度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2119016/

相关文章:

javascript - "requestAnimationFrame"方法无效

javascript - 在 MongoDB 中存储大数组

javascript - Django CORS 访问控制允许来源丢失

javascript - 通过 HTML5 或 JavaScript 启动 Android 手机前置摄像头

javascript - 我怎样才能获得这种动画背景效果?

javascript - 如何用requestAnimationFrame优化js动画并引入delta?

javascript - 平均数组列数

javascript - 使用javascript选择div文本的选择位置

javascript - 使用 Javascript 的井字游戏

javascript - Canvas:模拟具有缩放和旋转功能的相机