Using the imagettftext function with multiple lines?
Asked Answered
N

4

10

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


?>
Narcosis answered 29/5, 2011 at 6:17 Comment(0)
K
25

Try this:

$text = 'Cool Stuff! this is nice LALALALALA LALA HEEH EHEHE';
$text = wordwrap($_POST['title'], 15, "\n");
Kaylakayle answered 14/1, 2014 at 16:39 Comment(1)
Helped me today. 2 years after... :-)Annettaannette
N
6

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.

Norvell answered 28/9, 2011 at 19:57 Comment(2)
This code works awesomely but i just have one question...how do you then get each line separate?Butternut
instead of iterating over lines simply add PHP_EOL when line gets too long, like so: if ($lineWidth < $maxLineWidth) { $newText .= $value . ' '; } else { $newText .= PHP_EOL . $value; }Cuff
B
2

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:

Example

Beryl answered 4/6, 2018 at 0:13 Comment(1)
It works, but to align the text in center and change the line height?Laplante
L
-2

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
Latini answered 7/7, 2019 at 4:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.