by

PHP function to draw wrapped text

Here’s a PHP code snippet that draws text bounded by a textbox. You’ll need GD with TrueType support.

The snippet supports rotation, vertical and horizontal alignments, configurable line heights and leading, word wrap, character wrap, and text outlining.

The word wrapping is very greedy.

You can find the code snippet here:
http://www.sk89q.com/pastebin/php/imagettftextboxopt.phps

Example usage:

$size = 14;
$angle = 34;
$left = 10;
$top = 40;
$color = imagecolorallocate($im, 255, 0, 0);
$fontfile = "arial.ttf";
$text = "Test";
$opt = array(
  'width' => 300,
  'line_height' => 15,
  'orientation' => array(ORIENTATION_TOP, ORIENTATION_LEFT),
  'align' => ALIGN_LEFT,
  'v_align' => VALIGN_TOP,
  'outlines' = array(
    array(5, imagecolorallocate($im, 0, 255, 0)),
    array(2, imagecolorallocate($im, 0, 0, 255)),
  ),
  // More options documented in the code
);
imagettftextboxopt($im, $size, $angle, $left, $top, $color, $fontfile, $text, $opt);
  • Tom

    This is excellent, just what I needed, many thanks indeed

  • Cristian

    Hi, how can use?

  • sk89q

    Use it like imagetttext(). You can pass additional arguments with the last parameter, $opt. You can find the list of extra parameters in the source.

  • Rodrigo

    Thanks Man! This is just what I needed, you saved me a lot of time! You’re the best!

  • Coach

    I tried to align my text top left with the following code, but there is still some space left to the top!

    Coach

    $image = ImageCreateTrueColor(400, 400);
    $color = ImageColorAllocate($image, 235, 235, 160);
    $font_arial = “/home/…/fonts/arial.ttf”;

    $text = “very long text … very long text”;

    $options = array(“width”=>400, “height”=>400, “orientation”=>ORIENTATION_TOP, “align”=>ALIGN_LEFT, “v_align”=>VALIGN_TOP);
    imagettftextboxopt(&$image, 22, 0, 0, 0, $color, $font_arial, $text, $options);

  • sk89q

    I just changed the code a bit. Hopefully it should be closer.

  • http://www.munkbusiness.dk Michael

    Hallo, i tried this code, but i just can’t figure out how to use it, please why aren’t there any instructions for usage for us noobs.

  • sk89q

    Take a look at Coach’s comment for an example.

  • http://www.munkbusiness.dk Michael

    I tried that tons of times, it just shows an empty picture, the include thing in the start is your code, here is my code:

    400, “height”=>400, “orientation”=>ORIENTATION_TOP, “align”=>ALIGN_LEFT, “v_align”=>VALIGN_TOP);
    imagettftextboxopt(&$im, 22, 0, 0, 0, $orange, $font_times, $text, $options);

    imagecopy($im, $art, 16, 63, 0, 0, 318, 247);

    imagepng($im);
    imagedestroy($im);
    imagedestroy($art);

    ?>

  • http://www.munkbusiness.dk Michael

    It seems like it didn’t put in all the code, so i will make a file link: http://www.munkbusiness.dk/test1.txt

  • sk89q

    You need to change the curly quotes to regular quotes (WordPress changes them).

    Temporarily comment out the line ‘header(“Content-type: image/png”);’ to see errors.

  • http://www.munkbusiness.dk Michael

    I didn’t understand the thing about “curly quotes”. But i dom’t get eny error when i don’t have the header. Only some notices

  • http://www.munkbusiness.dk Michaelteke oout the header

    It seems like my last question was deleted… When i remove the header tag, it don’t give any errors or warnings only notices, so i can’t figure out why it dosn’t work, and the curly qoutes thing <- i didn’t get it at all

  • http://www.munkbusiness.dk Michael

    This is what i get if i comment out header and $options and put in default_opt in options place:

    Warning: Call-time pass-by-reference has been deprecated – argument passed by value; If you would like to pass it by reference, modify the declaration of [runtime function name](). If you would like to enable call-time pass-by-reference, you can set allow_call_time_pass_reference to true in your INI file. However, future versions may not support this any longer. in C:\Program Files\EasyPHP 2.0b1\www\rush\test2.php on line 61

    Notice: Undefined variable: default_opt in C:\Program Files\EasyPHP 2.0b1\www\rush\test2.php on line 61

    Catchable fatal error: Argument 9 passed to imagettftextboxopt() must be an array, null given, called in C:\Program Files\EasyPHP 2.0b1\www\rush\test2.php on line 61 and defined in C:\Program Files\EasyPHP 2.0b1\www\rush\textbox.php on line 41

  • TommyHot

    Very nice code, but would it be possible to support new lines? I mean when you put a text that is written on many new lines, it will ignore those new lines and still print that text on one line. I couldn’t find any way to do this and it would by nice if this function would support it. Thank you.

  • http://www.bitchesofcraigslist.com Brent

    I am trying to get this to work and I have tried the following:
    inserted the function at the top of my php doc.
    Function taken from http://sk89q.therisenrealm.com/pastebin/php/imagettftextboxopt.phps?source

    Then I inserted the following code

    $image = ImageCreateTrueColor(400, 400);

    $color = ImageColorAllocate($image, 235, 235, 160);
    $font_arial = “/home/brent/public_html/zepey/verdana.ttf”;

    $text = “Brents text”;

    $options = array(“width”=>400, “height”=>400, “orientation”=>ORIENTATION_TOP, “align”=>ALIGN_LEFT, “v_align”=>VALIGN_TOP);
    //imagettftextboxopt(&$image, 22, 0, 0, 0, $color, $font_arial, $text, $options);

    All I get is a blank white screen. If I try to print the imagettftextboxopt function I get the number 58

    I know I have the gd library because I use it to make thumbnails and I uploaded the font also. Any Ideas? If I can gget this script to work it will be awesome!

  • http://www.bitchesofcraigslist.com Brent

    sorry, in the last post the function imagettftextboxopt was commented out. Thats not how it is when i try to run it

  • http://www.bitchesofcraigslist.com Brent

    In the last post I sent imagettftextboxopt was commented out. This was not how I had it. Of course that would give me a blank white screen

  • http://mild.ch Enrique

    hi all.
    at first i got a white image too, but after playing a bit with the options, i found out that one has to set line_height to 1, as suggested in the comment.

    ‘line_height’ => 1, // Set to 0 to use the largest line height (not a good idea)

  • http://www.eiurunning.com Nate

    My text is all printint out, but all on one line. So its just like 4 lines all written over eachother. Can you help me out?

    Here is my page if you want to try:
    http://www.eiurunning.com/runnion/

    $new_image = imagecreatefromjpeg ($base_image);
    $text_colour = imagecolorallocate( $new_image, 255, 255, 255 );
    $line_colour = imagecolorallocate( $new_image, 128, 255, 0 );
    $font_sego = ‘segoepr.ttf’;
    $font_distant_galaxy = ‘sfdg.ttf’;
    $left = 25;
    $top = 200;
    $size = 10;
    $angle = 0;
    $options = array(”width”=>250, “height”=>400);
    imagettftextboxopt(&$new_image, $size, $angle, $left, $top, $text_colour, $font_sego, $details, $options);

  • Corpo

    Terrible piece of code !!!

    Works flawlessly, nothing to add because all options are already here!

    Thanks A LOT !

  • tori

    had to comment all the throw new exception lines.
    is it because i’m using php 4.x?

    works like a charm now.

    thanks a lot.

  • Anup

    It seems lines 56-58:

    ‘align’ => ALIGN_LEFT, // ALIGN_LEFT, ALIGN_MIDDLE, ALIGN_RIGHT
    ‘v_align’ => VALIGN_TOP, // VALIGN_TOP, VALIGN_CENTER, VALIGN_BOTTOM

    must be changed to:

    ‘align’ => ALIGN_LEFT, // ALIGN_LEFT, ALIGN_CENTER, ALIGN_RIGHT
    ‘v_align’ => VALIGN_TOP, // VALIGN_TOP, VALIGN_MIDDLE, VALIGN_BOTTOM

  • sk89q

    Ah, yes. You’re right.

  • Anup

    I think it will be nice additional feature for this usefull function to decriment font size in an internal loop to avoid trimming of text if it is too large.

    I’ve implemented it this way:

    $size++;
    do {
    $size–
    // original lines 105 – 253
    } while( $max_lines < count($lines) );

    Of course this is not efficient method but it works for me.
    I think you could find a more elegant way :)

  • Anup

    My third line must be:

    $size–; // decriment font size

  • Krudtso

    Hi i allmost got this script running, it work when i comment out this line: imagettftextboxopt($im, 22, 0, 0, 0, $orange, $font_times, $text, $options); (without the text offcourse) and if i comment out the header while that line is not commented out i get this message:

    Notice: Undefined offset: 29 in C:\Program Files\EasyPHP 2.0b1\www\rush\textbox.php on line 128

    Notice: Undefined offset: 29 in C:\Program Files\EasyPHP 2.0b1\www\rush\textbox.php on line 128

    textbox.php is the code you give us

    How do i fix this?

  • sk89q

    Well, it’s because the error reporting level you have set in your installation of PHP shows notice level warnings. The simple way to fix it is by putting error_reporting(E_ALL ^ E_NOTICE); at the top of your script. The better way would be to actually fix the notices, but you’d have to do that by yourself at the moment.

    http://php.net/error_reporting

  • Krudtso

    Thanks I allready tried removing all warnings and then it didn’t work, but now it does, thanks a bunch!

  • Krudtso

    Hi again. I think i found a wierd bug. If i try to render a “0” (zero), it dosn’t show anything. All other letters and numbers render jsut fine. I tried with different fonts and i doubble checked all fonts to have a “0” (zero) and they all had. Temporaly i use string replace to chane “0” (zero) to “O”. But it just don’t look as good, and is hard to use for calculations. PLease check this out.

  • Krudtso

    Sorry for posting 2 times in a row, but I did some more testing on the bug i mentioned above, and it seems that it don’t render when it render “0” (zero) alone, but if i write for example: f0 (zero) it renders zero fine or if i write 00 (zero) it also work fine.

  • sk89q

    “” == 0 in PHP.

    Change empty($buffer) to $buffer === “”

  • sk89q

    Don’t copy the slanted quotes from my last post (WordPress converted them). Use straight quotes.

  • Krudtso

    Thanks for reminding me about the slanted quotes, im not sure but where exactly do i need to chenge this in your code? $buffer appear several times.

  • Anup

    Good job! Thank you for sharing the function!
    I use it on my production site.

  • http://www.alpha-analytics.com Narendra Patil

    Hi,
    I got this script, its really nice script. Its completetly suitable for my application, because i am designing greeting cards by php GD library.
    But I have font size problem with the code taken from you. what exactly happens is that, when i give large amout of text, then it only takes lines according to width and height provided to it and skips other text. I want to have all text by managing font size which is given by the input.
    I hope you will definately help me. Any help from you will really be appreciated.

    Thanks for the nice script.

  • Joern

    This is a great script!
    Unfortunately I am not able to receive an output… All I get is a white page.
    I inserted your function in a php file, called the function as followed:

    400, “height”=>400, “orientation”=>ORIENTATION_TOP, “align”=>ALIGN_LEFT, “v_align”=>VALIGN_TOP);
    imagettftextboxopt(&$image, 22, 0, 0, 0, $color, $font_arial, $text, $options);
    ? >

    Well, I am not getting anything except a white page… Where could the mistake?
    Maybe I did a mistake witht he font-path?

    GD is version 2.0.28
    freetype 2.1.10

    Thanks a lot in advance for your help!

    ~Joern

  • sk89q

    @Narendra Patil: I’m not entirely sure what you mean. Can you rephrase that?

    @Joern: This may be a stupid question, but did you output the image to the browser?

  • http://www.suzerain.isgreat.org Sujith

    hi guys ,
    well and i have one request that is ,is there any possible to generate image from dive content[text] like following link show that image , i need a image which only from dive content ,plz let me know if any body have idea ! by PHP ,GD
    advance thanks
    Image url :http://photos-a.ak.fbcdn.net/photos-ak-snc1/v846/80/38/1307464944/n1307464944_182112_5902.jpg

    best regards,
    Sujith

  • sk89q

    What do you mean exactly?

  • http://www.suzerain.isgreat.org Sujith

    i meant the image must generate which exactly display in div content ,for example

    http://photos-a.ak.fbcdn.net/photos-ak-snc1/v846/80/38/1307464944/n1307464944_182112_5902.jpg

    the images shows that div have border with re-size handler ,i need to generate image as per that div content display ……anyway can you please give me the source code for “PHP function to draw wrapped text”

    best regards,
    Sujith

  • sk89q

    You just need to get the dimensions and position of the DIV and then use the fuction to draw within those boundaries.

    The code is at:
    http://sk89q.therisenrealm.com/pastebin/php/imagettftextboxopt.phps

  • Errors
  • sk89q

    Fixed.

  • http://cybersujith.co.nr Sujith

    Thanks buddy ,its works well …………..

  • Mazout

    Hi, thany you for yours fabullous php scripting. Could you please give me an example of image creation script. What must you script after your code ?
    We must use the ImageCreateTrueColor ? Thanks

  • sk89q

    Use it like you would use imagettftext()

  • http://www.willbeardmore.com Will

    Hi, I’m attempting to get this working using the outline function.

    I’m currently struggling, here’s my code:
    $black = imagecolorallocate($im, 255, 255, 255);
    $outlines = array(1,$black);
    $options = array(“width”=>400, “line_height” => 1, “outlines”=>$outlines);
    imagettftextboxopt($im,15,0,0,18,$orange,$font,$text,$options);

    I keep getting the “‘The outline argument uses nested arrays” error.

    Any ideas?

    • sk89q

      $outlines = array(array(1, $black));

      This allows you to do…

      $outlines = array(array(1, $black), array(4, $green), array(1, $red));

  • Tyson Harper

    nice article. Do you know if you can stroke or outline text with GD?

    • sk89q

      Yes. My function does exactly that, although its method is very hacky. It re-draws the text repeatedly in a pattern behind the text in order to achieve the effect.

  • Roland Hentschel

    Hi!

    It would be really nice, if there was a sample call for that script.

    ( -: roland :- )