Blog. Just Blog

Эффект выборочного цвета на PHP

Версия для печати Добавить в Избранное Отправить на E-Mail | Категория: Web-мастеру и не только | Автор: ManHunter
Эффект выборочного цвета на PHP
Эффект выборочного цвета на PHP

Эффект выборочного цвета есть в некоторых фотоаппаратах Nikon, во многих графических редакторах. Сам эффект заключается в том, что на изображении цветным остается только какой-нибудь один тон, а все остальные цвета преобразуются в оттенки серого. Выборочный цвет, например, часто применяется в оформлении готических фотографий, на которых кроваво-красные цветы, элементы одежды или предметы сочетаются с мрачным черно-белым фоном.

Выборочный цвет - красный
Выборочный цвет - красный

Я решил реализовать подобный эффект на PHP. Алгоритм обработки простой: в цикле проходим по всем точкам изображения, если точка попадает в нужный цветовой тон, то она остается без изменения, иначе обесцвечивается. Обрабатывать изображение попиксельно мы умеем, определять цвета точек тоже. Основной код позаимствован из предыдущей статьи, оттуда же взята формула получения значения цветового тона из RGB-цвета.
  1. // Файл для обработки
  2. $im=ImageCreateFromJPEG('test.jpg');
  3.  
  4. // Размеры изображения
  5. $width=ImageSX($im);
  6. $height=ImageSY($im);
  7.  
  8. for ($x=0$x<$width$x++) {
  9.     for ($y=0$y<$height$y++) {
  10.         $rgb=ImageColorAt($im,$x,$y);
  11.  
  12.         $R=($rgb >> 16) & 0xFF;
  13.         $G=($rgb >> 8) & 0xFF;
  14.         $B=$rgb 0xFF;
  15.  
  16.         // Цветовой тон
  17.         $maxRGB=max(array($R$G$B));
  18.         $minRGB=min(array($R$G$B));
  19.         $delta=$maxRGB-$minRGB;
  20.  
  21.         if ($delta!=0) {
  22.             if ($maxRGB==$R) {
  23.                 $h=(($G-$B)/$delta);
  24.             }
  25.             elseif ($maxRGB==$G) {
  26.                 $h=2+($B-$R)/$delta;
  27.             }
  28.             elseif ($maxRGB==$B) {
  29.                 $h=4+($R-$G)/$delta;
  30.             }
  31.             $hue=round($h*60);
  32.             if ($hue<0) { $hue+=360; }
  33.         }
  34.         else {
  35.             $hue=0;
  36.         }
  37.  
  38.         // Оставить только красный цветовой тон
  39.         if (!($hue>320 || $hue<=20)) {
  40.             // Преобразовать цвет в оттенки серого
  41.             $gray=0.2126*$R+0.7152*$G+0.0722*$B;
  42.             $new_color=ImageColorAllocate($im$gray$gray$gray);
  43.             ImageSetPixel($im,$x,$y,$new_color);
  44.         }
  45.     }
  46. }
  47.  
  48. // Прибраться за собой
  49. ImageDestroy($im);
Как вычисляется диапазон цветового тона, я подробно рассказал в статье про определение основного цвета, но тут, скорее всего, граничные значения придется корректировать и подбирать опытным путем. А вот на преобразовании в оттенки серого стоит остановиться. Для того, чтобы преобразовать цвет из RGB в оттенки серого, используется формула:

Gray = 0.2126*R + 0.7152*G + 0.0722*B
Соответственно, при обесцвечивании точки изображения, каждая составляющая RGB исходного цвета получает одинаковые значения, равные значениям оттенков серого.

Вот несколько примеров фотографий с наложенным на них эффектом выборочного цвета. Все они были получены только при помощи этого скрипта, никакие графические редакторы при этом не использовались.

Исходное изображение
Исходное изображение

Выборочный цвет - красный
Выборочный цвет - красный

Выборочный цвет - зеленый
Выборочный цвет - зеленый

Исходное изображение
Исходное изображение

Выборочный цвет - синий
Выборочный цвет - синий

Выборочный цвет - желтый
Выборочный цвет - желтый

Этот же код можно использовать просто для преобразования изображения в оттенки серого. Для этого надо убрать вычисление цветового тона и проверку его граничных значений.
  1. $file='test.jpg';
  2. $im=ImageCreateFromJPEG($file);
  3.  
  4. $width=ImageSX($im);
  5. $height=ImageSY($im);
  6.  
  7. for ($x=0$x<$width$x++) {
  8.     for ($y=0$y<$height$y++) {
  9.         $rgb=ImageColorAt($im,$x,$y);
  10.  
  11.         $R=($rgb >> 16) & 0xFF;
  12.         $G=($rgb >> 8) & 0xFF;
  13.         $B=$rgb 0xFF;
  14.  
  15.         $gray=0.2126*$R+0.7152*$G+0.0722*$B;
  16.         $new_color=imagecolorallocate($im$gray$gray$gray);
  17.         imagesetpixel($im,$x,$y,$new_color);
  18.     }
  19. }
  20.  
  21. header("Content-type: image/jpeg");
  22. ImageJPEG($im,NULL,100);
  23.  
  24. // Прибраться за собой
  25. ImageDestroy($im);
Получается примерно так:

Изображение в оттенках серого
Изображение в оттенках серого

