Créer une image PNG dynamique

Je veux créer une petite fonction en PHP qui prend des arguments comme la couleur, la forme, la transparence, etc. et affiche une image PNG. J'ai entendu parler de la bibliothèque PHP GD mais je veux savoir comment peut-on créer quelque chose d'aussi créatif que soon.media.mit.edu

22
demandé sur user2864740 2009-05-23 13:25:00

8 réponses

C'est un bon exemple, vous pouvez faire pratiquement tout ce qu'à l'aide de ces fonctions. Bien que possible, Créer une image comme celle que vous avez décrite serait assez difficile car j'ai fait des choses étranges avec des dégradés, des boucles et des couleurs.

Si vous voulez créer une image comme celle-ci dynamiquement en fonction de certains paramètres, vous pouvez toujours créer les images à l'avance dans photoshop, puis les superposer en fonction de ce qu'un utilisateur sélectionne.

Il y a beaucoup de plaisir que vous peut avoir.

Edit: Oh au fait, si vous êtes intéressé donner un paramètre invalide montre une partie du code python qui est responsable de la création de l'image et de l'erreur. Ce serait un bon endroit pour avoir une idée du code.

2ème édition: c'est juste quelque chose que j'ai fait avec ce genre de technologie. Gardez à l'esprit que c'était il y a un certain temps. Il accepte un nom basé sur la chaîne de requête et fait quelques boucles avec beaucoup de nombres aléatoires.

Ici est le code source, je m'excuse pour tout code stupide / citations. Cela a été écrit il y a un certain temps, quand j'avais environ 14 ans, je crois (probablement beaucoup de défauts).

<?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);

?>
21
répondu Sam152 2014-04-26 15:47:00

Voici le code que j'ai utilisé auparavant pour générer une image avec deux Noms, qui sont acceptés à partir des paramètres de chaîne de requête. J'utilise une image d'arrière-plan préparée et mets les noms dessus.

<?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);
?>

Pour afficher l'image générée sur la page, vous faites quelque chose comme ceci:

<img src="myDynamicImage.php?n1=bebe&n2=jake" />
6
répondu niaher 2009-05-23 09:46:59

Pas une réponse directe à "le faire en PHP" mais vous pouvez appeler un puissant logiciel de ligne de commande à partir de PHP. En particulier ImageMagick dessinera tout, y compris l'évier de cuisine. Il a également l'avantage d'être disponible pour les scripts "back-end" pour le traitement "hors bande" (c'est-à-dire, effectuer un traitement d'image après la fin de la demande (commentaires des utilisateurs plus rapides) ou tard dans la nuit en lots lorsque les ressources sont limitées pendant les heures de pointe.

4
répondu SpliFF 2009-05-23 14:18:26

Voici un exemple simple:

<?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;   
?>
3
répondu T.Todua 2015-07-17 11:33:46

Ce n'est pas complètement ce que vous cherchez, mais j'ai mis en place un script pour insérer des calques de couleurs dynamiques dans des images transparentes. Vous le configurez avec des "calques" d'images monochromes et pour l'exécuter, donnez-lui un code couleur hexadécimal. Le script recolore vos calques et les fusionne en une seule image à présenter. Voici le code; j'espère que vous pouvez en tirer profit.

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 );

Si vous souhaitez plus d'informations sur ce code, j'ai une explication détaillée sur mon blog.

2
répondu Stephen Walcher 2012-02-04 04:29:44

Voici ma fonction pour créer une image PNG dynamique avec du texte dynamique... Et peut être appelé comme-

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

Voici create_image.php qui fournit l'image demandée...

<?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); 
}
1
répondu Vishal Kumar Sahu 2016-12-16 21:33:07

Voici un exemple simple à utiliser:

<?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;   
?>
0
répondu user7373642 2017-01-04 11:16:44

Vous pouvez utiliser Imagick ainsi. Il peut être meilleur en termes de performances que la bibliothèque 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();

Source: http://coderaweso.me/php-imagick-create-images-texts/

0
répondu TharinduLucky 2018-03-27 21:54:20