Reputation: 4829
I want to create a small function in PHP which takes in arguments like color, shape, transparency etc. and outputs a PNG image. I heard about PHP GD library but I want to know how can one create something as creative as soon.media.mit.edu
Upvotes: 31
Views: 110143
Reputation: 3998
You can use Imagick as well. It can be better in performance wise than GD library.
// 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/
Upvotes: 1
Reputation: 21
Here is a simple example to use:
<?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;
?>
Upvotes: 2
Reputation: 1396
Here is my function to create dynamic png image with dynamic text... And can be called as-
<img src="create_image.php?s=008080_F_1000_200&t=Sample%20Image%20Drawn%20By%20PHP" alt="GD Library Example Image" >
Here is create_image.php which provides the image requested...
<?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);
}
Upvotes: 3
Reputation: 56351
here is simple example:
<?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;
?>
Upvotes: 5
Reputation: 19636
This is a good example, you can do virtually everything using these functions. While possible, creating an image like the one you described would be pretty hard by I have done some weird stuff with gradients, loops and colors though.
If you wanted to make an image like that dynamically based on some parameters you can always create the images beforehand in photoshop and then overlay them based on what a user selects.
There is a lot of fun you can have.
Edit: Oh by the way, if your interested giving an invalid parameter shows some of the python code that is responsible for creating the image and causing the error. It would be a good place to get some idea of the code.
2nd Edit: This is just something I have done with this sort of technology. Bear in mind it was quite a while ago. It accepts a name based on the query string and basically does a few loops with a lot of random numbers.
Here is the source code, I apologize for any stupid code/quotes. This was written quite a while ago, when I was about 14 I believe (probably many flaws).
<?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);
?>
Upvotes: 25
Reputation: 2575
It's not completely what you're looking for, but I put together a script to insert dynamic color layers into transparent images. You set it up with one-color images "layers" and to run it, feed it a hex color code. The script re-colors your layers and merges them into one image to present. Here's the code; hopefully you can get some use out of it.
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 );
If you want more information about that code, I have a detailed explaination on my blog.
Upvotes: 3
Reputation: 38956
Not a direct answer to "doing it in PHP" but you can call some powerful command-line software from PHP. In particular ImageMagick will draw everything including the kitchen sink. It also has the advantage of being available to "back-end" scripts for "out-of-band" processing (ie, performing image processing after the request completes (faster user feedback) or late at night in batches when resources are tight during peak times.
Upvotes: 4
Reputation: 9660
Here's the code that I used before to generate an image with two names, which are accepted from query string parameters. I use a prepared background image and put the names on top of it.
<?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);
?>
To display the generated image on the page you do something like this:
<img src="myDynamicImage.php?n1=bebe&n2=jake" />
Upvotes: 9