Обработка изображений 1. Введение
от aNNiMON
В этой вводной статье я расскажу о том, как кодируется цвет в компьютерной графике, заставлю немного поработать с битами
и покажу как быстро взаимодействовать с пикселями в JavaScript.

Содержание:
1. Введение
2. Изображения. Простая трансформация
3. Негатив, извлечение и инверсия каналов
4. Обесцвечивание
5. Цветовые модели
6. Яркость, насыщенность, контрастность, гамма-коррекция
7. Гистограмма
8. Масштабирование изображения
9. Размытие
10. Свёртка
Цвет
В физическом мире цвет представляет собой волну, в то время как в компьютерном мире это чаще всего число. Способов представления цвета много, о некоторых я расскажу в последующих статьях, а сегодня остановимся на самом распространённом — RGB.
В RGB цвет представляется как совмещение яркости трёх компонент: красного цвета (RED), зелёного (GREEN) и синего (BLUE). Минимальная яркость всех трёх компонент даёт нам чёрный цвет; максимальная яркость только красного, разумеется, даёт только красный цвет; максимальная яркость всех трёх компонент даёт белый цвет.

Минимальную и максимальную яркость можно представить разными способами:
- в процентах (0% — минимум, 100% — максимум)
- в вещественных числах (0.0 — минимум, 1.0 — максимум)
- в диапазоне одного байта (0 — минимум, 255 — максимум)
Из всех трёх способов, оптимальным для работы является третий, так как, по сравнению с первым, имеет более широкий диапазон, а по сравнению со вторым, использует целые числа. Именно этот способ представления цвета в RGB и получил широкое распространение.
Прозрачность
Кроме трёх компонент, отвечающих за цвет, существует ещё один компонент, отвечающий за прозрачность. Его ещё называют альфа-каналом (A - Alpha). Минимальное значение (0%, 0.0, 0) означает полностью прозрачный цвет, а максимальное (100%, 1.0, 255) — непрозрачный.
Способы представления цвета
Совмещение трёх (или четырёх) компонент даёт нам информацию о цвете (и прозрачности). Однако, что такое совмещение? В LED индикаторах, это набор из трёх светодиодов (вы уже поняли с какими цветами). В компьютерной графике совмещать компоненты цвета можно различными способами:
- не совмещать. Пусть себе идут поочерёдно в массиве.
- совмещать в одно число. 24-битное для RGB и 32-битное, если нужен альфа-канал.
В обоих случаях важно знать порядок следования компонент, потому что бывают разные:
- RGB. Здесь всё понятно, за красным следует зелёный, а потом синий.
- ARGB. Как и в предыдущем варианте, только прозрачность идёт первой.
- RGBA. Сначала цвет, потом прозрачность.
- BGR. Сначала синий, потом зелёный, потом красный.
- BGRA. Как и предыдущий, только прозрачность в конце.
Как три (или четыре) компоненты цвета совмещаются в одно число? Вспоминаем побитовые операции.
256 (от 0 до 255 включительно градаций) красного * 256 зелёного * 256 синего = 16777216 цветов.
16777216 цветов * 256 градаций прозрачности = 4294967296 значений.
Именно столько включает в себя 32-битный unsigned int.
Кодируется так:
ARGB: 00000000000000000000000000000000
ABGR: 00000000000000000000000000000000
RGBA: 00000000000000000000000000000000
Для удобства, такой цвет указывают в шестнадцатиричной системе счисления. Например, ARGB:
#AAFF0088: AA (170) - прозрачность, FF (255) - красный, 00 - зелёный, 88 (136) - синий
Работа с цветом в JavaScript
Окунёмся в дебри и будем работать с цветом в JavaScript вообще без использования библиотек jQuery и без самого jQuery.
По умолчанию, JavaScript вообще не совмещает компоненты, в массиве они идут друг за другом: pixels[0] - красный, pixels[1] - зелёный, pixels[2] - синий, pixels[3] - прозрачность. Этот способ медленный, поэтому рекомендуется использовать другой, где все компоненты совмещены в 32-битный unsigned int в ABGR — Uint32Array.
Вот пример закраски канваса красным, зелёным и синим цветом сначала с полной непрозрачностью (A = 255), а потом с полупрозрачностью (A = 128).
Следующая статья →

