Создать динамическое изображение PNG - PullRequest
24 голосов
/ 23 мая 2009

Я хочу создать небольшую функцию в PHP, которая принимает аргументы, такие как цвет, форма, прозрачность и т. Д., И выводит изображение PNG. Я слышал о библиотеке PHP GD, но я хочу знать, как можно создать что-то такое творческое, как soon.media.mit.edu

Ответы [ 8 ]

21 голосов
/ 23 мая 2009

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

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

Вы можете получить массу удовольствия.

Редактировать: Да, кстати, если ваш заинтересованный , задающий недопустимый параметр, показывает часть кода Python , который отвечает за создание изображения и вызывает ошибку. Было бы неплохо получить представление о коде.

2-е редактирование: это то, что я сделал с такой технологией. Имейте в виду, это было довольно давно. Он принимает имя на основе строки запроса и в основном выполняет несколько циклов с большим количеством случайных чисел.

Вот исходный код, я прошу прощения за любой глупый код / ​​цитаты. Это было написано довольно давно, когда мне было лет 14, я думаю (вероятно, много недостатков).

<?php
header("Content-type:image/jpeg");
$array=array("I am a monument to all your sins", "Currently making pizza","Best before 12/7/09", "Farming Onions");
        function imagettftext_cr(&$im, $size, $angle, $x, $y, $color, $fontfile, $text)
        {
            // retrieve boundingbox
            $bbox = imagettfbbox($size, $angle, $fontfile, $text);
            // calculate deviation
            $dx = ($bbox[2]-$bbox[0])/2.0 - ($bbox[2]-$bbox[4])/2.0;         // deviation left-right
            $dy = ($bbox[3]-$bbox[1])/2.0 + ($bbox[7]-$bbox[1])/2.0;        // deviation top-bottom
            // new pivotpoint
            $px = $x-$dx;
            $py = $y-$dy;
            return imagettftext($im, $size, $angle, $px, $y, $color, $fontfile, $text);
        }
$image = imagecreate(500,90);
$black = imagecolorallocate($image,0,0,0);
$grey_shade = imagecolorallocate($image,40,40,40);
$white = imagecolorallocate($image,255,255,255);


$text = $array[rand(0,sizeof($array)-1)];

// Local font files, relative to script
$otherFont = 'army1.ttf';
$font = 'army.ttf';

if($_GET['name'] == ""){ $name = "Sam152";}else{$name= $_GET['name'];}
$name = substr($name, 0, 25);    


//BG text for Name
while($i<10){
imagettftext_cr($image,rand(2,40),rand(0,50),rand(10,500),rand(0,200),$grey_shade,$font,$name);
$i++;
}
//BG text for saying
while($i<10){
imagettftext_cr($image,rand(0,40),rand(90,180),rand(100,500),rand(200,500),$grey_shade,$otherFont,$text);
$i++;
}

// Main Text
imagettftext_cr($image,35,0,250,46,$white,$font,$name);
imagettftext_cr($image,10,0,250,76,$white,$otherFont,$text);
imagejpeg($image);

?>
6 голосов
/ 23 мая 2009

Вот код, который я использовал ранее для генерации изображения с двумя именами, которые принимаются из параметров строки запроса. Я использую подготовленное фоновое изображение и помещаю поверх него имена.

<?php
// Print two names on the picture, which accepted by query string parameters.

$n1 = $_GET['n1'];
$n2 = $_GET['n2'];

Header ("Content-type: image/jpeg");
$image = imageCreateFromJPEG("images/someimage.jpg");
$color = ImageColorAllocate($image, 255, 255, 255);

// Calculate horizontal alignment for the names.
$BoundingBox1 = imagettfbbox(13, 0, 'ITCKRIST.TTF', $n1);
$boyX = ceil((125 - $BoundingBox1[2]) / 2); // lower left X coordinate for text
$BoundingBox2 = imagettfbbox(13, 0, 'ITCKRIST.TTF', $n2);
$girlX = ceil((107 - $BoundingBox2[2]) / 2); // lower left X coordinate for text

// Write names.
imagettftext($image, 13, 0, $boyX+25, 92, $color, 'ITCKRIST.TTF', $n1);
imagettftext($image, 13, 0, $girlX+310, 92, $color, 'ITCKRIST.TTF', $n2);

// Return output.
ImageJPEG($image, NULL, 93);
ImageDestroy($image);
?>

Для отображения сгенерированного изображения на странице вы делаете что-то вроде этого:

<img src="myDynamicImage.php?n1=bebe&n2=jake" />
4 голосов
/ 23 мая 2009

