Преобразование объявления в графическую файл карточку jpg формата 1.X

1672
Вот тут человек просил инструкцию на русском языке.

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

Самого заинтересовал этот вопрос, сначала подумал про canvas, потом понял, что для этой задачи можно по-проще вариант, поэтому немного разобрался в том как работают функции

imagefilledrectangle
imagettftext
imagecopymerge
и так далее.

Итак, генерация изображения с содержимым объявления.



0. Создаём папку /cards в директории images/board/

1. В components/board/fronted.php

перед

Код PHP:
  1. cmsPage::initTemplate('components', 'com_board_item')->
+

Код PHP:
  1. //генерируем карточку
  2. if(!file_exists('images/board/cards/'.$item['id'].'.jpg')){
  3.  
  4. $im = imagecreatetruecolor(500, 300); //ширина и высота картинки
  5. $border = imagecolorallocate($im, 203, 222, 240); //цвет рамки в формате RGB
  6. $bg = imagecolorallocate($im, 223, 235, 246); //цвет основного фона
  7. $black = imagecolorallocate($im, 0, 0, 0); //цвет текста
  8. imagefilledrectangle($im, 0, 0, 499, 299, $border); //рисуем основную подложку с цветом рамки, координаты слева верх, слева низ, справа верх, справа низ
  9. imagefilledrectangle($im, 20, 20, 479, 279, $bg); //основное поле с отступами от краев, благодаря которым будет эффект рамки, координаты слева верх, слева низ, справа верх, справа низ
  10. $cardtext = substr($item['content'], 0, 600); //получаем текст для картинки, обрезаем до 600 знаков
  11. $cardtext = wordwrap($cardtext, 80); //максимальная длина строки 80 символов после чего строка переносится, слова не разбиваются
  12. $cardtext .= '...'; //добавляем в конец текста многоточие
  13. $font = 'components/board/arial.ttf'; //указываем путь к шрифту, не забываем положить сам файл шрифта в указанное место
  14.  
  15. $cardtext = str_replace('<br />', '', $cardtext); //вырезаем тег переноса из текста, иначе он будет печататься на картинку
  16.  
  17. imagettftext($im, 13, 0, 30, 40, $black, $font, $cardtext); //рисуем из текста картинку: файл, размер шрифта, угол в градусах, координаты начала текста по x оси, по y оси, вет текста, файл шрифта, текст
  18.  
  19. //наносим водяной знак, если он не нужен три следующие строки можно удалить.
  20. $stamp = imagecreatefromjpeg('images/watermark.jpg'); // Здесь указан путь к файлу водяного знакоа в формате jpg
  21. imagecopymerge($im, $stamp, 270, 250, 0, 0, 199, 28, 60); //наносим водяной знак: исходный файл, файл водяного знака, отступ слева, отступ сверху, 0,0 - отсутствие смещений в координатах на самом файле водяного знака, ширина файла ВЗ, высота ВЗ, прозрачность ВЗ
  22. imagedestroy($stamp); //удаляем файл водяного знака из памяти
  23.  
  24. imagejpeg($im, 'images/board/cards/'.$item['id'].'.jpg'); //готовую карточку в папку images/board/cards. Каждое изображение имеет номер который совпадает с номером объявления.
  25.  
  26. imagedestroy($im); //очищаем память от изображения карточки
  27.  
  28. }
  29.  
  30. $item['card'] = '/images/board/cards/'.$item['id'].'.jpg';
Максимально подробно прокомментировал для тех, кто будет подгонять всё это дело под себя.

2. В файле components/board/model.php
добавим строку которая будет удалять карточку при удалении объявления

после

Код PHP:
  1. @unlink(PATH.'/images/board/'.$item['file']);
  2. @unlink(PATH.'/images/board/small/'.$item['file']);
  3. @unlink(PATH.'/images/board/medium/'.$item['file']);
+

Код PHP:
  1. //удаляем карточку объявления
  2. @unlink(PATH.'/images/board/cards/'.$item['id'].'.jpg');


3.В настройках кнопки "поделиться" указываем путь до картинки как '/images/board/cards/ТУТ-НОМЕР-ОБЪЯВЛЕНИЯ.jpg

Например, если речь идет о кнопке "поделиться" от Яндекса, которая вставлена в шаблон компонента объявления com_board_items.tpl

Код PHP:
  1. <script src="//yastatic.net/es5-shims/0.0.2/es5-shims.min.js"></script>
  2. <script src="//yastatic.net/share2/share.js"></script>
  3. <div class="ya-share2" data-services="collections,vkontakte,facebook,odnoklassniki,moimir" data-image="{$item.card}"></div>
на картинку здесь указывает вот это: data-image="{$item.card}"

Карточка сгенерированная при тех параметрах которые я указал в коде выше, выглядит вот так


Преобразование объявления в графическую файл карточку jpg формата
Набор мелочей Vol1 | Сообщение об ошибке 404 в основном дизайне сайта и релевантные подсказки
Комментарии (8)
Олег Васильевич я 15 июня 2017 в 18:03 +3
Нил™, подскажите, пожалуйста, а если переписать код снизу вверх, текст из картинки можно выудить?
Спойлер
Helg 15 июня 2017 в 18:30 0
Loadырь 15 июня 2017 в 18:34 +1
Олег Васильевич я, для этих целей достаточно перевернуть монитор и запустить заново.
Нил™ 15 июня 2017 в 20:15 0
предлагаете парсить объявления из картинок с парсенными объявлениями? Ну надо подумать, хотя вон тут уже предлагают решение.
Димитриус 19 июня 2017 в 01:39 0
ИМХО, Может лучше реализовать "налету" по запросу картинки сразу картинку и скармливать без создания файла на сервере. как минимум меньше движений с файлами на сервере.
Нил™ 19 июня 2017 в 14:31 0
что бы скормить картинку нужно указать ссылку на нее. Если генерировать картинку на лету без сохранения на сервере, как будет выглядеть урл картинки? data:img? Не проверял конечно, но вряд ли социальная сеть примет такой адрес.
Нил™ 19 июня 2017 в 14:35 0
и возникает вопрос: что считать инициализацией запроса картинки? блок поделиться сторонний скрипт, не знаю наверно можно как то повесить на клик по кнопке "поделиться" ещё и генерировать картинку по этому клику, но вряд ли все эти танцы имеют смысл. 1 раз сгенерировать и сохранить картинку и один раз удалить её при удалении объявления, не так уж много действий)
Димитриус 20 июня 2017 в 18:06 +1
1.указать заголовок
Header("Content-type: image/jpeg");
2. Вывести картинку imagejpeg без 2 параметра
3. через реварайт генерить ссылку с jpg на конце