Генерация PNG-графики на PHP через GD
Создание PNG с помощью GD в PHP
Наиболее эффективное решение для создания PNG-изображений в PHP - использование функции imagepng() в сочетании с imagecreatetruecolor(). Этот подход позволяет создавать изображения с высоким качеством и поддержкой альфа-канала.
$im = imagecreatetruecolor(200, 200);
$bg = imagecolorallocate($im, 255, 255, 255);
imagefill($im, 0, 0, $bg);
$red = imagecolorallocate($im, 255, 0, 0);
imageline($im, 0, 0, 200, 200, $red);
imagepng($im, 'output.png');
imagedestroy($im);
После выполнения скрипта в текущей директории появится файл output.png.
Проблема: изображение не создаётся. Необходимо проверить, подключено ли расширение GD (функция extension_loaded('gd')). Также возможны ошибки прав на запись в папку.
Как создать PNG с прозрачным фоном?
Для создания изображения с прозрачным фоном следует установить цвет фона как прозрачный с помощью imagecolorallocatealpha() и вызвать imagesavealpha().
$im = imagecreatetruecolor(100, 100);
imagesavealpha($im, true);
$transparent = imagecolorallocatealpha($im, 0, 0, 0, 127);
imagefill($im, 0, 0, $transparent);
$blue = imagecolorallocate($im, 0, 0, 255);
imagefilledellipse($im, 50, 50, 80, 80, $blue);
imagepng($im, 'transparent.png');
imagedestroy($im);
Типичная ошибка: забыли вызвать imagesavealpha() - прозрачность не сохраняется, фон становится чёрным.
Как вывести PNG сразу в браузер без сохранения в файл?
Применяется функция imagepng() без второго параметра, перед этим следует отправить заголовок Content-Type: image/png.
header('Content-Type: image/png');
$im = imagecreatetruecolor(50, 50);
$c = imagecolorallocate($im, 0, 200, 0);
imagefill($im, 0, 0, $c);
imagepng($im);
imagedestroy($im);
Проблема: если перед вызовом imagepng() был выведен какой-либо текст или HTML, изображение не отобразится. Следует убедиться, что в скрипте нет пробелов до <?php и после ?>.
Как наложить текст на PNG?
Используется imagestring() или imagettftext() для более качественного текста с TrueType шрифтами.
$im = imagecreatetruecolor(300, 100);
$bg = imagecolorallocate($im, 220, 220, 220);
imagefill($im, 0, 0, $bg);
$black = imagecolorallocate($im, 0, 0, 0);
$font = '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf';
imagettftext($im, 20, 0, 20, 60, $black, $font, 'Пример текста');
imagepng($im, 'text.png');
imagedestroy($im);
Частая ошибка: путь к шрифту неверный или шрифт не установлен. Рекомендуется использовать realpath() для проверки.
Как изменить размер существующего PNG и сохранить прозрачность?
Загрузка исходного изображения производится с помощью imagecreatefrompng(), затем создаётся новое изображение нужного размера и используется imagecopyresampled().
$src = imagecreatefrompng('source.png');
$w = imagesx($src);
$h = imagesy($src);
$new_w = 200;
$new_h = 150;
$dst = imagecreatetruecolor($new_w, $new_h);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $new_w, $new_h, $w, $h);
imagepng($dst, 'resized.png');
imagedestroy($src);
imagedestroy($dst);
Проблема: при изменении размера теряется прозрачность. Решение: перед imagecopyresampled установить флаг imagesavealpha($dst, true) и заполнить фон прозрачным цветом.
Расширенные примеры создания PNG
// Пример 1: Создание простого столбчатого графика
$width = 400;
$height = 300;
$im = imagecreatetruecolor($width, $height);
$white = imagecolorallocate($im, 255,255,255);
imagefill($im,0,0,$white);
$black = imagecolorallocate($im,0,0,0);
$red = imagecolorallocate($im,255,0,0);
$blue = imagecolorallocate($im,0,0,255);
// оси
imageline($im, 50, 250, 350, 250, $black); // X
imageline($im, 50, 30, 50, 250, $black); // Y
// столбцы
$data = [40, 80, 120, 160, 200];
foreach($data as $i => $val) {
$x1 = 60 + $i*60;
$x2 = $x1 + 40;
$y1 = 250 - $val;
$y2 = 250;
imagefilledrectangle($im, $x1, $y1, $x2, $y2, ($i%2==0)?$red:$blue);
}
imagepng($im, 'chart.png');
imagedestroy($im);
Результат:
Изображение chart.png с тремя синими и двумя красными столбцами.
// Пример 2: Наложение водяного знака
$main = imagecreatefrompng('photo.png');
$watermark = imagecreatefrompng('logo.png');
$m_w = imagesx($main);
$m_h = imagesy($main);
$wm_w = imagesx($watermark);
$wm_h = imagesy($watermark);
$dst_x = $m_w - $wm_w - 10;
$dst_y = $m_h - $wm_h - 10;
imagecopy($main, $watermark, $dst_x, $dst_y, 0, 0, $wm_w, $wm_h);
imagepng($main, 'watermarked.png');
imagedestroy($main);
imagedestroy($watermark);
Результат:
Изображение watermarked.png с логотипом в правом нижнем углу.
// Пример 3: Применение фильтров к PNG
$im = imagecreatefrompng('input.png');
imagefilter($im, IMG_FILTER_GRAYSCALE);
imagefilter($im, IMG_FILTER_CONTRAST, -50);
imagefilter($im, IMG_FILTER_BRIGHTNESS, 30);
imagepng($im, 'filtered.png');
imagedestroy($im);
Результат:
Изображение filtered.png с увеличенным контрастом и яркостью, обесцвеченное.
// Пример 4: Создание круглой аватарки с прозрачностью (упрощённый вариант)
$size = 200;
$avatar = imagecreatefrompng('avatar_source.png');
$av_w = imagesx($avatar);
$av_h = imagesy($avatar);
$im = imagecreatetruecolor($size, $size);
imagesavealpha($im, true);
$transparent = imagecolorallocatealpha($im, 0,0,0,127);
imagefill($im, 0,0,$transparent);
$src = imagecreatetruecolor($size, $size);
imagecopyresampled($src, $avatar, 0,0,0,0,$size,$size,$av_w,$av_h);
$mask = imagecreatetruecolor($size, $size);
$black = imagecolorallocate($mask,0,0,0);
$white = imagecolorallocate($mask,255,255,255);
imagefill($mask,0,0,$black);
imagefilledellipse($mask, $size/2, $size/2, $size, $size, $white);
imagecopy($im, $src, 0,0,0,0,$size,$size);
imagecopy($im, $mask, 0,0,0,0,$size,$size, IMG_COPY_MASK);
imagepng($im, 'avatar_circle.png');
imagedestroy($avatar);
imagedestroy($src);
imagedestroy($mask);
imagedestroy($im);
Результат:
Круглая аватарка с прозрачным фоном (белый круг, внутри изображение).