Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Image Functions : imagettftext

imagettftext

Write text to the image using TrueType fonts (PHP 4, PHP 5)
array imagettftext ( resource image, float size, float angle, int x, int y, int color, string fontfile, string text )

Example 1026. imagettftext() example

This example script will produce a white PNG 400x30 pixels, with the words "Testing..." in black (with grey shadow), in the font Arial.

<?php
// 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);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
imagefilledrectangle($im, 0, 0, 399, 29, $white);

// The text to draw
$text = 'Testing...';
// Replace path by your own font path
$font = 'arial.ttf';

// Add some shadow to the text
imagettftext($im, 20, 0, 11, 21, $grey, $font, $text);

// Add the text
imagettftext($im, 20, 0, 10, 20, $black, $font, $text);

// Using imagepng() results in clearer text compared with imagejpeg()
imagepng($im);
imagedestroy($im);
?>

The above example will output something similar to:


Related Examples ( Source code ) » imagettftext









Code Examples / Notes » imagettftext

php

Users may note a problem trying to use this function to display the Euro symbol.
The reason is that it is a late addition. Although the operating systems generally recognise code 0x80 (128 decimal) as Euro, this is not where it necessarily appears in the font. Some have it there, but many just have it in the extended character set at position 0x20AC (8364 decimal).
I have yet to find a font with it only at 0x80, so here is the fix:
<?php
$image=imagecreate(135,24);
$bg=imagecolorallocate($image,0,0,0);
$fg=imagecolorallocate($image,0,255,0);
$text = 'coffee - €3.50';
$friendly = eurofix($text);
imagettftext($image,16,0,5,20,$fg,"Papyrus.ttf",$friendly);
imagegif ($image);
imagedestroy ($image);
function eurofix($str) {
$euro=utf8_encode('&#8364;');
$str = preg_replace('/\x80/',$euro,$str);
return ($str);
}
?>
You should note, however, this won't help with fonts older than about 1999. It can only make sure the Euro is displayed where available.


imacs

To make it support chinese and japanese fonts, have a look here.
* http://www.freshmeat.net/appindex/1999/12/27/946305846.html


craig

This one caught me out a little bit as confusing, so in an attempt to help others..
"Using the negative of a color index has the effect of turning off antialiasing."
Simply put:
<?php
$textColour = ImageColorAllocate($image, 255, 255, 255);
ImageTTFText($image, 8, 0, 0, 0, -$textColour, $font, $text);
?>
Note the - (minus) before the $textColor in ImageTTFText, this creates the negative colour index, and switches off AA on text.


ugo dot quaisse

This is a script that aim at center the (multi) lines :
<?php
header("Content-type: image/png");
//1line per column
$text=array(0=>"line 1",1=>"line 2");
$largeur=500;
$line_height=30;
$hauteur=sizeof($text)*$line_height;
// Create the image
$im = imagecreatetruecolor($largeur, $hauteur);
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 225, 225, 225);
$blue = imagecolorallocate($im, 0, 62, 126);
imagefilledrectangle($im, 0, 0, $largeur, $hauteur, $white);
// Replace path by your own font path
$font = 'font.ttf';
for($i=0;$i<=sizeof($text);$i++) {
//Center the text
$size = imagettfbbox(20, 0, $font, $text[$i]);
$long_text = $size[2]+$size[0];
$posx=($largeur-$long_text)/2;
// Add the text
imagettftext($im, 20, 0, $posx, $line_height+$line_height*$i, $blue, $font, $text[$i]);
}
imagepng($im);
imagedestroy($im);
?>


a4w

This function will make your text bold:
<?php
function drawboldtext($image, $size, $angle, $x_cord, $y_cord, $r, $g, $b, $fontfile, $text)
{
  $color = ImageColorAllocate($image, $r, $g, $b);
  $_x = array(1, 0, 1, 0, -1, -1, 1, 0, -1);
  $_y = array(0, -1, -1, 0, 0, -1, 1, 1, 1);
  for($n=0;$n<=8;$n++)
  {
     ImageTTFText($image, $size, $angle, $x_cord+$_x[$n], $y_cord+$_y[$n], $color, $fontfile, $text);
  }
}
?>


ken

Strangely this function seems to work with adobe post script files (tried .pfb) not sure why this isn't documented or why there is a separate set of functions for dealing with postscript.

lassial

Roy van Arem suggested a neat code for listing TTFs on a machine. However, it has some problems (such as lower and upper case distinction of file extension and defective fonts) that I have corrected in the following script, which can be implemented as a single PHP script (name as you like):
<?php //make sure there are no blank lines above
       
$ffolder="/usr/local/bin/fonts"; //The directory where your fonts reside
if (empty($_GET['f']))
{
$folder=dir($ffolder); //open directory
echo "<HTML><BODY>\n";
   
while($font=$folder->read())
 if(stristr($font,'.ttf')) //only ttf fonts
       $fonts[]=$font;
       
$folder->close();
if (!empty($fonts))
       {
       echo "<table><tr><th colspan='2'>Fonts available in $ffolder</th></tr>"
       ."\n<tr><th>Name</th><th>Appereance</th>";
       sort($fonts);
       foreach ($fonts as $font)
               echo "<tr><td>$font</td><td> <IMG src='".$_SERVER['SCRIPT_NAME']
                       ."?f=$font'></td></tr>\n";
       }
else echo "No fonts found from $ffolder";
echo "\n</HTML></BODY>";
}
else
{
$im=@imagecreatetruecolor(200,30)
       or die("Cannot Initialize new GD image stream");
$black=imagecolorallocate($im,0,0,0);
$white=imagecolorallocate($im,255,255,255);
imagefill($im,0,0,$white);
imagettftext($im,14,0,5,25,$black, "$ffolder/".$_GET['f'] , $_GET['f']);
header("Content-type: image/png");
header('Content-Length: ' . strlen($im));
imagepng($im);
imagedestroy($im);
}
?>


