Blog. Just Blog

Эффект тиснения на PHP

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

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

Каждый стиль задается матрицей со смещениями миксуемых пикселов, в приведенном примере их 5.
  1. // Стиль тиснения 0..4
  2. $emboss_style=0;
  3.  
  4. // Изображение для обработки
  5. $file='image.jpg';
  6.  
  7. // Матрицы стилей тиснения
  8. $matrix=array(
  9.     array(
  10.         array(1.00.0, -1.0),
  11.         array(2.00.0, -2.0),
  12.         array(1.00.0, -1.0),
  13.     ),
  14.     array(
  15.         array(1.02.01.0),
  16.         array(0.00.00.0),
  17.         array(-1.0, -2.0, -1.0),
  18.     ),
  19.     array(
  20.         array(2.01.00.0),
  21.         array(1.00.0, -1.0),
  22.         array(0.0, -1.0, -2.0),
  23.     ),
  24.     array(
  25.         array(-2.0, -1.00.0),
  26.         array(-1.00.01.0),
  27.         array(0.01.02.0),
  28.     ),
  29.     array(
  30.         array(-2.0, -2.00.0),
  31.         array(-2.06.00.0),
  32.         array(0.00.00.0),
  33.     ),
  34. );
  35.  
  36. $im=ImageCreateFromJPEG($file);
  37.  
  38. $width=ImageSX($im);
  39. $height=ImageSY($im);
  40.  
  41. $gray_pixels=array();
  42. for ($x=0$x<$width$x++) {
  43.     for ($y=0$y<$height$y++) {
  44.         $rgb=ImageColorAt($im,$x,$y);
  45.         $R=($rgb >> 16) & 0xFF;
  46.         $G=($rgb >> 8) & 0xFF;
  47.         $B=$rgb 0xFF;
  48.  
  49.         $gray=intval(0.2126*$R+0.7152*$G+0.0722*$B);
  50.         if ($gray>255) {
  51.             $gray=255;
  52.         }
  53.         $gray_pixels[$y*$width+$x]=$gray;
  54.     }
  55. }
  56.  
  57. $min=1000000;
  58. $max=0;
  59.  
  60. $emboss=array();
  61.  
  62. for ($y=0$y<$height$y++) {
  63.     $y_prev=$y-1;
  64.     if ($y_prev<0) {
  65.         $y_prev=0;
  66.     }
  67.     $y_next=$y+1;
  68.     if ($y_next>$height-1) {
  69.         $y_next=$height-1;
  70.     }
  71.  
  72.     $w1=$y_prev*$width;
  73.     $w2=$y*$width;
  74.     $w3=$y_next*$width;
  75.  
  76.     for ($x=0$x<$width$x++) {
  77.         $x_prev=$x-1;
  78.         if ($x_prev<0) {
  79.             $x_prev=0;
  80.         }
  81.         $x_next=$x+1;
  82.         if ($x_next>$width-1) {
  83.             $x_next=$width-1;
  84.         }
  85.  
  86.         $new=
  87.             $gray_pixels[$w1+$x_prev]*$matrix[$emboss_style][0][0]+
  88.             $gray_pixels[$w1+$x]*$matrix[$emboss_style][0][1]+
  89.             $gray_pixels[$w1+$x_next]*$matrix[$emboss_style][0][2]+
  90.             $gray_pixels[$w2+$x_prev]*$matrix[$emboss_style][1][0]+
  91.             $gray_pixels[$w2+$x]*$matrix[$emboss_style][1][1]+
  92.             $gray_pixels[$w2+$x_next]*$matrix[$emboss_style][1][2]+
  93.             $gray_pixels[$w3+$x_prev]*$matrix[$emboss_style][2][0]+
  94.             $gray_pixels[$w3+$x]*$matrix[$emboss_style][2][1]+
  95.             $gray_pixels[$w3+$x_next]*$matrix[$emboss_style][2][2];
  96.  
  97.         $emboss[$y*$width+$x]=$new;
  98.  
  99.         $min=min($min,$new);
  100.         $max=max($max,$new);
  101.     }
  102. }
  103.  
  104. if (($diff=$max-$min)<1) {
  105.     $diff=1;
  106. }
  107.  
  108. for ($x=0$x<$width$x++) {
  109.     for ($y=0$y<$height$y++) {
  110.         $clr=($emboss[$y*$width+$x]-$min)*255/$diff;
  111.         $color=ImageColorAllocate($im,$clr,$clr,$clr);
  112.         ImageSetPixel($im,$x,$y,$color);
  113.     }
  114. }
  115.  
  116. // Вывести изображение в браузер
  117. header("Content-type: image/jpeg");
  118. ImageJPEG($im,NULL,100);
  119.  
  120. // Прибраться за собой
  121. ImageDestroy($im);
В зависимости от выбранного стиля тиснения, результат будет отличаться. Например, изображение будет выпуклое или наоборот, вдавленное. Также вы можете поэкспериментировать с собственными матрицами для получения различных эффектов.

Оригинальное изображение
Оригинальное изображение

Эффект тиснения на PHP
Эффект тиснения на PHP

Эффект тиснения на PHP
Эффект тиснения на PHP

Эффект тиснения на PHP
Эффект тиснения на PHP

Эффект тиснения на PHP
Эффект тиснения на PHP

Эффект тиснения на PHP
Эффект тиснения на PHP

Да, я в курсе про существование штатной функции PHP Imagefilter с фильтром IMG_FILTER_EMBOSS. Вот какой результат она дает на этом же изображении, причем только один, без возможности настроек.

Результат работы функции Imagefilter
Результат работы функции Imagefilter

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

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

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

Комментарии

Отзывы посетителей сайта о статье
ManHunter (24.04.2023 в 21:33):
Тут главный смысл в алгоритме, а не в наборе готовых функций.
Petya (24.04.2023 в 19:18):
Судя по коду, у Вас там свёртка + обесцвечивание, а претензия к встроенному EMBOSS - корявое ядро. Отсюда вопрос: на предмет скорости с приличным качеством, не смотрели на imageconvolution (https://www.php.net/manual/ru/function.imageconvolution.php) + IMAGE_FILTER_COLORIZE со своими коэффициентами?

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

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

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