且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-10-17 23:36:20

从1 X 0到1 X 3,我们总共记录了16个值

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

请记住,将数组编入索引

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

不是

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

This question is for a deeper understanding of my previous question about large size Canvas animation. The question is here: Repeat HTML canvas element (box) to fill whole viewport

I am trying to understand the logic behind the TypedArray - Uint8ClampedArray. I will first start with my research and get to the question itself later.

So, ImageData represents the pixel data of the HTML5 Canvas. It allows for much faster performance and is good for heavy animations. After we have our ImageData object, we create a buffer space for it. Because we can not read & write directly from / to buffer, we pass this buffer to a TypedArray. In this case Uint8ClampedArray which is like a normal array and allows to access data inside it.

Each pixel on our canvas is represented by 4 integer values that stand for red, green, blue, alfa - as in RGBA - ranging from 0 to 255. Each of these value is assigned to an Uint8ClampedArray index starting from 0 and the array is divided into chunks of 4. So first 4 values are very first pixel, second 4 values are 2nd pixel and so on. The Cavnas pixels are being read from left to right, row by row.

So if for example we want to get array index of red value of the pixel at xCoord = 3; yCoord = 1; canvasWidth = 10;. The formula from MDN: Pixel manipulation with canvas suggests that we do the following math:

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

But if we try to do the same manually, and just calculate ourselves pixel by pixel, we don't get the same value. It's always a little off. How would we calculate manually? In this picture we start from 0 X 0 to 0 X 9 and to 1 X 3. Because we start from top left and move toward right, it's inverted and Y is our first coordinate and X is our second coordinate. From 0 X 0 to 0 X 9 we record 40 values in total (4 values on each pixel, 10 pixels in total width); From 1 X 0 to 1 X 3 we record 16 values in total. We get 56th index at the end, instead of 52 as we had calculated using the formula.

So, please help me understand the whole logic in Uint8ClampedArray and how it's calcualted.

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

The last 4 bytes of these 16 do represent the pixel at (3, 1). The red channel is the first of these, preceded by 12 bytes for the pixels to the left and 40 bytes for the pixels in the first row. It is sitting at index 52 in the overall array.

Remember that arrays are indexed as

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

not as

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