borgso

Right align out of "webmaster at higher-designs dot com" code
<?php
$color = imagecolorallocate($im, 0, 0, 0);
$font = 'visitor.ttf';
$fontsize = "12";
$fontangle = "0";
$imagewidth = imagesx($im);
$imageheight = imagesy($im);
$text = "My right align text";
$box = @imageTTFBbox($fontsize,$fontangle,$font,$text);
$textwidth = abs($box[4] - $box[0]);
$textheight = abs($box[5] - $box[1]);
$xcord = $imagewidth - ($textwidth)-2; // 2 = some space from right side.
$ycord = ($imageheight/2)+($textheight/2);
ImageTTFText ($im, $fontsize, $fontangle, $xcord, $ycord, $black, $font, $text);
?>


erik

Remember!!!
When uploading a font to your website you have to set the transfer mode to binary. It took me some time to find out :P. Tried to download the font from my website and it was spoiled.
In your script, the path to your font, use realpath("arial.ttf") so there is no confusion about that.


tom pike

Ref: Craig at frostycoolslug dot com
"Using the negative of a color index has the effect of turning off antialiasing."
This is true, but only if the image has been created with imagecreate() (as opposed to imagecreatetruecolor())


jwe

Quick tip for anyone who is receiving text like in the example in this page (ie: through $_GET['text'] or something similar) and needs to format the text into multiple lines.  The trick is finding the spaces...
<?php
$text = $_GET['text'];
// for a maximum of 38 characters on a line...
while(strlen($text) > 38) {
  $startPoint = 37;
  // find a space to break the line on
  while(substr($text, $startPoint, 1) != " ") {
$startPoint--;
  }
  $line[] = trim(substr($text, 0, $startPoint));
  $text = substr($text, $startPoint);
}
$line[] = trim($text);
?>
The result is an array called $line that contains all the lines of text you need to output in order.
The only tasks left are to determine the correct height of the image based on the font size you want to use.  Don't forget to leave some padding space for punctuation and descenders between lines (commas, g, q, p, y, etc).
imagettftext is unbelievably useful when you need to create header images using non-standard fonts.  Amazing.  Huge thanks to the devs.
--Julian


admin

On my conf: php5.1.2+apache 1.33
iconv() function works very well with all cyrillic encodings, so you needn't to write your function like win2uni


alexey

Notice that the path to the TrueType font has to be included in open_basedir list if open_basedir restriction is activated in php.ini.

sohel taslim

Left Right Center align/justify of text in image. It is easy and simple to do in PHP.
Create an image from text and align them as you want. After that save or display image.
<?php
/**
* Function for converting Text to Image.
* Kip CENTURY.TTF file in same folder.
*
* @author Taslim Mazumder Sohel
* @deprecated 1.0 - 2007/08/03
*
*/
//Example call.
   $str = "New life in programming.\nNext Line of Image.\nLine Number 3\n" .
"This is line numbet 4\nLine number 5\nYou can write as you want.";
header("Content-type: image/gif");
   imagegif(imagettfJustifytext($str,"CENTURY.TTF",2));
   //End of example.
   
   
   /**
    * @name   : makeImageF
    *
    * Function for create image from text with selected font. Justify text in image (0-Left, 1-Right, 2-Center).
    *
    * @param String $text     : String to convert into the Image.
    * @param String $font     : Font name of the text. Kip font file in same folder.
    * @param int    $W        : Width of the Image.
    * @param int    $H        : Hight of the Image.
    * @param int    $X        : x-coordinate of the text into the image.
    * @param int    $Y        : y-coordinate of the text into the image.
    * @param int    $fsize    : Font size of text.
    * @param array  $color   : RGB color array for text color.
    * @param array  $bgcolor  : RGB color array for background.
    *
    */
   function imagettfJustifytext($text, $font="CENTURY.TTF", $Justify=2, $W=0, $H=0, $X=0, $Y=0, $fsize=12, $color=array(0x0,0x0,0x0), $bgcolor=array(0xFF,0xFF,0xFF)){
   
    $angle = 0;
    $L_R_C = $Justify;
    $_bx = imageTTFBbox($fsize,0,$font,$text);
$W = ($W==0)?abs($_bx[2]-$_bx[0]):$W; //If Height not initialized by programmer then it will detect and assign perfect height.
$H = ($H==0)?abs($_bx[5]-$_bx[3]):$H; //If Width not initialized by programmer then it will detect and assign perfect width.
    $im = @imagecreate($W, $H)
   or die("Cannot Initialize new GD image stream");
   
   
$background_color = imagecolorallocate($im, $bgcolor[0], $bgcolor[1], $bgcolor[2]); //RGB color background.
$text_color = imagecolorallocate($im, $color[0], $color[1], $color[2]); //RGB color text.

if($L_R_C == 0){ //Justify Left

imagettftext($im, $fsize, $angle, $X, $fsize, $text_color, $font, $text);

}elseif($L_R_C == 1){ //Justify Right
$s = split("[\n]+", $text);
    $__H=0;
   
    foreach($s as $key=>$val){
   
    $_b = imageTTFBbox($fsize,0,$font,$val);
    $_W = abs($_b[2]-$_b[0]);
    //Defining the X coordinate.
    $_X = $W-$_W;
//Defining the Y coordinate.
$_H = abs($_b[5]-$_b[3]);  
$__H += $_H;  
    imagettftext($im, $fsize, $angle, $_X, $__H, $text_color, $font, $val);
    $__H += 6;
   
    }
   
}
elseif($L_R_C == 2){ //Justify Center
   
    $s = split("[\n]+", $text);
    $__H=0;
   
    foreach($s as $key=>$val){
   
    $_b = imageTTFBbox($fsize,0,$font,$val);
    $_W = abs($_b[2]-$_b[0]);
    //Defining the X coordinate.
    $_X = abs($W/2)-abs($_W/2);
//Defining the Y coordinate.
$_H = abs($_b[5]-$_b[3]);  
$__H += $_H;  
    imagettftext($im, $fsize, $angle, $_X, $__H, $text_color, $font, $val);
    $__H += 6;
   
    }
   
    }

return $im;

   }
   
 