Не прямой ответ на «делать это на PHP», но вы можете вызвать мощное программное обеспечение командной строки из PHP. В частности ImageMagick будет рисовать все, включая раковину. Он также имеет то преимущество, что он доступен для «внутренних» сценариев для «внеполосной» обработки (т. Е. Для выполнения обработки изображений после завершения запроса (более быстрая обратная связь с пользователем) или поздним вечером в пакетном режиме, когда ресурсы ограничены во время часы пик.

3 голосов
/ 17 июля 2015

вот простой пример:

<?php
    $your_text = "Helloooo Worldddd";

    $IMG = imagecreate( 250, 80 );
    $background = imagecolorallocate($IMG, 0,0,255);
    $text_color = imagecolorallocate($IMG, 255,255,0); 
    $line_color = imagecolorallocate($IMG, 128,255,0);
    imagestring( $IMG, 10, 1, 25, $your_text,  $text_color );
    imagesetthickness ( $IMG, 5 );
    imageline( $IMG, 30, 45, 165, 45, $line_color );
    header( "Content-type: image/png" );
    imagepng($IMG);
    imagecolordeallocate($IMG, $line_color );
    imagecolordeallocate($IMG, $text_color );
    imagecolordeallocate($IMG, $background );
    imagedestroy($IMG); 
    exit;   
?>
2 голосов
/ 04 февраля 2012

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

function hexLighter($hex, $factor = 30) {
    $new_hex = '';

    $base['R'] = hexdec($hex{0}.$hex{1});
    $base['G'] = hexdec($hex{2}.$hex{3});
    $base['B'] = hexdec($hex{4}.$hex{5});

    foreach ($base as $k => $v) {
        $amount = 255 - $v;
        $amount = $amount / 100;
        $amount = round($amount * $factor);
        $new_decimal = $v + $amount;

        $new_hex_component = dechex($new_decimal);

        $new_hex .= sprintf('%02.2s', $new_hex_component);
    }

    return $new_hex;
}

// Sanitize/Validate provided color variable
if (!isset($_GET['color']) || strlen($_GET['color']) != 6) {
    header($_SERVER['SERVER_PROTOCOL'] . ' 400 Bad Request', true, 400);

    exit(0);
}

if (file_exists( "cache/{$_GET['color']}.png" )) {
    header( 'Content-Type: image/png' );
    readfile( "cache/{$_GET['color']}.png" );

    exit(0);
}

// Desired final size of image
$n_width = 50;
$n_height = 50;

// Actual size of source images
$width = 125;
$height = 125;

$image =    imagecreatetruecolor($width, $height);
            imagesavealpha($image, true);
            imagealphablending($image, false);

$n_image =  imagecreatetruecolor($n_width, $n_height);
            imagesavealpha($n_image, true);
            imagealphablending($n_image, false);

$black = imagecolorallocate($image, 0, 0, 0);
$transparent = imagecolorallocatealpha($image, 255, 255, 255, 127);

imagefilledrectangle($image, 0, 0, $width, $height, $transparent);

$layers = array();
$layers_processed = array();

$layers[] = array( 'src' => 'layer01.gif', 'level' => 0 );  // Border
$layers[] = array( 'src' => 'layer02.gif', 'level' => 35 );     // Background
$layers[] = array( 'src' => 'layer03.gif', 'level' => 100 );    // White Quotes

foreach ($layers as $idx => $layer) {
    $img = imagecreatefromgif( $layer['src'] );
    $processed = imagecreatetruecolor($width, $height);

    imagesavealpha($processed, true);
    imagealphablending($processed, false);

    imagefilledrectangle($processed, 0, 0, $width, $height, $transparent);

    $color = hexLighter( $_GET['color'], $layer['level'] );
    $color = imagecolorallocate($image,
        hexdec( $color{0} . $color{1} ),
        hexdec( $color{2} . $color{3} ),
        hexdec( $color{4} . $color{5} )
    );

    for ($x = 0; $x < $width; $x++)
        for ($y = 0; $y < $height; $y++)
            if ($black === imagecolorat($img, $x, $y))
                imagesetpixel($processed, $x, $y, $color);

    imagecolortransparent($processed, $transparent);
    imagealphablending($processed, true);

    array_push($layers_processed, $processed);

    imagedestroy( $img );
}

foreach ($layers_processed as $processed) {
    imagecopymerge($image, $processed, 0, 0, 0, 0, $width, $height, 100);

    imagedestroy( $processed );
}

imagealphablending($image, true);

imagecopyresampled($n_image, $image, 0, 0, 0, 0, $n_width, $n_height, $width, $height);

imagealphablending($n_image, true);

header( 'Content-Type: image/png' );
imagepng( $n_image, "cache/{$_GET['color']}.png" );
imagepng( $n_image );

// Free up memory
imagedestroy( $n_image );
imagedestroy( $image );

Если вам нужна дополнительная информация об этом коде, у меня есть подробное объяснение в моем блоге .

1 голос
/ 17 декабря 2016

Вот моя функция для создания динамического PNG-изображения с динамическим текстом ... И можно назвать как-

<img src="create_image.php?s=008080_F_1000_200&t=Sample%20Image%20Drawn%20By%20PHP" alt="GD Library Example Image" >

Вот create_image.php, который предоставляет запрошенное изображение ...

<?php
$setting = isset($_GET['s']) ? $_GET['s'] : "FFF_111_100_100";
$setting = explode("_",$setting );
$img = array();

switch ($n = count($setting)) {
    case $n > 4 :
    case 3:
        $setting[3] = $setting[2];
    case 4:
        $img['width'] = (int) $setting[2];
        $img['height'] = (int) $setting[3];
    case 2:
        $img['color'] = $setting[1];
        $img['background'] = $setting[0];
        break;
    default:
        list($img['background'],$img['color'],$img['width'],$img['height']) = array('F','0',100,100);
        break;
}

$background = explode(",",hex2rgb($img['background']));
$color = explode(",",hex2rgb($img['color']));
$width = empty($img['width']) ? 100 : $img['width'];
$height = empty($img['height']) ? 100 : $img['height'];
$string = (string) isset($_GET['t']) ? $_GET['t'] : $width ."x". $height;

header("Content-Type: image/png");
$image = @imagecreate($width, $height)
    or die("Cannot Initialize new GD image stream");

$background_color = imagecolorallocate($image, $background[0], $background[1], $background[2]);
$text_color = imagecolorallocate($image, $color[0], $color[1], $color[2]);

imagestring($image, 5, 5, 5, $string, $text_color);
imagepng($image);
imagedestroy($image);

function hex2rgb($hex) {
    // Copied
   $hex = str_replace("#", "", $hex);

   switch (strlen($hex)) {
    case 1:
        $hex = $hex.$hex;
    case 2:
          $r = hexdec($hex);
          $g = hexdec($hex);
          $b = hexdec($hex);
        break;

    case 3:
          $r = hexdec(substr($hex,0,1).substr($hex,0,1));
          $g = hexdec(substr($hex,1,1).substr($hex,1,1));
          $b = hexdec(substr($hex,2,1).substr($hex,2,1));
        break;

    default:
          $r = hexdec(substr($hex,0,2));
          $g = hexdec(substr($hex,2,2));
          $b = hexdec(substr($hex,4,2));
        break;
   }

   $rgb = array($r, $g, $b);
   return implode(",", $rgb); 
}
0 голосов
/ 28 марта 2018

Вы также можете использовать Imagick . Это может быть лучше по производительности, чем библиотека GD.

// Create new object
$im = new Imagick();

// Create new image with properties
$im->newImage( 1000, 1000, '#FF0000' );

// Write texts on it
$text_draw = new ImagickDraw();
$text_draw->setFont( 'path/to/font' );
$text_draw->setFontSize( 150 );
$text_draw->setStrokeColor('#fff');
$text_draw->setFillColor('#C0C0C0');

$im->setImageFormat( "png" );
$im->writeImage( 'path/to/save/filename.png' );
$img->destroy();

Источник: http://coderaweso.me/php-imagick-create-images-texts/

0 голосов
/ 04 января 2017

Вот простой пример использования:

<?php
    $your_text = "Helloooo Worldddd";

    $IMG = imagecreate( 250, 80 );
    $background = imagecolorallocate($IMG, 0,0,255);
    $text_color = imagecolorallocate($IMG, 255,255,0); 
    $line_color = imagecolorallocate($IMG, 128,255,0);
    imagestring( $IMG, 10, 1, 25, $your_text,  $text_color );
    imagesetthickness ( $IMG, 5 );
    imageline( $IMG, 30, 45, 165, 45, $line_color );
    header( "Content-type: image/png" );
    imagepng($IMG);
    imagecolordeallocate($IMG, $line_color );
    imagecolordeallocate($IMG, $text_color );
    imagecolordeallocate($IMG, $background );
    imagedestroy($IMG); 
    exit;   
?>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...