Какова логика индексации в массиве 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
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
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

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