PHP-торт на день Рождения!

С Днём Рождения?!

Наша задача – сделать какую-нибудь приятную картинку для поздравления наших клиентов ко дню рождения. Что можно придумать оригинальней, чем выписывать его имя поверх какой-нибудь картинки, например, праздничного торта? Ведь своё имя всегда приятно видеть, особенно в таком контексте.

Планируем, собираем ресурсы

Итак, пишем простейший PHP скрипт для вывода надписи поверх картинки.

Торт наш будет выглядеть так –

Наш праздничный торт ко Дню Рождения!

Используем формат PNG с прозрачным цветом. Мы его немного затемнили в редакторе, чтобы надпись поверх выглядела более ярко. Сохраним его в папке images под именем bd_cake.png.

Шрифт. Использовать будем TTF-шрифт Fita_Poluustav (fitpustv.ttf – взять здесь, бесплатный).

Сообразим так – имя клиента выписываем поверх торта посередине, а внизу надпись “поздравляем!“. Цвет шрифта будем использовать зелёный, так как он приятнее для глаз и нравится большинству женщин и мужчин (согласно опросу, о котором я где-то на хабре читал недавно).

Итак, торт готов, шрифт готов, теперь пишем небольшой PHP-скриптик, используя старую добрую GD библиотеку (доп. пояснения к коду даны ниже).

Сразу замечу только, что имя скрипту задаётся через GET параметр name, если он не указан используем имя любимой девушки или жены, например, Светлана. Длина имени не должна превышать 13 символов.

Кодировка скрипта и имени должна быть UTF-8.

// Файл bd_cake.php
 
// пробуем получить имя из GET-параметра name
$name = htmlspecialchars(urldecode(@$_GET['name']));
if(trim($name) == '')
	$name = 'Светлана';
 
// ограничим имя 13 символами, иначе оно будет вылезать за пределы экрана
// используем mb_ функции, так как UTF8 мультибайтовая кодировка
if(mb_strlen($name,'utf-8') > 13)
	$name = mb_substr($name,0,13,'utf-8');
 
// путь по умолчанию для шрифта - текущий каталог
putenv('GDFONTPATH=' . realpath('.')); 
$font = 'fitpustv'; // название шрифта без расширения ttf
 
$im = imagecreatefrompng('images/bd_cake.png'); // наш торт
$green = imagecolorallocate($im,0x0,0xFF,0x34); // цвет зелёный
 
// Выкл. alpha blending и вкл. флаг alpha (см. ниже)
imagealphablending($im, false);
imagesavealpha($im, true);
imagealphablending($im, true);
 
$text = 'поздравляем!';
$x = getX(27,0, $text);
imagettftext($im, 27, 0, $x, 255, $green, $font, $text);
 
$text = $name;
$sz = 36;
$x = getX($sz,16, $text);
$y = getY($sz,16, $text);
imagettftext($im, $sz, 16, $x, $y, $green, $font, $text);
 
 
header('Content-Type: image/png');
imagepng($im);
die;
 
// центруем текст по X
function getX($size, $angle, $text)
{
	global $font, $im;
 
	$ts = imagettfbbox($size,$angle,$font,$text);
	$dx = abs($ts[2] - $ts[0]);
	return (imagesx($im) - $dx) / 2;
}
 
// центруем текст по Y
function getY($size, $angle, $text)
{
	global $font, $im;
 
	$ts = imagettfbbox($size,$angle,$font,$text);
	$dy = abs($ts[5] - $ts[3]);
	return (imagesy($im) - $dy) / 2 + $dy;
}

Тестируем

В итоге по умолчанию получаем такое:

С Днём Рождения!

Имя:

Для теста используем поле ввода и кнопку “Обновить” так:

<input id="text" size="30" maxlength="20">
<button onclick="document.getElementById('cake').src=
   'http://atzar.ru/bd_cake.php?name='+document.getElementById('text').value">Обновить
</button>

Доп. пояснения к скрипту

Такой код:

// Выкл. alpha blending и вкл. флаг alpha (см. ниже)
imagealphablending($im, false);
imagesavealpha($im, true);
imagealphablending($im, true);

выглядит странно, но он работает как надо.

Первые две строчки позволяют сохранить прозрачность для всего рисунка PNG, третья строчка включает прозрачность для шрифта, иначе надпись будет выводиться буквами на белом фоне.

Функции getX и getY позволяют определять координаты X и Y для центрирования надпись по рисунку по соотв. осям. Имя мы центрируем по обоим осям, а слово “поздравляем!” только по оси X, Y-координату подпираем эксперименталдьным путём где-то в нижней части торта.

В качестве аргументов они принимают размер шрифта, угол наклона и сам текст. Используют глобальные переменные рисунка ($im) и имени шрифта ($font).

В принципе всё. GD-функция imagettftext выводит надпись на рисунке по расчитанным координатам. Имя мы выводим под углом 16 градусов (снизу вверх).

Остальные GD-функции обычные, imagecreatefrompng – получаем рисунок из готово файла PNG, imagecolorallocate – готовим цвет в формате RGB, imagepng – выводим рисунок в браузер или файл (если мы укажем второй параметр).

Если мы выводим PNG-рисунок прямиком в браузер, мы должны установить HTTP-заголовок Content-Type: image/png, и конечно не должны смешивать вывод с текстом.

Всё, благодарю за ваше внимание, успехов и до новых встреч!