ImageData 数组中的索引逻辑是什么?

What is the indexing logic in the ImageData array?

这个问题是为了更深入地理解我之前关于大尺寸Canvas动画的问题。问题在这里:Repeat HTML canvas element (box) to fill whole viewport

我想了解 TypedArray - Uint8ClampedArray 背后的逻辑。我会先从我的研究开始,然后再回到问题本身。

所以,ImageData代表了HTML5个Canvas的像素数据。它允许更快的性能并且适用于重动画。在我们有了 ImageData 对象之后,我们为它创建一个缓冲区 space。因为我们不能直接从/写入缓冲区,所以我们将此缓冲区传递给 TypedArray。在这种情况下,Uint8ClampedArray 类似于普通数组并允许访问其中的数据。

我们 canvas 上的每个像素由 4 个整数值表示,代表红色、绿色、蓝色、阿尔法 - 与 RGBA 中一样 - 范围从 0 到 255。这些值中的每一个都被分配给一个 Uint8ClampedArray索引从 0 开始,数组被分成 4 个块。所以前 4 个值是第一个像素,后 4 个值是第二个像素,依此类推。正在从左到右逐行读取 Cavnas 像素。

因此,例如,如果我们想要获取 xCoord = 3; yCoord = 1; canvasWidth = 10; 处像素的红色值的数组索引。 MDN: Pixel manipulation with canvas 中的公式建议我们进行以下计算:

var red = y * (width * 4) + x * 4; = 1 * 10 * 4 + 3 * 4 = 52;

但是如果我们尝试手动执行相同的操作,并且只是逐个像素地计算自己,我们就不会得到相同的值。它总是有点偏离。我们如何手动计算?在这张图中,我们从 0 X 0 开始到 0 X 9 再到 1 X 3。因为我们从左上角开始向右移动,所以它是倒置的,Y 是我们的第一个坐标,X 是我们的第二个坐标。从0 X 00 X 9一共记录了40个值(每个像素4个值,共10个像素宽度);从1 X 01 X 3一共记录了16个值。我们最后得到第 56 个索引,而不是我们使用公式计算的 52。

所以,请帮助我理解 Uint8ClampedArray 中的整个逻辑以及它是如何计算的。

From 1 X 0 to 1 X 3 we record 16 values in total

这 16 个中的最后 4 个字节表示 (3, 1) 处的像素。红色通道是其中的第一个,前面是左侧像素的 12 个字节和第一行中像素的 40 个字节。它位于整个数组中的索引 52。

记住 arrays are indexed 作为

0   1   2
+---+---+--
|   |   |
+---+---+--

不如

+---+---+--
| 0 | 1 | 2
+---+---+--