Blog. Just Blog

Рисуем компас на PHP

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

Появилась следующая задача. Есть пачка изображений, каждому изображению соответствует определенное направление съемки. Требуется промаркировать все изображения картинкой компаса, который указывает это направление. С самой маркировкой проблем не возникло, а вот с компасами пришлось немного повозиться.

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

Простой поворот изображения
Простой поворот изображения

Для достижения правильного результата надо сделать следующее. На исходном изображении компаса отмечаются координаты, по которым должны находиться надписи, а сами надписи с изображения удаляются в графическом редакторе. При обработке изображение компаса поворачивается на нужный угол, а затем на него уже наносятся надписи скриптом. Новые координаты для каждой надписи считаются по формуле из школьного курса геометрии.
  1. // Файл с изображением компаса
  2. $im=ImageCreateFromPNG('compass.png');
  3.  
  4. // Размеры изображения
  5. $img_width=ImageSX($im);
  6. $img_height=ImageSY($im);
  7.  
  8. // Отступ текста
  9. $padding=25;
  10. // Название и размер шрифта
  11. $font_name='arialbd.ttf';
  12. $font_size=24;
  13. // Угол поворота компаса по часовой стрелке
  14. $angle=25;
  15.  
  16. // Координаты и текст надписей
  17. $coords=array(
  18.     array(
  19.         'x'=>intval($img_width/2),
  20.         'y'=>$padding,
  21.         'txt'=>'N'
  22.     ),
  23.     array(
  24.         'x'=>($img_width-$padding),
  25.         'y'=>intval($img_height/2),
  26.         'txt'=>'E'
  27.     ),
  28.     array(
  29.         'x'=>intval($img_width/2),
  30.         'y'=>($img_height-$padding),
  31.         'txt'=>'S'
  32.     ),
  33.     array(
  34.         'x'=>$padding,
  35.         'y'=>intval($img_height/2),
  36.         'txt'=>'W'
  37.     ),
  38. );
  39.  
  40. // Цвет фона для поворота
  41. $back_color=ImageColorAllocate($im255,255,255);
  42.  
  43. // Повернуть компас на заданный угол
  44. $rotation=ImageRotate($im,(360-$angle),$back_color);
  45.  
  46. // Цвет текста для надписей
  47. $text_color=ImageColorAllocate($rotation0,0,0);
  48.  
  49. // Размеры получившегося изображения
  50. $n_width=ImageSX($rotation);
  51. $n_height=ImageSY($rotation);
  52.  
  53. foreach($coords as $data) {
  54.     // Угол поворота в радианах
  55.     $rad=deg2rad($angle);
  56.  
  57.     // Координаты центра изображения
  58.     $dx=$img_width/2;
  59.     $dy=$img_height/2;
  60.  
  61.     $new_x=$dx+($data['x']-$dx)*cos($rad)-($data['y']-$dy)*sin($rad);
  62.     $new_y=$dy+($data['x']-$dx)*sin($rad)+($data['y']-$dy)*cos($rad);
  63.  
  64.     // Корректировка координат под размер нового изображения
  65.     $new_x+=intval(($n_width-$img_width)/2);
  66.     $new_y+=intval(($n_height-$img_height)/2);
  67.  
  68.     // Корректировка координат с учетом размера символов
  69.     $tmpx=ImageTTFBBox($font_size,0,$font_name,$data['txt']);
  70.     $fx=intval(($tmpx[2]-$tmpx[0])/2);
  71.     $new_x-=$fx;
  72.     $fy=intval(($tmpx[7]-$tmpx[1])/2);
  73.     $new_y-=$fy;
  74.  
  75.     // Нанести текст на изображение
  76.     ImageTTFText($rotation,$font_size,0,
  77.         $new_x,$new_y,$text_color,$font_name,$data['txt']
  78.     );
  79. }
  80.  
  81. // Обрезать изображение компаса под оригинальные размеры
  82. ImageCopy($im,$rotation,0,0,
  83.     intval(($n_width-$img_width)/2),
  84.     intval(($n_height-$img_height)/2),
  85.     $img_width,$img_height
  86. );
  87.  
  88. // Вывести в браузер
  89. header("Content-type: image/jpeg");
  90. ImageJPEG($im,NULL,100);
  91.  
  92. // Прибраться за собой
  93. ImageDestroy($im);
  94. ImageDestroy($rotation);
В коде учитывается, что после поворота изображение будет увеличено, а также корректируются позиции надписей в зависимости от ширины и высоты символов в выбранном шрифте. Готовое изображение компаса по размерам соответствует исходному.

Поворот изображения с нанесением текста
Поворот изображения с нанесением текста

Как вы можете видеть, результат выглядит гораздо лучше. Все обозначения сторон света находятся на своих местах, при этом оставаясь читаемыми. По этому же принципу можно не только рисовать компас, но и обрабатывать другие изображения, где используется поворот и нанесение каких-либо текстовых элементов на его участки.

Поделиться ссылкой ВКонтакте Поделиться ссылкой на Facebook Поделиться ссылкой на LiveJournal Поделиться ссылкой в Мой Круг Добавить в Мой мир Добавить на ЛиРу (Liveinternet) Добавить в закладки Memori Добавить в закладки Google
Просмотров: 240 | Комментариев: 4

Метки: PHP, графика

Комментарии

Отзывы посетителей сайта о статье
ManHunter (20.10.2022 в 16:21):
Нет. Воровская звезда восьмиконечная, с лучами одинаковой длины.
Ellephant (20.10.2022 в 08:09):
Так может воровская звезда это и есть компас?! Символизирует типа "я свободен как ветер"! Ну а компАс назвать вроде не по фене, вот и назвали звезда. Это моя версия, если что. ;)
ManHunter (15.10.2022 в 11:31):
Как говорил дедушка Фрейд, иногда сигара - это просто сигара.
OggO (15.10.2022 в 09:16):
Получилась звезда воровская)))
Огуречек огуречек - получился человечек)

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

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

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