?>


mitch

If you're having issues with fonts not working... (Could not find/open font) check your permissions on the folder/font files and make sure they're 775, especially if you've just pulled them from a windows box. Hope this helps!

roy van arem

If you want to display a list of fonts in a directory and see what they look like, you could do something like this:
<HTML><BODY>
<?php
$folder=dir("fonts/"); //The directory where your fonts reside
while($font=$folder->read())
 {
 if(stristr($font,'.ttf'))echo '<IMG SRC="img.php?'.substr($font,0,strpos($font,'.')).'">'; //only ttf fonts
 }
$folder->close();
?>
</BODY></HTML>
The file for 'img.php' should be something like this:
<?php
$font=$_SERVER["QUERY_STRING"];
header("Content-type: image/png");
$im=@imagecreatetruecolor(200,30)or die("Cannot Initialize new GD image stream");
$black=imagecolorallocate($im,0,0,0);
$white=imagecolorallocate($im,255,255,255);
imagefill($im,0,0,$white);
imagettftext($im,18,0,5,25,$black,"fonts/".$font,$font);
imagepng($im);
imagedestroy($im);
?>
Something similar I implemented at http://font.beginstart.com


limalopex.eisfux.de

If you have problems displaying german umlauts or other chars with an ascii value > 127, try to convert the text-parameter first. The following function converts character-values > 127 (both: UTF-8 + ANSI) to HTML's numeric coded entities:
<?php
define('EMPTY_STRING', '');
function foxy_utf8_to_nce(
 $utf = EMPTY_STRING
) {
 if($utf == EMPTY_STRING) return($utf);
 $max_count = 5; // flag-bits in $max_mark ( 1111 1000 == 5 times 1)
 $max_mark = 248; // marker for a (theoretical ;-)) 5-byte-char and mask for a 4-byte-char;
 $html = EMPTY_STRING;
 for($str_pos = 0; $str_pos < strlen($utf); $str_pos++) {
   $old_chr = $utf{$str_pos};
   $old_val = ord( $utf{$str_pos} );
   $new_val = 0;
   $utf8_marker = 0;
   // skip non-utf-8-chars
   if( $old_val > 127 ) {
     $mark = $max_mark;
     for($byte_ctr = $max_count; $byte_ctr > 2; $byte_ctr--) {
       // actual byte is utf-8-marker?
       if( ( $old_val & $mark  ) == ( ($mark << 1) & 255 ) ) {
         $utf8_marker = $byte_ctr - 1;
         break;
       }
       $mark = ($mark << 1) & 255;
     }
   }
   // marker found: collect following bytes
   if($utf8_marker > 1 and isset( $utf{$str_pos + 1} ) ) {
     $str_off = 0;
     $new_val = $old_val & (127 >> $utf8_marker);
     for($byte_ctr = $utf8_marker; $byte_ctr > 1; $byte_ctr--) {
       // check if following chars are UTF8 additional data blocks
       // UTF8 and ord() > 127
       if( (ord($utf{$str_pos + 1}) & 192) == 128 ) {
         $new_val = $new_val << 6;
         $str_off++;
         // no need for Addition, bitwise OR is sufficient
         // 63: more UTF8-bytes; 0011 1111
         $new_val = $new_val | ( ord( $utf{$str_pos + $str_off} ) & 63 );
       }
       // no UTF8, but ord() > 127
       // nevertheless convert first char to NCE
       else {
         $new_val = $old_val;
       }
     }
     // build NCE-Code
     $html .= '&#'.$new_val.';';
     // Skip additional UTF-8-Bytes
     $str_pos = $str_pos + $str_off;
   }
   else {
     $html .= chr($old_val);
     $new_val = $old_val;
   }
 }
 return($html);
}
?>


--colibri--

