Canvas imagedata多个像素插入

时间:2014-11-05 14:01:13

标签: javascript canvas pixels

我正在检索canvas imagedata中的像素,而且我正在做很多事情。

我认为在cpu时间内插入和检索canvas imagedata是很昂贵的,所以我想尽量减少这些。

切割的一种方法是制作一个可以在一个序列中插入多个像素的插入,但到目前为止我还没有看到如何做到这一点。到目前为止,我看到的所有示例都只检索并插入一个像素。

所以问题是, 为了加快画布imagedata像素操作,我如何同时插入/检索多个像素?

1 个答案:

答案 0 :(得分:2)

在检索像素缓冲区时,只需选择一个更大的区域:

var imageData = ctx.getImageData(x, y, width, height);
                                       ^^^^^^^^^^^^ not limited to one

现在,您的数据缓冲区将包含给定区域的所有像素。获得整个画布:

var imageData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);

调整它们并放回相同的位置:

ctx.putImageData(imageData, x, y);

你已经完成了。

请记住,每个像素由四个字节(RGBA)组成。要解决更大的缓冲区,您可以这样做:

function getPixelIndex(x, y) {
    return (y * width + x) * 4; // width used when getting buffer
}

提示:

  • 如果您计划更新同一缓冲区,通常只需检索一次缓冲区并存储指向它的指针,在需要时更新它并放回,然后重复使用相同的缓冲区。这样可以节省获取缓冲区的时间。如果您在平均时间使用标准方法将图形应用于画布,则无法使用。
  • 您也可以使用createImageData()代替getImageData()开始使用空缓冲区。
  • 如果您的像素颜色数据或多或少是静态的,则可以使用Uint32Array而不是Uint8ClampedArray来更新缓冲区。获得imageData后,您将获得这样的32位版本:

    var buffer32 = new Uint32Array(imageData.data.buffer);

您的新buffer32将指向相同的基础字节缓冲区,因此没有显着的内存开销,但它允许您读取和写入32位值而不仅仅是8位。请注意,字节顺序(通常)为little-endian,因此将字节排序为ABGR。然后像以前一样,在需要更新时调用ctx.putImageData(imageData, x, y);