Еще один вариант этого эффекта - "рентгеновский снимок". Тут тоже считается оттенок серого, но немного по другой формуле, а затем цвет инвертируется.
  1. $file='test.jpg';
  2. $im=ImageCreateFromJPEG($file);
  3.  
  4. $width=ImageSX($im);
  5. $height=ImageSY($im);
  6.  
  7. for ($x=0$x<$width$x++) {
  8.     for ($y=0$y<$height$y++) {
  9.         $rgb=ImageColorAt($im,$x,$y);
  10.  
  11.         $R=($rgb >> 16) & 0xFF;
  12.         $G=($rgb >> 8) & 0xFF;
  13.         $B=$rgb 0xFF;
  14.  
  15.         $gray=0.3*$R+0.6*$G+0.1*$B;
  16.  
  17.         $gray=280-$gray;
  18.         if ($gray>255) { $gray=255; }
  19.  
  20.         $new_color=imagecolorallocate($im$gray$gray$gray);
  21.         imagesetpixel($im,$x,$y,$new_color);
  22.     }
  23. }
  24.  
  25. header("Content-type: image/jpeg");
  26. ImageJPEG($im,NULL,100);
  27.  
  28. // Прибраться за собой
  29. ImageDestroy($im);
Изменяя коэффициент инвертирования, можно добиться различных вариантов рентгеновского снимка. Мне больше нравится значение 280.

Эффект рентгеновского снимка
Эффект рентгеновского снимка

А вот программная реализация алгоритма из статьи. При помощи этой утилиты можно удалять с изображения ненужные цвета. Автор - wetal, за что ему большое спасибо.

Remove color 0.1Remove color 0.1

Remove.color.0.1.zip (228,871 bytes)


Поделиться ссылкой ВКонтакте
Просмотров: 2884 | Комментариев: 14

Метки: PHP, графика
Внимание! Статья опубликована больше года назад, информация могла устареть!

Комментарии

Отзывы посетителей сайта о статье
ManHunter (12.04.2022 в 11:04):
Добавил эффекты оттенков серого и рентгеновских лучей.
Never (27.07.2016 в 15:52):
wetal, спасибо!
voffka (20.07.2016 в 06:40):
Теперь понятно как на али семена рисуют
master-ufa (19.07.2016 в 17:21):
Спасибо. То, что доктор прописал.
DiPrm (19.07.2016 в 09:39):
Красивая реализация на PHP и отличная программа! От себя добавлю, что интересный эффект дает закрашивание фона в черный цвет помимо оттенок серого, можно также добавить прозрачность.
ManHunter (18.07.2016 в 11:02):
Прикольно получилось, спасибо! Прицеплю к статье в качестве примера.
wetal (18.07.2016 в 10:43):
Вот, посмотрите что вышло:
win2util.far.ru/programs/remcol.zip

После запуска программы выбираем изображение( положил в архив два с разными цветами!), оно открывается в уменьшенном размере. если умещается не всё в окне, то можно окно программы растянуть.
Галочками отмечаем, какой цвет оставить и нажимаем Просмотр, для возврата всех цветов нажимаем Сброс. Правой кнопкой мыши можно на картинке выбрать цвет, который надо удалить с картинки, если даже он входит в диапазон выбранных цветов. Это бывает полезно для коррекции.
Вроде всё остальное понятно. Проверял на win XP.
ManHunter (17.07.2016 в 20:13):
А лучше на файлообменник, тогда я приаттачу программу к статье.
master-ufa (17.07.2016 в 19:16):
wetal пришли на электронку: 771973@mail.ru
wetal (15.07.2016 в 18:04):
master-ufa, можно легко! Я почти так и сделал "на коленке" тестовую. Могу оформить в конечный вариант, если надо.
Never (15.07.2016 в 13:04):
Ох не фигаж ты демон! Фотошоп фотошопом, а тут же хоть пакетную обработку фигач. Да и не всегда же комбайн в виде фотошопа нужен, я до сих пор твоими "пилотами" пользуюсь.
ManHunter (15.07.2016 в 11:01):
master-ufa, фотошоп же: http://photoshop-help.ru/3061-...yy-urok.html
master-ufa (15.07.2016 в 10:25):
А можно сделать программку, где в одном окне файл находишь, а в другом определяешь какие цветы оставить/убрать?
wetal (15.07.2016 в 06:18):
Спасибо, очень полезный алгоритм. Предыдущую статью "Определение основного цвета изображения на PHP" видел, но  как то тогда не увидел практической ценности( на PHP не пишу). А тут с наглядными примерами сразу стало ясно где и как можно применить. Переписал для себя, отлично работает и на десктопе, достаточно быстро фильтрует цвета!

Добавить комментарий

Заполните форму для добавления комментария
Имя*:
Текст комментария (не более 2000 символов)*:

*Все поля обязательны для заполнения.
Комментарии, содержащие рекламу, ненормативную лексику, оскорбления и т.п., а также флуд и сообщения не по теме, будут удаляться. Нарушителям может быть заблокирован доступ к сайту.
Наверх
Powered by PCL's Speckled Band Engine 0.2 RC3
© ManHunter / PCL, 2008-2024
При использовании материалов ссылка на сайт обязательна
Время генерации: 0.09 сек. / MySQL: 2 (0.0038 сек.) / Память: 4.5 Mb
Наверх