I am creating a Text-Image on given template in which all parameter are dynamic,Its working fine! and creating image like,my php script is,
<?php
// To fetch template info from database
$template_query = mysql_query("SELECT * FROM templates WHERE templateID = '".$fetch['templateID']."'");
$temp_data = mysql_fetch_assoc($template_query);
//create and save images
$temp = '../'. $temp_data['blank_templates'];
//check image type
$image_extension = strtolower(substr(strrchr($temp_data['blank_templates'], "."), 1));
$im = imagecreatefromjpeg($temp);
$black = hexdec($temp_data['font_color']);
// Replacing path by your own font path
$font = '..'.$temp_data['font_file_upload'];
// Break it up into pieces 125 characters long
$no_of_characters_line = $temp_data['no_of_characters_line'];
$lines = explode('|', wordwrap($message, $no_of_characters_line, '|'));
// Starting Y position and X position
$y = $temp_data['position_from_top'];
$x = $temp_data['position_from_left'];
$font_size = $temp_data['font_size'];
$rotation_angle = $temp_data['rotation'];
$line_height = $temp_data['line_height'];
foreach ($lines as $line)
{
imagettftext($im, $font_size,$rotation_angle, $x, $y, $black, $font, $line);
// Increment Y so the next line is below the previous line
$y += $line_height;
}
$id = uniqid();
$save = '../messagesimage/'.$id. '.'.$image_extension;
$path_save = substr($save, 3);
// Using imagepng() results in clearer text compared with imagejpeg()
imagejpeg($im,$save);
imagedestroy($im);
Which is creating image like..!
Now I want to add the ability to change font opacity and shadowing dynamically,Is it possible ? If yes then please help me to do this ..
Thanks in Advance
Wow, you've been waiting a while.
To give your text some transparency, you'll need to define your text color with an alpha channel.
$black = imageallocatecoloralpha(0,0,0,16);
To give your text some shadow
$shadow = imageallocatecoloralpha(0,0,0,64); // more transparent
imagettftext($im, $font_size,$rotation_angle, $x+1, $y+1, $shadow, $font, $line);
imagettftext($im, $font_size,$rotation_angle, $x, $y, $black, $font, $line);
Even later, but it seems the current answer is incorrect.
To define a color with transparency, you use the function imagecolorallocatealpha():
$black = imagecolorallocatealpha($image, 0, 0, 0, 50);
Shadows, like Michael pointed out, are quite simple(Just use the correct function name, and make sure you add the image object). However, if you want a more shadowy looking shadow, blur it a bit:
$shadow = imagecolorallocatealpha($im, 0, 0, 0, 50);
//Draw shadow text
imagettftext($im, $font_size, 0, $x, $y, $shadow, $fontn, $text);
//Blur
imagefilter($im, IMG_FILTER_GAUSSIAN_BLUR);
//Draw text
imagettftext($im, $font_size, 0, $x, $y, $white, $fontn, $text);
After applying the above shadow method to an image, it renders similar to this:
Related
I need to write in RTL mode to imagettftext, 'caus arabic language is in this way: and I don't mean to revert the letters, I mean a css-like RTL (direction:rtl), so aligned-flag on the right... how can I?
My easy code:
require('static/I18N/Arabic.php');
$Arabic = new I18N_Arabic('Glyphs');
$font="static/ArabicModern-Light.ttf";
$testo=$Arabic->utf8Glyphs($testo);
imagettftext($im, 26, 0, 560, 345, $textcolor, $font, "\"".$testo."\"");
Thanks!
After eventually finding and downloading Ar-PHP 4.0 I've updated this answer to use Arabic. Since I don't understand Arabic I've used the text 'العَرَبِيَّة' from the Arabic Wikipedia page.
Source:
<?php
require_once('./Arabic.php');
$iw = 300; // image width.
$ih = 150; // image height.
$size = 40;
$angle = 0;
$font = 'arial';
$text = 'العَرَبِيَّة';
$obj = new I18N_Arabic('Glyphs');
$text = $obj->utf8Glyphs($text);
$box = imagettfbbox($size, $angle, $font, $text);
$tw = abs($box[6] - $box[4]); // text width.
$th = abs($box[7] - $box[1]); // text height.
$im = imagecreatetruecolor($iw, $ih);
imagefill($im, 0, 0, 0x00c0c0c0); // set a grey background.
// left aligned.
imagettftext($im, $size, $angle, 0, $th, 0x00000000, $font, $text);
// centre aligned.
imagettftext($im, $size, $angle, ($iw / 2) - ($tw / 2), $th * 2, 0x00000000, $font, $text);
// right aligned.
imagettftext($im, $size, $angle, $iw - $tw, $th * 3, 0x00000000, $font, $text);
header('Content-Type: image/png');
imagepng($im);
imagedestroy($im);
Result (generated with PHP 7.1):
Reference image from Wikipedia:
Edit: Below is a comparison of the first five lines from the text you linked to in your comment, run through the code I wrote above (obviously with some minor changes to handle multiple lines):
Your original image (cropped) on the left, my generated image on the right.
Aside from not aligning correctly it's a match.
i want to add a white box around some text i add to an image via GD-Lib.
but i don't know how to do this best.
Here is my current code:
<?php
$textImg = imagecreatefromjpeg($tempImage);
$black = imagecolorallocate($textImg, 0, 0, 0);
$font = 'lib/verdana.ttf';
// Add the text
imagettftext($textImg, 20, 0, imagesx($textImg)*$textData['x']/100, imagesy($textImg)*$textData['y']/100, $black, $font, $textData['text']);
imagejpeg($textImg,$tempImage,$jpegQuality);
?>
I hope you can help me out.
You can use imagettfbbox() to get the coordinates of the bounding box by passing the same settings you use for the text itself (same text, font and size etc).
Once you have these coordinates you can use imagerectangle() to draw a border around the text, or you can use imagefilledrectangle() to draw a solid rectangle. Be sure to call it before you render the text with imagettftext()
A basic example is below but will need some tweaking as most of it is from memory and I suspect the $x and $y calculation could be done better as it probably doesn't work with varying canvas sizes as it is now. However, it demonstrates the principle.
// Set the content-type
header('Content-Type: image/png');
// Create the image
$im = imagecreatetruecolor(400, 30);
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 0, 0, 0);
imagefilledrectangle($im, 0, 0, 399, 29, $black);
// The text to draw
$text = 'Testing';
// Replace path by your own font path
$font = 'verdana.ttf';
// Add the text
$bbox = imagettfbbox(20, 0, $font, $text);
$x = $bbox[1] + (imagesx($im) / 2) - ($bbox[4]);
$y = $bbox[3] + (imagesy($im) / 2) - ($bbox[5]);
imagerectangle($im, 0, 0, $x, $y, $white);
imagettftext($im, 20, 0, 0, 20, $white, $font, $text);
// Using imagepng() results in clearer text compared with imagejpeg()
imagejpeg($im);
imagedestroy($im);
How can i generate multiple texts using the imagecreatetruecolor() method? I have the following code, but this displays either the first font or the second - not both:
<?php
// Set the content-type
header('Content-type: image/png');
// The text to draw
$text = 'Hello Farooqi';
$x = 0;
$y = 0;
$w = 50;
$h = 50;
$s = 13;
// Create the image
$im = imagecreatetruecolor($w , $s);
imagesavealpha($im, true);
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im,0,0,0);
$text_color = imagecolorallocate($im, 200,200, 91);
$blue = imagecolorallocate($im,0,0,180);
$alpha = imagecolorallocatealpha($im, 0, 0, 0, 127);
//imagefilledrectangle($im, 0, 0, 150, 25, $black);
imagefill($im, 0, 0, $alpha);
// Replace path by your own font path
$font = 'Calibri Bold.ttf';
// Add the text
$dimensions = imagettftext($im, $s, 0, $x, $y, $black, $font, $text);
$textWidth = ($dimensions[2]);
$imm = imagecreatetruecolor($w , $s);
imagesavealpha($imm, true);
$bluem = imagecolorallocate($imm,50,50,50);
$alpham = imagecolorallocatealpha($imm, 0, 0, 0, 127);
imagefill($imm, 0, 0, $alpham);
imagettftext($imm, $s, 0, $x+3, $y+3, $bluem, $font, $text);
// Using imagepng() results in clearer text compared with imagejpeg()
imagepng($im);
imagepng($imm);
imagedestroy($im);
imagedestroy($imm);
?>
Here above in these last 4 lines only one line appears, and that's the first one. How can I have both lines?
Please help. Thanks in advance.
The imagepng($im); will be called and outputted to your HTML code and as the header is set to an image it will display this image. No matter your imagepng($inm) that comes afterwards.
A better way would be to create two different PHP files. One that does your script and ends in imagepng($im); and another one that ends in imagepng($inm);
And then in your master PHP (header = text/html) file you just mention these 2 files in your image source:
<img src="functions/first_image.php" />
<img src="functions/second_image.php" />
I'm creating transparent text -> png images with php and so far so good. The only problem is that I want the ability to have the text word wrap due to a fixed width.. Or alternatively be able to insert breaklines into the text. Has anyone had any exp doing this? here is my code...
<?php
$font = 'arial.ttf';
$text = 'Cool Stuff! this is nice LALALALALA LALA HEEH EHEHE';
$fontSize = 20;
$bounds = imagettfbbox($fontSize, 0, $font, $text);
$width = abs($bounds[4]-$bounds[6]);
$height = abs($bounds[7]-$bounds[1]);
$im = imagecreatetruecolor($width, $height);
imagealphablending($im, false);
imagesavealpha($im, true);
$trans = imagecolorallocatealpha($im, 255, 255, 255, 127);
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
imagecolortransparent($im, $black);
imagefilledrectangle($im, 0, 0, $width, $height, $trans);
// Add the text
imagettftext($im, $fontSize, 0, 0, $fontSize-1, $grey, $font, $text);
imagepng($im, "image.png");
imagedestroy($im);
?>
Try this:
$text = 'Cool Stuff! this is nice LALALALALA LALA HEEH EHEHE';
$text = wordwrap($_POST['title'], 15, "\n");
Simply explode the text on spaces to get an array of words, then start building lines by looping through the words array, testing the addition of each new word via imagettfbbox to see if it creates a width that exceeds the maxwidth you set. If it does, start the next word on a fresh new line. I find it easier to simply create a new string with special line breaks characters added, and then just explode that string again to create an array of lines, each of which you will write onto the final image separately.
Something like this:
$words = explode(" ",$text);
$wnum = count($words);
$line = '';
$text='';
for($i=0; $i<$wnum; $i++){
$line .= $words[$i];
$dimensions = imagettfbbox($font_size, 0, $font_file, $line);
$lineWidth = $dimensions[2] - $dimensions[0];
if ($lineWidth > $maxwidth) {
$text.=($text != '' ? '|'.$words[$i].' ' : $words[$i].' ');
$line = $words[$i].' ';
}
else {
$text.=$words[$i].' ';
$line.=' ';
}
}
Where the pipe character is the line break character.
Of all the answers posted I liked Genius in trouble's the best but it just adds a linebreak every 15 characters rather than letting the text "flow" as it would in a modern word processor with variable line lengths depending on font choice & which characters are used (e.g. lowercase L takes less horizontal space than uppercase W--l vs. W).
I came up with a solution which I've released as open source at https://github.com/andrewgjohnson/linebreaks4imagettftext
To use you would simply change:
$font = 'arial.ttf';
$text = 'Cool Stuff! this is nice LALALALALA LALA HEEH EHEHE';
$fontSize = 20;
$bounds = imagettfbbox($fontSize, 0, $font, $text);
$width = abs($bounds[4]-$bounds[6]);
To:
$font = 'arial.ttf';
$text = 'Cool Stuff! this is nice LALALALALA LALA HEEH EHEHE';
$fontSize = 20;
$bounds = imagettfbbox($fontSize, 0, $font, $text);
$width = abs($bounds[4]-$bounds[6]);
// new code to add the "\n" line break characters to $text
require_once('linebreaks4imagettftext.php'); //https://raw.githubusercontent.com/andrewgjohnson/linebreaks4imagettftext/master/source/linebreaks4imagettftext.php
$text = \andrewgjohnson\linebreaks4imagettftext($fontSize, 0, $font, $text, $width);
Here is an example of the before & after with a longer piece of text:
If your string not have a any space you can try this :
$text = 'Cool Stuff!thisisniceLALALALALALALAHEEHEHEHE';
$text = wordwrap($_POST['title'], 15, "\n",true); //TRUE = Wrap
Currently I've got the following working just fine without any problems (yet).
header ("Content-type: image/png");
$string = $_REQUEST['text'];
$font = 15;
$width = 300;
$height = 350;
$image = imagecreate($width, $height);
$back = ImageColorAllocate($image, 255, 255, 255);
$border = ImageColorAllocate($image, 0, 0, 0);
ImageFilledRectangle($image, 0, 0, $width, $height, $border);
ImageFilledRectangle($image, 1, 1, $width-2, $height-2, $back);
$text_color = imagecolorallocate($image, 255, 0, 0);
ImageStringWrap($image, $font, 3, 2, $string, $text_color, $width-2 );
imagepng($image);
function ImageStringWrap($image, $font, $x, $y, $text, $color, $maxwidth) {
$fontwidth = ImageFontWidth($font);
$fontheight = ImageFontHeight($font);
if ($maxwidth != NULL) {
$maxcharsperline = floor($maxwidth / $fontwidth);
$text = wordwrap($text, $maxcharsperline, "\n", false);
}
while (list($numl, $line) = each($lines)) {
ImageString($image, $font, $x, $y, $line, $color);
$y += $fontheight;
}
}
While the above works great, one thing I've been failing to work is be able to get line breaks like would come out akin to nl2br().
The text that this is pulling from in $_REQUEST['text'] is from the database, which was originally inserted from a textarea and passed to this script via URL. Naturally when people type in a textarea, there are line breaks that come from that. While printing it to the browser via text is easy, I can't seem to get the same result within an image.
I haven't spend a long time working with the GD library, but after searching around I really can't find anything about how to do this. Is it just not possible?