|
|
|
|
|
|
Рассылки Subscribe.ru |
Генерация картинок на Drupal-сайтеПри работе над одним своим проектом понадобилось написать PHP-скрипт, который генерирует изображение. С PHP в этом нет ничего сложного. Поскольку проект уже был сделан на Drupal, возникла мысль, а нельзя ли сделать это используя его возможности, например, для использования некоторых системных функций или подключения к базе данных. Оказалось можно. Причем, как минимум двумя способами: в отдельном файле и в собственном модуле. Способ первый. Отдельный файл.Создадим в корне сайта файл с названием image.php. Попробуем вывести изображение с числом материалов размещенных на нашем сайте. Код очень простой: <?php /* Подключаем Drupal и загружаем его. После вызова функции drupal_bootstrap доступны все функции и системные переменные Drupal. */ require_once './includes/bootstrap.inc'; drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL); /* Отправляем браузеру заголовок типа контента: изображение в формате PNG. */ drupal_set_header("Content-type: image/png"); /* Создаем изображение. */ $image = imagecreate(88, 31); /* Определяем цвета фона и текста. */ $background_color = imagecolorallocate($image, 2, 122, 198); $text_color = imagecolorallocate($image, 255, 255, 255); /* Заливаем фон изображения. */ imagefill($image, 0, 0, $background_color); /* Запрашиваем из таблицы нод количество материалов сайта. */ $query = "SELECT COUNT(`nid`) FROM `{node}`"; $result = db_result(db_query ($query)); /* Выводим результат в изображение. */ imagestring($image, 5, 5, 7, $result , $text_color); /* Отдаем изображение в браузер. */ imagepng($image); /* Освобождаем ресурсы в оперативной памяти сервера. */ imagedestroy($image); Способ второй. Модуль Drupal.Статичное изображениеПусть наш модуль называется testimagepng. function testimagepng_menu() { $items['testimage.png'] = array( 'type' => MENU_CALLBACK, 'page callback' => 'testimagepng_image', 'access arguments' => array('access content'), ); return $items; } В том же файле разместим функцию testimagepng_image которая и будет генерировать изображение. Код почти совпадает с приведенным в первом способе. function testimagepng_image() { drupal_set_header("Content-type: image/png"); $image = imagecreate(88, 31); $background_color = imagecolorallocate($image, 2, 122, 198); $text_color = imagecolorallocate($image, 255, 255, 255); imagefill($image, 0, 0, $background_color); $query = "SELECT COUNT(`nid`) FROM `{node}`"; $result = db_result(db_query ($query)); imagestring($image, 5, 5, 7, $result , $text_color); imagepng($image); imagedestroy($image); /* Прерываем выполнение скриптов, чтобы Drupal не посылал в конце изображения своего вывода. */ exit(); } Достоинством этого метода генерации картинок состоит в том, что в HTML она вставляется при помощи кода, который ничем не отличается от кода для вставки обычного PNG-изображения в виде файла: <img src="http://example.com/testimage.png"> Изображение выглядит как статичный файл, но генерировать ее вы можете каким угодно способом внутри функции testimagepng_image(). Динамически генерируемое изображениеНебольшая неточнось, этого заголовка состоит в том, что изображение по прежнему выглядит как статичный файл, но будет генерироваться в зависимости от его названия. Попробуем запрограммировать разбор такого синтаксиса названия файла: НОМЕР_НОДЫ-РАЗМЕР_ШРИФТА-ШИРИНА-ВЫСОТА-ЦВЕТ_ТЕКСТА-ЦВЕТ_ФОНА.РАСШИРЕНИЕ_ФАЙЛА Например: 108-10-500-30-FFFFFF-027AC6.gif Итак, пусть модуль называется banner_generator (с полным правом, между прочим). function banner_generator_menu() { $items['banners/%'] = array( 'page arguments' => array(1), 'type' => MENU_CALLBACK, 'page callback' => 'banner_generator_generate', 'access arguments' => array('access content'), ); return $items; } После включения модуля в структуре нашего сайта появится адрес http://example.com/banners/ приобращении к которому все, что мы наберем после завершающего слеша попадет в функцию banner_generator_generate () в качестве первого параметра. Т.е., если мы запросим адрес http://example.com/banners/108-10-500-30-FFFFFF-027AC6.gif, то функции будет передан аргумент 108-10-500-30-FFFFFF-027AC6.gif. Реализуем требуемую функцию. function banner_generator_generate ($file='') { /* Для отображения нелатинского текста на изображениях нам потребуется файл шрифта формата True Type Файл должен лежать в папке модуля. Взять его можно из папки шрифтов Windows. Ф случае отсутствия файла Drupal сгенерирует страницу Page not found. */ $font = drupal_get_path('module', 'banner_generator') . "/arial.ttf"; if (!file_exists($font)) return drupal_not_found(); /* Разбиваем полученый параметр на имя файла и расширение. */ $tmp = explode('.', $file); $name = array_shift($tmp); $ext = strtolower(array_pop($tmp)); /* Разбиваем по дефисам имя файла на отдельные компоненты. */ $tmp = explode('-', $name); /* Получаем идентификатор ноды и достаем заголовок нужной страницы из базы. */ $nid = (int) array_shift($tmp); $query = "SELECT `title` FROM `{node}` WHERE `nid`=%d"; $result = db_result(db_query ($query, $nid)); if ($result===FALSE) return drupal_not_found(); /* Получаем размер шрифта. В случае, слишком большого, неправильного или отсутствующего значения ставим по умолчанию в 15px. */ $size = (int) array_shift($tmp); $size = $size < 1 ? 15 : $size; $size = $size > 100 ? 15 : $size; /* Определяем размеры контейнера требуемого для текста. */ list($lower_left_X, $lower_left_Y, $lower_right_X, $lower_right_Y, $upper_right_X, $upper_right_Y, $upper_left_X, $upper_left_Y) = imagettfbbox ($size, 0, $font, $result); $box_width = max($lower_left_X, $lower_right_X, $upper_right_X, $upper_left_X) - min ($lower_left_X, $lower_right_X, $upper_right_X, $upper_left_X) + 1; $box_height = max($lower_left_Y, $lower_right_Y, $upper_right_Y, $upper_left_Y) - min($lower_left_Y, $lower_right_Y, $upper_right_Y, $upper_left_Y) + 1; /* Теперь получаем требуемую ширину изображения. Если она отсутствует, слишком мала или велика, то устанавливаем ее чуть больше контейнера текста */ $width = (int) array_shift($tmp); $width = $width <1 ? $box_width + $size : $width; $width = $width > 1000 ? $box_width + $size : $width; $height = (int) array_shift($tmp); $height = $height <1 ? $box_height + $size : $height; $height = $height > 1000 ? $box_height + $size : $height; /* Создаем изображение рассчитанных размеров */ $image = imagecreatetruecolor($width, $height); if (!$image) return drupal_not_found(); /* Получаем и задаем для изображения цвет текста и разбираем его на красный, зеленый и голубой цвета. Все ошибки трактуются в пользу отсутствия цвета. */ $color = array_shift($tmp); $red = substr($color, 0, 2); $red = $red ? $red : '00'; $green = substr($color, 2, 2); $green = $green ? $green : '00'; $blue = substr($color, 4, 2); $blue = $blue ? $blue : '00'; $text_color = imagecolorallocate($image, hexdec($red), hexdec($green), hexdec($blue)); /* Получаем и задаем для изображения цвет фона и разбираем его на красный, зеленый и голубой цвета. Все ошибки трактуются в пользу наличия цвета. Заливаем фон. */ $color = array_shift($tmp); $red = substr($color, 0, 2); $red = $red ? $red : 'FF'; $green = substr($color, 2, 2); $green = $green ? $green : 'FF'; $blue = substr($color, 4, 2); $blue = $blue ? $blue : 'FF'; $background_color = imagecolorallocate($image, hexdec($red), hexdec($green), hexdec($blue)); imagefill($image, 0, 0, $background_color); /* Рассчитываем координаты левого нижнего угла контейнера текста (это особенность функции imagettftext) так, чтобы контейнер встал по центру изображения. После этого выводим текст в изображение. */ $x = (int) ($width - $box_width)/2; $y = (int) ($height + $box_height - $size/2)/2; imagettftext ($image, $size, 0, $x, $y, $text_color, $font, $result); /* Теперь в зависимости от расширения файла посылаем браузеру клиента соответствующие заголовкии и отдаем изображение. В случае неправильного расширения генерируем ошибку Page not found. */ switch ($ext) { case 'png': drupal_set_header("Content-type: image/png"); @imagepng($image); break; case 'gif': drupal_set_header("Content-type: image/gif"); @imagegif($image); break; case 'jpg': case 'jpeg': drupal_set_header("Content-type: image/jpeg"); @imagejpeg($image); break; default: imagedestroy($image); return drupal_not_found(); } /* Освобождаем ресурсы в оперативной памяти сервера и завершаем исполнение скриптов, чтобы Drupal не добавил свой вывод. */ imagedestroy($image); exit(); } Вставлять в код сайта такое динамическое изображение можно обычным способом. Например, код баннера этой статьи будет выглядеть так: Вернее так: Источники |
|
Direqtor Home Page by ASIADATA. |
|
Второй модуль,
Второй модуль, предназначенный для генерации заголовка ноды не срабатывает. Сделал все как в примере, положил шрифт в папку модуля и кстати! переименовал функцию которая в примере:
function testimagepng_menu()
на
function banner_generator_menu()
Первый модуль (с количеством опубликованных нод) - ОК.
Поправил
Спасибо за замечание.
Отправить комментарий