Содержание:
1. Введение
2. Изображения. Простая трансформация
3. Негатив, извлечение и инверсия каналов
4. Обесцвечивание
5. Цветовые модели
6. Яркость, насыщенность, контрастность, гамма-коррекция
7. Гистограмма
8. Масштабирование изображения
9. Размытие
10. Свёртка
Цвет
В физическом мире цвет представляет собой волну, в то время как в компьютерном мире это чаще всего число. Способов представления цвета много, о некоторых я расскажу в последующих статьях, а сегодня остановимся на самом распространённом — RGB.
В RGB цвет представляется как совмещение яркости трёх компонент: красного цвета (RED), зелёного (GREEN) и синего (BLUE). Минимальная яркость всех трёх компонент даёт нам чёрный цвет; максимальная яркость только красного, разумеется, даёт только красный цвет; максимальная яркость всех трёх компонент даёт белый цвет.

Минимальную и максимальную яркость можно представить разными способами:
- в процентах (0% — минимум, 100% — максимум)
- в вещественных числах (0.0 — минимум, 1.0 — максимум)
- в диапазоне одного байта (0 — минимум, 255 — максимум)
Из всех трёх способов, оптимальным для работы является третий, так как, по сравнению с первым, имеет более широкий диапазон, а по сравнению со вторым, использует целые числа. Именно этот способ представления цвета в RGB и получил широкое распространение.
Прозрачность
Кроме трёх компонент, отвечающих за цвет, существует ещё один компонент, отвечающий за прозрачность. Его ещё называют альфа-каналом (A - Alpha). Минимальное значение (0%, 0.0, 0) означает полностью прозрачный цвет, а максимальное (100%, 1.0, 255) — непрозрачный.
Способы представления цвета
Совмещение трёх (или четырёх) компонент даёт нам информацию о цвете (и прозрачности). Однако, что такое совмещение? В LED индикаторах, это набор из трёх светодиодов (вы уже поняли с какими цветами). В компьютерной графике совмещать компоненты цвета можно различными способами:
- не совмещать. Пусть себе идут поочерёдно в массиве.
- совмещать в одно число. 24-битное для RGB и 32-битное, если нужен альфа-канал.
В обоих случаях важно знать порядок следования компонент, потому что бывают разные:
- RGB. Здесь всё понятно, за красным следует зелёный, а потом синий.
- ARGB. Как и в предыдущем варианте, только прозрачность идёт первой.
- RGBA. Сначала цвет, потом прозрачность.
- BGR. Сначала синий, потом зелёный, потом красный.
- BGRA. Как и предыдущий, только прозрачность в конце.
Как три (или четыре) компоненты цвета совмещаются в одно число? Вспоминаем побитовые операции.
256 (от 0 до 255 включительно градаций) красного * 256 зелёного * 256 синего = 16777216 цветов.
16777216 цветов * 256 градаций прозрачности = 4294967296 значений.
Именно столько включает в себя 32-битный unsigned int.
Кодируется так:
ARGB: 00000000000000000000000000000000
- (alpha << 24) | (red << 16) | (green << 8) | blue
- (alpha << 24) | (blue << 16) | (green << 8) | red
- (red << 24) | (green << 16) | (blue << 8) | alpha
Для удобства, такой цвет указывают в шестнадцатиричной системе счисления. Например, ARGB:
#AAFF0088: AA (170) - прозрачность, FF (255) - красный, 00 - зелёный, 88 (136) - синий
Работа с цветом в JavaScript
Окунёмся в дебри и будем работать с цветом в JavaScript вообще без использования библиотек jQuery и без самого jQuery.
- // Получили canvas, его размеры и контекст
- const canvas = document.getElementById('canvas');
- const width = canvas.width;
- const height = canvas.height;
- const ctx = canvas.getContext('2d');
- // Получаем данные. Формат: {data: [], width: xx, height: xx}
- const img = ctx.getImageData(0, 0, width, height);
- const pixels = img.data;
- // Обрабатываем
- // pixels[...] = ...
- // Заносим данные
- ctx.putImageData(img, 0, 0);
По умолчанию, JavaScript вообще не совмещает компоненты, в массиве они идут друг за другом: pixels[0] - красный, pixels[1] - зелёный, pixels[2] - синий, pixels[3] - прозрачность. Этот способ медленный, поэтому рекомендуется использовать другой, где все компоненты совмещены в 32-битный unsigned int в ABGR — Uint32Array.
- const canvas = document.getElementById('canvas');
- const width = canvas.width;
- const height = canvas.height;
- const ctx = canvas.getContext('2d');
- const img = ctx.getImageData(0, 0, width, height);
- const pixels = new Uint32Array(img.data.buffer);
- // Обрабатываем
- // pixels[...] = ...
- ctx.putImageData(img, 0, 0);
Вот пример закраски канваса красным, зелёным и синим цветом сначала с полной непрозрачностью (A = 255), а потом с полупрозрачностью (A = 128).
See the Pen Image processing 1 by aNNiMON (@aNNiMON) on CodePen.
2. Изображения. Простая трансформация