If you have configured and compiled PHP with all the necessary command-line options and still get the error:
Fatal error: Call to undefined function imagettftext()
Try doing a "make clean"  before building the php apache module:
./configure [...]
make clean
make
make install
This may solve your problem (and hopefully keep you from wasting hours trying different compile options!)


02-dec-2002 07:13

If you have an older version of the GD library, but wish to use a font file which has spaces in the path, you should convert the path into DOS style names. This will only work on windows.
For example:
C:\reallylongpath\reallylongpath\font.ttf
Would become:
C:\really~1\really~1\font.ttf


paul reinheimer

If you compiled PHP yourself but get an error:
Fatal error: Call to undefined function imagettftext().
You need to compile PHP with more options.
--with-gd
--enable-gd-native-ttf
--with-png
--with-zlib-dir=/usr/local/lib/zlib-1.2.1
--with-ttf
--with-jpeg-dir=/usr/local/lib/jpeg-6b/
--with-freetype-dir=/usr/local/lib/freetype-2.1.9/
--with-xpm-dir=/usr/X11R6/
The next set deal with setting up GD, and the appropriate options. Just enabling GD, ttf, png & jpeg is NOT enough. You also need Freetype and XPM.


plusplus7

If you are getting all rectangles instead of text, it may well mean that your ttf font is not opentype, particularly if it is an older freeware one. This requirement didn't exist in older versions so you may find that your font stops working after you upgrade. To fix this problem, try downloading the free MS Volt utility. From there, open your font file, and then click on Compile, and resave.

nospam

I've found that upsampling your text by a factor of 8 or more can really improve the readability of generated text, especially in smaller font sizes (9 or less). I find it also helps with fonts that have kerning to reduce space between letters such as capital T and capital A (TA) where the top-right of the T will be cut off due to GD "features".
I can't tell you, the reader, exactly how to do this, as it will depend on how you are currently generating your text, but essentially what you want to try doing is upsize your font by a factor of 8 and then scale down the resulting image by the same factor.
So if you were using font size 10, use font size 80 and use imagecopyresampled() to divide the width/height down again by 8. The resulting image will be a few pixels different in width / height compared to direct text writing, so make sure to check your image sizes if you are using fixed dimensions.
Play around with other factors, 16 is a bit nicer but results in a higher CPU/RAM load when processing. Any higher is unnecessary I think. If possible you should also cache the image to a file instead of reprocessing it each request.


mats dot engstrom

I'll second the note from --colobri--.  
Just adding --with-ttf and --with-freetype-dir=/usr/lib/ on the ./configure and then doing a "make; make install" is not enough.
I had to do a "make clean" and then a "make install" in order to get the FreeType-support enabled.
Here are my relevant ./configure lines:
--with-gd \
--enable-gd-native-ttf \
--with-ttf \
--with-freetype-dir=/usr/lib/ \
--with-jpeg-dir=/usr/lib/libjpeg.so.62 \
--enable-exif \


admin

I wrote two classes: PHP Abstract Drawing Toolkit and PHP Graphics, the elements of PHP Font Image Generator2. An instance of the class Graphics can draw multi-sampling antialiased text, 7 horizontal alignment of text box (left, center, right, left-adjust, center-adjust, right-adjust, adjust), 3 vertical alignment (top, middle, bottom), and other Java-like methods.
<?php
require_once "package.graphics.php";
$canvas = new Canvas();
$canvas->setSize(400, 400);
$g =& $canvas->getGraphics();
$g->setColor(new Color(0xffffff));
$g->fill();
$g->setColor(new Color(0, 0, 0, 80));
$g->setFont(new Font($_POST['font'], 20));
$g->drawString($_POST['text'], 0, 0, 400, 400, 'center-adjust', 'middle');
$canvas->complete();
$canvas->output();
?>
The class script is here.
http://sgssweb.com/experiments/?file=PHPFontImageGenerator2


