Какова логика индексации в массиве ImageData?

Этот вопрос предназначен для более глубокого понимания моего предыдущего вопроса об анимации холста большого размера. Вопрос здесь: Повторите элемент холста HTML (поле), чтобы заполнить всю область просмотра.

Я пытаюсь понять логику TypedArray — Uint8ClampedArray. Я сначала начну с моего исследования и перейду к самому вопросу позже.

Итак, ImageData представляет пиксельные данные холста HTML5. Он обеспечивает гораздо более высокую производительность и хорош для тяжелых анимаций. После того, как у нас есть объект ImageData, мы создаем для него буферное пространство. Поскольку мы не можем читать и писать напрямую из/в буфер, мы передаем этот буфер в TypedArray. В данном случае это Uint8ClampedArray, который похож на обычный массив и позволяет получить доступ к данным внутри него.

Каждый пиксель на нашем холсте представлен 4 целочисленными значениями, которые обозначают красный, зеленый, синий, альфа — как в RGBA — в диапазоне от 0 до 255. Каждому из этих значений присваивается индекс Uint8ClampedArray, начиная с 0, и массив делится на куски по 4. Таким образом, первые 4 значения — это самый первый пиксель, вторые 4 значения — это 2-й пиксель и так далее. Пиксели Cavnas считываются слева направо, строка за строкой.

Итак, если, например, мы хотим получить индекс массива красного значения пикселя в xCoord = 3; yCoord = 1; canvasWidth = 10;. Формула из MDN: Манипулирование пикселями с холстом предполагает, что мы делаем следующую математику:

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 0 до 0 X 9 записываем 40 значений (по 4 значения на каждый пиксель, 10 пикселей в общей ширине); Всего от 1 X 0 до 1 X 3 записываем 16 значений. В итоге получаем 56-й индекс, а не 52, как мы рассчитали по формуле.

Итак, пожалуйста, помогите мне понять всю логику в Uint8ClampedArray и как она вычисляется.

Этот ответ — хороший канонический ресурс для работы с этой структурой.
ggorlen 08.03.2022 23:11
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
Раскрытие чувствительных данных
Раскрытие чувствительных данных
Все внешние компоненты, рассмотренные здесь до сих пор, взаимодействуют с клиентской стороной. Однако, если они подвергаются атаке, они не...
Зод: сила проверки и преобразования данных
Зод: сила проверки и преобразования данных
Сегодня я хочу познакомить вас с библиотекой Zod и раскрыть некоторые ее особенности, например, возможности валидации и трансформации данных, а также...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Руководство ChatGPT по продаже мини JS-файлов
Руководство ChatGPT по продаже мини JS-файлов
JS-файл - это файл, содержащий код JavaScript. JavaScript - это язык программирования, который в основном используется для добавления интерактивности...
2
1
524
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Всего от 1 X 0 до 1 X 3 мы записываем 16 значений.

Последние 4 байта из этих 16 представляют пиксель в (3, 1). Красный канал является первым из них, ему предшествуют 12 байтов для пикселей слева и 40 байтов для пикселей в первой строке. Он находится под индексом 52 в общем массиве.

Помните, что массивы индексируются как

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

не как

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

Другими словами, пиксель с координатами 3,1 охватывает индексы от 52 до 55, и поскольку массивы имеют индекс 0, 56-е значение находится в индексе 55 -> их метод получает конечный индекс пикселя, а метод MDN получает начальный индекс. И, кстати, для OP более понятным способом написания формулы MDN было бы ((y * width) + x) * 4 -> индекс пикселя * байт на пиксель.

Kaiido 19.12.2020 03:29

Другие вопросы по теме