Эффект рисунка масляными красками на PHP
Эффект рисунка масляными красками на PHP
Еще один красивый художественный эффект на PHP - преобразование фотографии в рисунок масляными красками. Такой эффект часто встречается в различных графических редакторах и приложениях, а сегодня разберем, как он достигается.
Сперва немного теории. Для получения цветного мазка надо определить толщину кисти, то есть радиус области, в которой цвет будет приводиться к единому значению. Чем больше толщина кисти, тем менее детальным будет получаться изображение. Но и слишком тонкой кисть делать не надо, оптимальное значение радиуса 5-6. Второй важный параметр для преобразования - это интенсивность цвета. Она задает погрешность, при которой два слегка отличающихся цвета приравниваются к одному. Чем больше это значение, тем более детальным будет результат. По результатам тестирования наилучший баланс достигается при значении интенсивности в диапазоне 25-50. Значения лучше подбирать индивидуально для каждого изображения.
Code (PHP) : Убрать нумерацию
- $file='image.jpg';
- // Файл для обработки
- $im=ImageCreateFromJPEG($file);
- // Размеры изображения
- $width=ImageSX($im);
- $height=ImageSY($im);
- // Результат
- $im2=ImageCreateTruecolor($width,$height);
- // Радиус обработки
- $radius=5;
- // Предельная интенсивность
- $int_level=25;
- for ($x=$radius; $x<($width-$radius); $x++) {
- for ($y=$radius; $y<($height-$radius); $y++) {
- $sumR=array();
- $sumG=array();
- $sumB=array();
- $intensity=array();
- ; Получить интенсивность для всех точек в заданном радиусе
- for($nx=-$radius; $nx<$radius; $nx++) {
- for($ny=-$radius; $ny<$radius; $ny++) {
- $rgb=ImageColorAt($im,$x+$nx,$y+$ny);
- $R=($rgb >> 16) & 0xFF;
- $G=($rgb >> 8) & 0xFF;
- $B=$rgb & 0xFF;
- $cur_int=round(((($R+$G+$B)/3)*$int_level)/255);
- if ($cur_int>255) { $cur_int=255; }
- if (!isset($intensity[$cur_int])) {
- $intensity[$cur_int]=0;
- $sumR[$cur_int]=0;
- $sumG[$cur_int]=0;
- $sumB[$cur_int]=0;
- }
- $intensity[$cur_int]++;
- $sumR[$cur_int]+=$R;
- $sumG[$cur_int]+=$G;
- $sumB[$cur_int]+=$B;
- }
- }
- ; Определить преобладающий цвет в области
- $cur_max=0;
- $max_index=0;
- for($i=0; $i<256; $i++) {
- if (isset($intensity[$i])) {
- if ($intensity[$i]>$cur_max) {
- $cur_max=$intensity[$i];
- $max_index=$i;
- }
- }
- }
- $_R=round($sumR[$max_index]/$cur_max);
- $_G=round($sumG[$max_index]/$cur_max);
- $_B=round($sumB[$max_index]/$cur_max);
- $new_color=ImageColorAllocate($im2, $_R, $_G, $_B);
- ImageSetPixel($im2,$x,$y,$new_color);
- }
- }
- // Добавить размытие
- ImageFilter($im2, IMG_FILTER_GAUSSIAN_BLUR);
- ImageFilter($im2, IMG_FILTER_GAUSSIAN_BLUR);
- // Вывести результат в браузер
- header("Content-type: image/jpeg");
- ImageJPEG($im2,NULL,100);
- // Прибраться за собой
- ImageDestroy($im);
- ImageDestroy($im2);
Так как в обработчике используется несколько вложенных циклов, время работы в любом случае будет ощутимым, даже для небольших изображений. К сожалению, особой оптимизации тут никак не добиться. Про обработку огромных плакатов в реальном времени тоже, увы, можно не мечтать.
Эффект рисунка масляными красками на PHP
Из-за особенностей работы алгоритма на готовом изображении получается не закрашенная рамка толщиной в радиус. Смотрится не очень красиво, поэтому перед нанесением точек на готовое изображение лучше определить цвет границы исходного изображения и выполнить заливку фона.
Эффект рисунка масляными красками на PHP
Для сглаживания резких линий можно воспользоваться функцией ImageFilter с эффектом размытия IMG_FILTER_GAUSSIAN_BLUR, причем применить ее к изображению надо как минимум дважды.
Просмотров: 698 | Комментариев: 1
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
Дмитрий
(09.04.2022 в 18:21):
МОНА САКС. МАКС ПАЙН!!!
Добавить комментарий
Заполните форму для добавления комментария