mer`zikain

I was looking for a way to add kerning to my text and finally just made this function to do it. Of course, if you're generating the size of the image based on the text you're putting in it, you'll have to figure out the new size to fit the new text width but I'm sure you can figure that out.
for($i=0;$i<strlen($text);$i++){
       // Get single character
$value=substr($text,$i,1);
if($pval){ // check for existing previous character
list($lx,$ly,$rx,$ry) = imagettfbbox($fontsize,0,$font,$pval);
$nxpos+=$rx+3;
}else{
$nxpos=0;
}
       // Add the letter to the image
imagettftext($im, $fontsize, 0, $nxpos, $ypos, $fontcolor, $font, $value);
$pval=$value; // save current character for next loop
}


jpetsel

I was looking at ugo's center and it was great for left to right centering, but it wouldn't center up and down.  So with some changes to suit my needs this is what I came up with.  Some of the notations are just for my edifcation so may mean nothing for you all but you will see I added a $posy that helps with centering up and down.  I was also feeding my feilds from a form.
<?php
// Set the content-type
header("Content-type: image/png");
//1line per column
$text=array(0=>$_POST['linei'],1=>$_POST['lineii'],
2=>$_POST['lineiii'],3=>$_POST['lineiv'],4=>$_POST['linev']);
$Image_Width=400;
$Text_Size=$_POST['textsize'];
$Image_Height=400;
// Create the image
$im = imagecreatetruecolor ($Image_Width, $Image_Height); /* Create a blank image */
// Create some colors
$white = imagecolorallocate($im, 255, 255, 255);
$grey = imagecolorallocate($im, 128, 128, 128);
$black = imagecolorallocate($im, 0, 0, 0);
imagefilledrectangle($im, 1, 1, 398, 398, $white);
// Replace path by your own font path
$font = $_POST['font_name'];
for ($i=0; $i < sizeof($text); $i++) {
//Center the text
$Text_Box_Size = imagettfbbox($Text_Size, 0, $font, $text[$i]);
$Text_Box_Width = abs($Text_Box_Size[2] + $Text_Box_Size[0]);
$Text_Box_Height = abs($Text_Box_Size[7] + $Text_Box_Size[1]);
$Text_Height = $Text_Height + $Text_Box_Height;
$posx = ($Image_Width - $Text_Box_Width) / 2;
$posy = ($Image_Height - $Text_Box_Height * sizeof($text)) / 2 + $Text_Height;
/*
Add the text (***array imagettftext ( resource image, float size, float angle,
int x, int y, int color, string fontfile, string text )***)
*/

imagettftext($im, $Text_Size, 0, $posx, $posy, $black, $font, $text[$i]);
}
// Using imagepng() results in clearer text compared with imagejpeg()
imagepng($im);
imagedestroy($im);
?>


webmaster

I spent days looking for this, couldn't find it, so just made it myself. This is an ultra simple text banner that keeps the text pretty much centered (not perfect when text is angled) vertically and horizontally. Size, font, colors are easy to edit and in HTML version for the colors.
Any additions (maybe for multi-line functionality) can be added if you desire.
<?php
### Declare this script will be displayed as a PNG image.
header("Content-type: image/png");
####################### BEGIN USER EDITS #######################
$imagewidth = 500;
$imageheight = 100;
$fontsize = "20";
$fontangle = "0";
$font = "arial.ttf";
$text = "123456789";
$backgroundcolor = "003366";
$textcolor = "FFCC66";
######################## END USER EDITS ########################
### Convert HTML backgound color to RGB
if( eregi( "([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})", $backgroundcolor, $bgrgb ) )
{$bgred = hexdec( $bgrgb[1] );   $bggreen = hexdec( $bgrgb[2] );   $bgblue = hexdec( $bgrgb[3] );}
### Convert HTML text color to RGB
if( eregi( "([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})", $textcolor, $textrgb ) )
{$textred = hexdec( $textrgb[1] );   $textgreen = hexdec( $textrgb[2] );   $textblue = hexdec( $textrgb[3] );}
### Create image
$im = imagecreate( $imagewidth, $imageheight );
### Declare image's background color
$bgcolor = imagecolorallocate($im, $bgred,$bggreen,$bgblue);
### Declare image's text color
$fontcolor = imagecolorallocate($im, $textred,$textgreen,$textblue);
### Get exact dimensions of text string
$box = @imageTTFBbox($fontsize,$fontangle,$font,$text);
### Get width of text from dimensions
$textwidth = abs($box[4] - $box[0]);
### Get height of text from dimensions
$textheight = abs($box[5] - $box[1]);
### Get x-coordinate of centered text horizontally using length of the image and length of the text
$xcord = ($imagewidth/2)-($textwidth/2)-2;
### Get y-coordinate of centered text vertically using height of the image and height of the text
$ycord = ($imageheight/2)+($textheight/2);
### Declare completed image with colors, font, text, and text location
imagettftext ( $im, $fontsize, $fontangle, $xcord, $ycord, $fontcolor, $font, $text );
### Display completed image as PNG
imagepng($im);
### Close the image
imagedestroy($im);
?>


ultraniblet

I have found the kerning (spacing between letters) pretty poor with GD - it's not up to your average designer's standards. Here are some ways to improve it:
- Place the letters one by one using their bounding box instead of using one string
- adjust with a $kerning value
- For small text, sample it down from a larger size to adjust in increments less than 1px
Eg:
<?PHP
$STRING = "NOTRE PHILOSOPHIE";
// ---- PRESETS
$FONT = "CantoriaMTStd-SemiBold.otf";
$FONT_SIZE = 10.5;
$WIDTH = 200;
$HEIGHT = 16;
$KERNING = 0;
$BASELINE = 12;
$BG_COLOR = array(
"R"=>5,
"G"=>45,
"B"=>53
);
$TXT_COLOR = array(
"R"=>188,
"G"=>189,
"B"=>0
);
// ---- CREATE CANVAS + PALETTE
$canvas = imageCreateTrueColor($WIDTH*4,$HEIGHT*4);
$bg_color = imageColorAllocate($canvas, $BG_COLOR["R"], $BG_COLOR["G"], $BG_COLOR["B"]);
$txt_color = imageColorAllocate($canvas, $TXT_COLOR["R"], $TXT_COLOR["G"], $TXT_COLOR["B"]);
imagefill ( $canvas, 0, 0, $bg_color );
// ---- DRAW
$array = str_split($STRING);
$hpos = 0;
for($i=0; $i<count($array); $i++)
{
$bbox = imagettftext( $canvas, $FONT_SIZE*4, 0, $hpos, $BASELINE*4, $txt_color, $FONT, $array[$i] );

$hpos = $bbox[2]+$KERNING;
}
// ---- SAMPLE DOWN & OUTPUT
$final = imageCreateTrueColor($WIDTH,$HEIGHT);
imageCopyResampled( $final, $canvas, 0,0,0,0, $WIDTH, $HEIGHT, $WIDTH*4, $HEIGHT*4 );
header('Content-type: image/png');
imagePNG($final);
imageDestroy($canvas);
imageDestroy($final);
?>


waage

I had some issues trying to get both word wrapping and new line detection but with some of the help from the comments below i got this. (thanks to jwe for the main part of the code here)
<?php
function ttfWordWrappedText($text, $strlen = 38) {
$text = urldecode($text);
$text = explode("\n", $text);

$i = 0;
foreach($text as $text)
{
while(strlen($text) > $strlen) {
  $startPoint = $strlen - 1;
  while(substr($text, $startPoint, 1) != " ") {
       $startPoint--;
  }
  $line[$i][] = trim(substr($text, 0, $startPoint));
  $text = substr($text, $startPoint);
}
$line[$i][] = trim($text);
$i++;
}

return $line;
}
?>
This returns an array for each newline entered and subarray for each wordwrapped line to print.
ie.
Array
(
   [0] => Array
       (
           [0] => This is the first long line
           [1] => that i entered.
       )
   [1] => Array
       (
           [0] => And this is the new line after that.
       )
)


jwe

I found this line a little confusing:
"May include decimal numeric character references (of the form: &#8364;) to access characters in a font beyond position 127."
I was using a font that had apostrophes and quotes stored in a non-standard position, and so they were being rendered as spaces by imagettftext.  This line seemed to suggest a solution, but it took a while to figure it out.
Turns out, a "decimal numeric character reference" is a decimal conversion of the hex value of the *unicode* position of the character you want.  For a while I was trying ASCII positions (I knew the ALT+ code for typing the character I needed in Windows).
In the Windows XP character map, the unicode positions are shown as U+2018 or U+201C, etc.  Ignore the U+ and convert that hex number to decimal, and then stick that in your text string with the &# on the front and ; on the end, and pass it to imagettftext.
--Julian


elvis

I could not find any information about why my server renders ttf fonts looking really ugly. On servers around me i could not find any - except one - which could render fonts fine. I have the latest gd2 and freetype packages.
Check the differences (these two images are generated with the same php code and the same font):
my version
http://www.tinystudios.hu/rating.php? game_name=TekkenDarkResurrection&rating=98&plus=Fine& minus=worstEver&platform=PSP
good version
http://www.globalgame.hu/rating.php? game_name=TekkenDarkResurrection&rating=98&plus=Fine& minus=worstEver&platform=PSP


gav-alex

Hi all!
When my hoster updated his php's libs at first minutes i've got the same problem as some of you.
Php couldn't find the path to true type fonts.
The solution in my case was to make the path look like this
<?php
imagettftext($im, 20, 0, 620, 260, $secondary_color, "./tahoma.ttf" , "NEWS");
?>
so as you can see i simply added "./"
another tip that i wanted to add here is how to write in RUssian on image using imagettftext
you simply have to change the function argument like this
<?php
imagettftext($im, 15, 0, 575, 300, $secondary_color, "./tahoma.ttf" , win2uni("some word in russian"));
?>
where win2uni is the function that converts win1251 to unicode. here is the code of it
<?php
 //  Windows 1251 -> Unicode
 function win2uni($s)
 {
   $s = convert_cyr_string($s,'w','i'); //  win1251 -> iso8859-5
   //  iso8859-5 -> unicode:
   for ($result='', $i=0; $i<strlen($s); $i++) {
     $charcode = ord($s[$i]);
     $result .= ($charcode>175)?"&#".(1040+($charcode-176)).";":$s[$i];
   }
   return $result;
 }
?>
That's all today! Thanks for your attention!
Alex


pillepop2003

Hey guys,
check this function if you want to rotate the text around its center and not its "lower left" pivot-point:
<?php
// Put center-rotated ttf-text into image
// Same signature as imagettftext();
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, $py, $color, $fontfile, $text);
}
?>
Big up
Phil


webmaster

Developers who want to write Persian(Farsi) or Arabic characters to the image can use the following function.
http://developer.berlios.de/projects/persian-log2vis/


lassial

Creating multiline text with GD is bit complicated, one of the issues I've ran to is how to set line spacing, a normal feature in all type setting (even type writers). By default, line spacing with imagettftext seems to be 150 % or more, too much for me anyhow. Thus I've used the function below to get the lines closer to each other. By default, it appears to create 100 % linespacing, but it has not been tested thoroughly.
null imagettfmultilinetext
(resource $image, float $size, float $angle, int $x, int $y, int $color, string $fontfile, string $text , $spacing)
spacing is a coefficient, comparable to Line spacing in a word processors or graphics software, causing a shift relative to font size in the line spacing
<?php
function imagettfmultilinetext($image, $size, $angle, $x, $y, $color, $fontfile,  $text, $spacing=1)
{
$lines=explode("\n",$text);
for($i=0; $i< count($lines); $i++)
{
$newY=$y+($i * $size * $spacing);
imagettftext($image, $size, $angle, $x, $newY, $color, $fontfile,  $lines[$i], $spacing);
}
return null;
}
?>


ole clausen

Comment to: Sohel Taslim (03-Aug-2007 06:19)
Thanks for the function which I have modified a bit. In the new version the lines have equal space between them (the g's in your example create bigger space between the lines) - set by the parameter '$Leading'.
I have used the for-loop for better performance and slimmed the rest a little  :)
   /**
    * @name                    : makeImageF
    *
    * Function for create image from text with selected font. Justify text in image (0-Left, 1-Right, 2-Center).
*
    * @param String $text     : String to convert into the Image.
    * @param String $font     : Font name of the text. Kip font file in same folder.
    * @param int    $Justify  : Justify text in image (0-Left, 1-Right, 2-Center).
    * @param int    $Leading  : Space between lines.
    * @param int    $W        : Width of the Image.
    * @param int    $H        : Hight of the Image.
    * @param int    $X        : x-coordinate of the text into the image.
    * @param int    $Y        : y-coordinate of the text into the image.
    * @param int    $fsize    : Font size of text.
    * @param array  $color    : RGB color array for text color.
    * @param array  $bgcolor  : RGB color array for background.
    *
    */
   function imagettfJustifytext($text, $font="CENTURY.TTF", $Justify=2, $Leading=0, $W=0, $H=0, $X=0, $Y=0, $fsize=12, $color=array(0x0,0x0,0x0), $bgcolor=array(0xFF,0xFF,0xFF)){
       
       $angle = 0;
       $_bx = imageTTFBbox($fsize,0,$font,$text);
$s = split("[\n]+", $text);  // Array of lines
$nL = count($s);  // Number of lines
       $W = ($W==0)?abs($_bx[2]-$_bx[0]):$W;    // If Width not initialized by programmer then it will detect and assign perfect width.
       $H = ($H==0)?abs($_bx[5]-$_bx[3])+($nL>1?($nL*$Leading):0):$H;    // If Height not initialized by programmer then it will detect and assign perfect height.

       $im = @imagecreate($W, $H)
           or die("Cannot Initialize new GD image stream");
       
       $background_color = imagecolorallocate($im, $bgcolor[0], $bgcolor[1], $bgcolor[2]);  // RGB color background.
       $text_color = imagecolorallocate($im, $color[0], $color[1], $color[2]); // RGB color text.

       if ($Justify == 0){ //Justify Left
           imagettftext($im, $fsize, $angle, $X, $fsize, $text_color, $font, $text);
       } else {
// Create alpha-nummeric string with all international characters - both upper- and lowercase
       $alpha = range("a", "z");
$alpha = $alpha.strtoupper($alpha).range(0, 9);
// Use the string to determine the height of a line
$_b = imageTTFBbox($fsize,0,$font,$alpha);
$_H = abs($_b[5]-$_b[3]);
$__H=0;
           for ($i=0; $i<$nL; $i++) {
               $_b = imageTTFBbox($fsize,0,$font,$s[$i]);
               $_W = abs($_b[2]-$_b[0]);
               //Defining the X coordinate.
               if ($Justify == 1) $_X = $W-$_W;  // Justify Right
else $_X = abs($W/2)-abs($_W/2);  // Justify Center

//Defining the Y coordinate.
$__H += $_H;
               imagettftext($im, $fsize, $angle, $_X, $__H, $text_color, $font, $s[$i]);
               $__H += $Leading;
           }
}

       return $im;
   }


admin

Another way of the bellow. After creating a child class of GMIPluggableSet class, which should override two method: getExpression() and getVariables(), throw it to a instance of FontImageGenerator class.
For example, the code follows:
<?php
require_once 'package.fig.php';
class SampleFontImagePluggableSet
extends GMIPluggableSet
{
var $defaultVariables = array(
"text" => null,
"size" => null,
"font" => null,
"color" => "0x000000",
"alpha" => "100",
"padding" => 0,
"width" => null,
"height" => null,
"align" => "left",
"valign" => "middle",
"bgcolor" => "0xffffff",
"antialias" => 4
);

function SampleFontImagePluggableSet() {
parent::GMIPluggableSet();
}

function getExpression() {
return "size {width}, {height};".
  "autoresize none;".
  "type gif, 256, {color: {bgcolor}};".
  "padding {padding};".
  "color {color: {bgcolor}};".
  "fill;".
  "color {color: {color}, {alpha}};".
  "antialias {antialias};".
  "font {font}, {size};".
  "string {text}, 0, 0, {width}, {height}, {align}, {valign};";
}

function getVariables() {
return array_merge($this->defaultVariables, $_GET);
}
}
$pluggableSet = new SampleFontImagePluggableSet();
$fig = new FontImageGenerator();
$fig->setPluggableSet($pluggableSet);
$fig->execute();
?>
This output a image with the text defined in $_GET['text'], the font in $_GET['font'], the text color in $_GET['color'], the background in $_GET['bgcolor'], and so on.
The script file is available at: http://sgssweb.com/experiments/?file=PHPFontImageGenerator .


nick

A trivial function to get right or centre aligned horizontal text:
function imagettftextalign($image, $size, $angle, $x, $y, $color, $font, $text, $alignment='L') {

//check width of the text
$bbox = imagettfbbox ($size, $angle, $font, $text);
$textWidth = $bbox[2] - $bbox[0];
switch ($alignment) {
case "R":
$x -= $textWidth;
break;
case "C":
$x -= $textWidth / 2;
break;
}

//write text
imagettftext ($image, $size, $angle, $x, $y, $color, $font, $text);
}


buddyhacker

A correction to Paul Reinheimer's note above regarding this PHP error:
Fatal error: Call to undefined function imagettftext().
Paul states that you need XPM libraries to resolve this issue.  This is not true.  There is an error message that originates from "configure" which mistakenly shows itself when other components are missing.  For instance, if you tell "configure" to add JPEG support, and it can't find the libraries, it will tell you it can't find the JPEG libraries AND it will recommend adding --with-xpm to solve the problem.  This recommendation is ill-placed and misleading.
I received the same error message above, along with the recommendation to add XPM supprt.  However I resolved it by adding the --with-freetype-dir  AND --enable-gd-native-ttf  options  to the "configure" command line.  I did _not_ need XPM.
There are other variations to this error message, such as the script recommending adding JPEG support or PNG support to resolve it's own inability to locate other libraries.  The script needs some cleanup in order to fix these poorly placed recommendations.
FYI, imagettftext() is a call to one of the truetype fonts functions.  It is NOT related in any way to the XPM libraries, so it is not required unless you explicitly want XPM functionality.


ben

A centralised text watermark - of  any length, that automatically sizes to about 70% of the width, and can be rotated to any angle.
<?php
/* Get image info */
$Image = @ImageCreateFromJPEG ("YourImage.jpg") ;
$sx = imagesx($Image) ;
$sy = imagesy($Image) ;
if ($WatermarkNeeded)
{
/* Set text info */
$Text="Copyright Ben Clay" ;
$Font="arial.ttf" ;
$FontColor = ImageColorAllocate ($Image,255,255,255) ;
$FontShadow = ImageColorAllocate ($Image,0,0,0) ;
$Rotation = 30 ;
/* Make a copy image */
$OriginalImage = ImageCreateTrueColor($sx,$sy) ;
ImageCopy ($OriginalImage,$Image,0,0,0,0,$sx,$sy) ;
/* Iterate to get the size up */
$FontSize=1 ;
do
{
$FontSize *= 1.1 ;
$Box = @ImageTTFBBox($FontSize,0,$Font,$Text);
$TextWidth = abs($Box[4] - $Box[0]) ;
$TextHeight = abs($Box[5] - $Box[1]) ;
}
while ($TextWidth < $sx*0.7) ;
/*  Awkward maths to get the origin of the text in the right place */
$x = $sx/2 - cos(deg2rad($Rotation))*$TextWidth/2 ;
$y = $sy/2 + sin(deg2rad($Rotation))*$TextWidth/2 + cos(deg2rad($Rotation))*$TextHeight/2 ;
/* Make shadow text first followed by solid text */
ImageTTFText ($Image,$FontSize,$Rotation,$x+4,$y+4,$FontShadow,$Font,$Text);
ImageTTFText ($Image,$FontSize,$Rotation,$x,$y,$FontColor,$Font,$Text);
/* merge original image into version with text to show image through text */
ImageCopyMerge ($Image,$OriginalImage,0,0,0,0,$sx,$sy,50) ;
}
ImageJPEG ($Image) ;
?>


Change Language


Follow Navioo On Twitter
gd_info
getimagesize
image_type_to_extension
image_type_to_mime_type
image2wbmp
imagealphablending
imageantialias
imagearc
imagechar
imagecharup
imagecolorallocate
imagecolorallocatealpha
imagecolorat
imagecolorclosest
imagecolorclosestalpha
imagecolorclosesthwb
imagecolordeallocate
imagecolorexact
imagecolorexactalpha
imagecolormatch
imagecolorresolve
imagecolorresolvealpha
imagecolorset
imagecolorsforindex
imagecolorstotal
imagecolortransparent
imageconvolution
imagecopy
imagecopymerge
imagecopymergegray
imagecopyresampled
imagecopyresized
imagecreate
imagecreatefromgd2
imagecreatefromgd2part
imagecreatefromgd
imagecreatefromgif
imagecreatefromjpeg
imagecreatefrompng
imagecreatefromstring
imagecreatefromwbmp
imagecreatefromxbm
imagecreatefromxpm
imagecreatetruecolor
imagedashedline
imagedestroy
imageellipse
imagefill
imagefilledarc
imagefilledellipse
imagefilledpolygon
imagefilledrectangle
imagefilltoborder
imagefilter
imagefontheight
imagefontwidth
imageftbbox
imagefttext
imagegammacorrect
imagegd2
imagegd
imagegif
imagegrabscreen
imagegrabwindow
imageinterlace
imageistruecolor
imagejpeg
imagelayereffect
imageline
imageloadfont
imagepalettecopy
imagepng
imagepolygon
imagepsbbox
imagepsencodefont
imagepsextendfont
imagepsfreefont
imagepsloadfont
imagepsslantfont
imagepstext
imagerectangle
imagerotate
imagesavealpha
imagesetbrush
imagesetpixel
imagesetstyle
imagesetthickness
imagesettile
imagestring
imagestringup
imagesx
imagesy
imagetruecolortopalette
imagettfbbox
imagettftext
imagetypes
imagewbmp
imagexbm
iptcembed
iptcparse
jpeg2wbmp
png2wbmp
eXTReMe Tracker