Перевод изображения в оттенки серого: таблицы, формулы и онлайн-конвертер
- Глаз человека неравномерно чувствителен к цветам: зелёный вклад в яркость ~59%, красный ~30%, синий ~11%.
- Самая точная яркостная формула (ITU-R BT.709): Gray = 0.2126·R + 0.7152·G + 0.0722·B
- Устаревший метод «среднего арифметического» даёт тёмные неестественные оттенки и не рекомендуется.
- Быстрый способ для веба — CSS-фильтр grayscale(100%) — работает аппаратно на GPU.
- Альфа-канал (прозрачность) обрабатывается отдельно: сохраняется без изменений.
- Почему простое усреднение не работает?
- Пошаговый пример: конвертируем пиксель вручную
- Код на JavaScript: конвертация через Canvas
- CSS-фильтр grayscale: мгновенно и без кода
- Обработка прозрачности и альфа-канала
- Распространённые ошибки и их решение
- Сравнение методов: таблица инструментов
- Edge-cases: градиенты, чёрно-белые фото, HDR
- Как отладить конвертацию вручную
Почему простое усреднение не работает?
Часто новички применяют формулу Gray = (R + G + B) / 3. Результат — грязно-серый, неестественный. Причина: глаз по-разному воспринимает яркость цветов. Зелёный кажется самым ярким, синий — самым тёмным. Усреднение даёт чрезмерно тёмный зелёный и светлый синий.
Корректные коэффициенты основаны на международном стандарте ITU-R BT.709:
где R, G, B — значения в гамма-скорректированном цветовом пространстве (sRGB). Если ваше изображение в линейном RGB (например, HDR), сначала нужно применить обратную гамма-коррекцию, затем посчитать яркость, затем снова гамма-скорректировать. В вебе 99% изображений sRGB, поэтому формула BT.709 работает напрямую.
Альтернативный стандарт ITU-R BT.601 (для SD-телевидения) использует другие веса: 0.299·R + 0.587·G + 0.114·B. Он немного светлее в красных тонах, но на практике разница незаметна.
Пошаговый пример: конвертируем пиксель вручную
Возьмём пиксель с цветом #3A7B12 (R=58, G=123, B=18).
- Проверяем, что значения в sRGB (обычно да).
- Применяем BT.709:
Gray = 0.2126×58 + 0.7152×123 + 0.0722×18 - Считаем:
12.33 + 87.97 + 1.30 = 101.60 - Округляем до целого: 102.
- Итоговый серый пиксель: (102, 102, 102) или #666666.
Если бы использовали среднее: (58+123+18)/3 = 66.33 → 66, что на 35% темнее. Разница критична для тёмных сцен.
Теперь попробуйте с любым цветом — используйте наш Конвертер изображения в оттенки серого для мгновенного преобразования.
Код на JavaScript: конвертация через Canvas
Самый простой способ в браузере — использовать <canvas>. Пишем функцию, которая обрабатывает каждый пиксель изображения.
function toGrayscale(canvas) {
const ctx = canvas.getContext('2d');
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const r = data[i];
const g = data[i + 1];
const b = data[i + 2];
// BT.709
const gray = 0.2126 * r + 0.7152 * g + 0.0722 * b;
data[i] = data[i + 1] = data[i + 2] = Math.round(gray);
// data[i+3] (альфа) не трогаем
}
ctx.putImageData(imageData, 0, 0);
}Важные нюансы:
- Прозрачность (альфа-канал) сохраняется — её не нужно менять.
- Для больших изображений (5000×5000+) на старых устройствах может тормозить — используйте WebAssembly или WebGL.
- Если изображение загружено с другого домена, canvas может быть «загрязнён» (CORS). Убедитесь, что сервер отдаёт
Cross-Origin-Resource-Policyили используйте режимcrossOrigin.
CSS-фильтр grayscale: мгновенно и без кода
Если нужно просто показать изображение в сером на странице, лучший способ — CSS.
img {
filter: grayscale(100%);
-webkit-filter: grayscale(100%); /* Safari */
}Браузер использует GPU-ускоренную яркостную формулу (обычно BT.709). Плюсы:
- Без JavaScript, работает мгновенно.
- Поддерживает анимацию:
transition: filter 0.5s;— плавно меняет насыщенность. - Можно задать процент: 50% — частичное обесцвечивание.
Минусы:
- Нельзя управлять формулой (BT.601, среднее).
- Исходное цветное изображение всё равно загружается целиком; не сэкономите трафик.
- В старых браузерах (IE11) не работает — нужен polyfill или SVG-фильтр.
После преобразования можно дополнительно собрать изображения в PDF или сжать их для экономии места.
- 1Загрузка пикселя
Получить RGB-значения из data imageData.
- 2Выбор формулы
Использовать BT.709: Gray = 0.2126R + 0.7152G + 0.0722B.
- 3Учёт альфа-канала
Оставить прозрачность без изменений или смешать с фоном.
- 4Применение гаммы (редко)
Только для линейного RGB: сначала обратная гамма, потом яркость, потом гамма.
- 5Округление
Math.round() до целого числа 0-255.
- 6Запись обратно
Присвоить R=G=B=Gray, альфа не трогать.
Обработка прозрачности и альфа-канала
Изображения в форматах PNG и TIFF содержат альфа-канал (прозрачность). При переводе в серый нужно решить: оставить альфу или залить фон?
Сохранить прозрачность: просто не трогайте четвёртый байт (альфа) каждого пикселя. Это подходит для иконок, логотипов.
Залить фон: если нужно получить непрозрачное серое изображение, предварительно смешайте с фоном (обычно белым). Формула для каждого канала:
где α_src — прозрачность пикселя (0..1). После смешивания альфе присваивается 255.
Пример на Canvas:
function blendWithWhite(imageData) {
const data = imageData.data;
for (let i = 0; i < data.length; i += 4) {
const alpha = data[i + 3] / 255;
data[i] = Math.round(data[i] * alpha + 255 * (1 - alpha));
data[i+1] = Math.round(data[i+1] * alpha + 255 * (1 - alpha));
data[i+2] = Math.round(data[i+2] * alpha + 255 * (1 - alpha));
data[i+3] = 255;
}
}После преобразования в серый фон уже не нужен — альфа становится непрозрачной.
🧠 Тест: выберите правильную формулу яркости
1. Почему среднее арифметическое (R+G+B)/3 не годится?
2. Какой вклад зелёного канала в яркость по BT.709?
3. Что произойдёт с альфа-каналом при конвертации?
4. Каким CSS-свойством можно быстро сделать изображение серым?
Распространённые ошибки и их решение
Ошибка 1: Использование среднего арифметического — серый получается неестественным. Исправляется заменой на BT.709.
Ошибка 2: Потеря прозрачности — случайно обнуляется альфа-канал. Проверяйте, что не трогаете data[i+3] или не присваиваете ей 255 без необходимости.
Ошибка 3: Некорректный CORS — canvas «загрязняется», и метод toDataURL() выбрасывает исключение. Решение: либо загружайте изображение с сервера, разрешающего CORS, либо используйте прокси.
Ошибка 4: Производительность на больших изображениях — обработка 8-мегапиксельной фотографии может занимать секунды. Совет: уменьшайте изображение перед конвертацией (например, до 1024px по ширине).
Ошибка 5: Несоответствие цветового пространства — некоторые изображения в Adobe RGB или ProPhoto RGB. Если преобразовывать их по sRGB-формуле, яркость будет неточной. Решение: конвертируйте в sRGB перед серым.
Совет: всегда тестируйте на изображениях с насыщенными красными и синими — на них ошибки виднее всего.
Сравнение методов: таблица инструментов
| Метод | Точность | Скорость | Простота |
|---|---|---|---|
| Canvas JS (BT.709) | Высокая | Средняя | Средняя |
| CSS grayscale(100%) | Высокая | Мгновенно (GPU) | Очень высокая |
| OpenCV (Python) | Максимальная | Высокая | Низкая |
| Онлайн-конвертер | Высокая | — | Максимальная |
Для разовых задач используйте Конвертер изображения в оттенки серого — он использует BT.709 и сохраняет альфа-канал. Если нужно сразу несколько операций, попробуйте конвертер в Base64 для встраивания в код.
Edge-cases: градиенты, чёрно-белые фото, HDR
Градиенты и плавные переходы: при конвертации могут появиться артефакты из-за округления. Используйте алгоритмы с дизерингом (Floyd-Steinberg) для более плавного результата, если цель — 8-битный серый.
Чёрно-белые фото с оттенком: старые фото часто имеют сепию (коричневый оттенок). Простое обесцвечивание даёт неестественный результат. Лучше сначала выполнить цветокоррекцию, затем конвертировать.
HDR-изображения: они хранятся в линейном цветовом пространстве с большим динамическим диапазоном. Формула BT.709 не подходит — сначала нужно применить tone-mapping (например, Reinhard) в sRGB, затем конвертировать.
GIF с палитрой: GIF использует индексный цвет. Для конвертации сначала преобразуйте в true color, затем в серый, затем оптимизируйте обратно в GIF с серой палитрой. Наш сервис сжатия поможет уменьшить итоговый размер.
Как отладить конвертацию вручную
Если результат выглядит неправильно (например, красные стали слишком тёмными), выполните следующие шаги:
- Откройте консоль браузера (F12).
- Выберите пиксель с проблемным цветом (используйте инструмент «Пипетка» или
canvas.getImageData). - Напишите короткий скрипт, вычисляющий серый по разным формулам:
function gray709(r,g,b) {
return Math.round(0.2126*r + 0.7152*g + 0.0722*b);
}
function gray601(r,g,b) {
return Math.round(0.299*r + 0.587*g + 0.114*b);
}
console.log('BT.709:', gray709(58,123,18));
console.log('BT.601:', gray601(58,123,18));
console.log('Average:', Math.round((58+123+18)/3));Сравните полученные значения с ожидаемым. Разница >10 указывает на несоответствие формулы.
Если проблема в скорости — профилируйте: console.time('gray'); ... console.timeEnd('gray'); для разных размеров изображения.
Для пакетной обработки удобно использовать Палитру из изображения онлайн — она анализирует доминирующие цвета и их яркость.
🧮 Посчитайте сами — инструменты по теме
🧭 Разделы по теме
Частые вопросы
Как перевести изображение в оттенки серого онлайн?
Используйте конвертер изображения в оттенки серого: загрузите фото, выберите метод (яркостный или средний) и скачайте результат. Обрабатываются форматы JPG, PNG, BMP, WebP.
Какая формула используется для перевода в серый в Photoshop?
Photoshop по умолчанию использует формулу яркости L = 0.299·R + 0.587·G + 0.114·B (ITU-R BT.601). В настройках можно изменить на sRGB или Lab.
Можно ли вернуть цвет из серого изображения?
Обратная операция невозможна без потери — информация о цвете уничтожена. Существуют алгоритмы колоризации (искусственные), но они не восстановят оригинал.
Почему серый иногда выглядит синеватым или зеленоватым?
Если используется неправильная формула (например, среднее арифметическое), синий становится слишком светлым, зелёный — слишком тёмным. Исправьте формулу на BT.709 или BT.601.
Как перевести в серый только часть изображения?
В CSS можно использовать маску или обрезку. В Canvas обойдите нужные пиксели циклом. В фоторедакторах — инструмент «кисть истории» или слой-маска.
Чем отличается конвертация через браузер от серверной?
Браузерная через Canvas работает на стороне клиента, не отправляя изображение на сервер — безопаснее для приватности. Серверная (ImageMagick, OpenCV) быстрее для больших объёмов.
Как сохранить прозрачность при переводе в серый?
В коде не трогайте четвёртый канал (альфа). В Photoshop — просто обесцветьте изображение (Shift+Ctrl+U), прозрачность сохранится. В онлайн-конвертерах выбирайте опцию «сохранить альфа-канал».
Какой формат изображения лучше для серого?
JPG подходит для фото (нет альфы, сжатие). PNG — для иконок и графики с прозрачностью. WebP сочетает хорошее сжатие и поддержку альфы.
Источники и нормативные документы
- ITU-R BT.709-6 - Parameter values for the HDTV standards
- ITU-R BT.601-7 - Studio encoding parameters of digital television
- MDN: CSS filter grayscale()
- W3C: Canvas 2D - Pixel manipulation
- Гамма-коррекция и цветовые пространства (Wikipedia)