Blog. Just Blog

Эффект волнового искажения изображения на PHP

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

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

Код преобразования несложный. Создается целевое изображение с учетом высоты выступов волны, затем в цикле берутся точки из каждого ряда исходного изображения и по синусоиде накладываются на целевое изображение.
  1. // Обрабатываемый файл
  2. $file='image.jpg';
  3.  
  4. // Настройки параметров волны
  5. $wave_height=20;
  6. $wave_width=80;
  7.  
  8. $im=ImageCreateFromJPEG($file);
  9.  
  10. $width=ImageSX($im);
  11. $height=ImageSY($im);
  12.  
  13. $wave=ImageCreateTruecolor($width,$height+$wave_height*2);
  14.  
  15. $rgb=ImageColorAt($im,0,0);
  16. $R=($rgb >> 16) & 0xFF;
  17. $G=($rgb >> 8) & 0xFF;
  18. $B=$rgb 0xFF;
  19. $new_color=ImageColorAllocate($wave$R$G$B);
  20. ImageFilledRectangle($wave,0,0,$width,$height+$wave_height*2,$new_color);
  21.  
  22. for ($x=0$x<$width$x++) {
  23.     for ($y=0$y<$height$y++) {
  24.         // Вычисление позиции сдвига
  25.         $dy=$wave_height+intval($y+$wave_height*sin($x/$wave_width));
  26.         $rgb=ImageColorAt($im,$x,$y);
  27.  
  28.         $R=($rgb >> 16) & 0xFF;
  29.         $G=($rgb >> 8) & 0xFF;
  30.         $B=$rgb 0xFF;
  31.  
  32.         $new_color=ImageColorAllocate($wave$R$G$B);
  33.  
  34.         ImageSetPixel($wave,$x,$dy,$new_color);
  35.     }
  36. }
  37.  
  38. header("Content-type: image/jpeg");
  39. ImageJPEG($wave,NULL,100);
  40.  
  41. // Прибраться за собой
  42. ImageDestroy($im);
  43. ImageDestroy($wave);
Параметры колебания волны настраиваются значением переменных $wave_height и $wave_width. Соответственно, это высота волны и ее длина. Для изображений типа флагов значения должны быть побольше, для "морских" картинок поменьше. Заливка фона на участках подъема и спуска волны выполняется по цвету угловой точки изображения. Такой вариант хорош для изображений с одноцветной рамкой или однородным фоном. В некоторых случаях можно даже выполнять обрезку выступов, но это уже зависит от обрабатываемого изображения.

Эффект волнового искажения изображения на PHP
Эффект волнового искажения изображения на PHP

Эффект волнового искажения изображения на PHP
Эффект волнового искажения изображения на PHP

Для портретов и фотографий людей параметры настраиваются индивидуально. Результат получается как в кривых зеркалах в "Комнате смеха".

Эффект волнового искажения изображения на PHP
Эффект волнового искажения изображения на PHP

Алгоритм можно немного оптимизировать, чтобы во-первых, избавиться от вложенного цикла, а во-вторых, более корректно обрабатывать неоднородный фон на выступах волны.
  1. // Обрабатываемый файл
  2. $file='image.jpg';
  3.  
  4. // Настройки параметров волны
  5. $wave_height=15;
  6. $wave_width=15;
  7.  
  8. $im=ImageCreateFromJPEG($file);
  9.  
  10. $width=ImageSX($im);
  11. $height=ImageSY($im);
  12.  
  13. $wave=ImageCreateTruecolor($width,$height+$wave_height*2);
  14.  
  15. for ($x=0$x<$width$x++) {
  16.     $dy=$wave_height+intval($wave_height*sin($x/$wave_width));
  17.     ImageCopyResampled($wave,$im,$x,0,$x,0,1,$height+$wave_height*2,1,$height);
  18.     ImageCopy($wave,$im,$x,$dy,$x,0,1,$height);
  19. }
  20.  
  21. header("Content-type: image/jpeg");
  22. ImageJPEG($wave,NULL,100);
  23.  
  24. // Прибраться за собой
  25. ImageDestroy($im);
  26. ImageDestroy($wave);
Такой вариант будет хорошо работать на портретах и пейзажах, но плохо работать на флагах и изображениях с однотонными рамками. Так что решение выбирайте сами в зависимости от задачи.

Эффект волнового искажения изображения на PHP
Эффект волнового искажения изображения на PHP

Эффект волнового искажения изображения на PHP
Эффект волнового искажения изображения на PHP

Эффект волнового искажения изображения на PHP
Эффект волнового искажения изображения на PHP

Волну можно делать не только вертикальную, но и горизонтальную. Для этого в формулу расчета надо подставить координату Y, а сдвиг считать по координате X.

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

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

Комментарии

Отзывы посетителей сайта о статье
DiPrm (06.06.2022 в 23:15):
А Мона Лиза номер 2 напоминает Иосифа Бродского!
ManHunter (06.06.2022 в 14:06):
Ага, причем я специально никакие параметры волн для этого не подбирал, как-то само получилось с первого раза.
DiPrm (06.06.2022 в 11:51):
Собакен очень органично смотрится!)
кодер (05.06.2022 в 22:27):
ImageMagick ещё обычно пользуют на стороне сервера. К PHP вроде тоже прикручивается.

А вместо фотошопа я, например, давно уже пересел на GIMP, очень нравится, вполне реально перестроиться и привыкнуть. Очень много форматов поддерживает. Может там туториалов и книг для гимпа по-меньше будет, это да. Но на фотошоп возвращаться уже нет желания. Возня с лицензиями-активациями, прожорливость последних версий, ну его...
ManHunter (04.06.2022 в 13:38):
Ну есть же всякие онлайновые редакторы для графики. Морда крутится на JS, обработка выполняется частично на canvas, частично на сервере. Но полноценно заменить фотошоп невозможно.
NobootRecord (04.06.2022 в 13:32):
"Результат получается как в кривых зеркалах в 'Комнате смеха'" - хорошее сравнение, соглашусь. Особенно угарнул с "отфотошопленной" Мона Лизы.
А возможно ли реально портировать Photoshop на PHP? :)

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

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

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