I have a line of text that i need to wrap and center in a GD image. I am using a ttf font as well. Can anything give me some assistance please?
I have managed to get some text to wrap doing the following, but now i need to get it to center:
function wrap($fontSize, $angle, $fontFace, $string, $width){
$ret = "";
$arr = explode(' ', $string);
foreach ( $arr as $word ){
$teststring = $ret.' '.$word;
$testbox = imagettfbbox($fontSize, $angle, $fontFace, $teststring);
if ( $testbox[2] > $width ){
$ret.=($ret==""?"":"\n").$word;
} else {
$ret.=($ret==""?"":' ').$word;
}
}
return $ret;
}
User valentijn de Pagter provides, on php net manual, a nice function to calculate the box (I see you're using imagettfbbox(), indeed) and from the array it returns calculate how to center text. You can find it here:
center text with imagettfbbox
To center both horizontally and vertically: get half height from imagettfbbox of whole text (with new lines) and substract it from half height of your image ($start_x).
Now split text by new lines, create ttfbox for every line and get it's height ($h) and half width ($w). Draw line starting from half image width + $w and $start_x, add $h to $start_x, repat until all lines are written.
This is what I did. using the imagettftext function, you can add new line marks and continue on to the next line. You can add \n to the string after a certain amount of characters. This example will only break on spaces, so words won't get cut off.
$description=$property['description'];
$len=strlen($description);
$str="";
$c=0;
for($i=0;$i<$len;$i++){
$chr=substr($description,$i,1);
$str.=$chr;
if($c>40 && $chr==" ") {
$str.="\n";
$c=0;
}
$c++;
}
$result=$str;
imagettftext($img, 15, 0, $x - 60, $descmgn, $textcolor, $font, $result);
Related
I'm attempting to wrap text around a curve using the function found below. However, this does not take into account aligning the text centered no matter how wide the text maybe be. As an attempt to solve this problem I calculated the width of the text using a binding box.
$type_space=imagettfbbox($fontSize, 0, $fontname, $text);
$image_width = abs($type_space[4] - $type_space[0]) + 10;
However, from this, I need to work out a way that it can adjust the start $angle based on the width. I've played around with lots of settings, however just can't seem to find the correct maths. Any help would be amazing, thank you!
Curve Function
function imagettftextarc($image, $size, $angle, $x, $y, $r, $color, $fontfile, $text, $dir=false){
$sbox=imagettfbbox($size, 0, $fontfile, ' ');
$sbox=($sbox[2]-$sbox[0])*0.1;
$angle=$angle*M_PI/180;
foreach(preg_split('//u', $text) AS $t){
$px=$x+$r*cos($angle);
$py=$y+$r*sin($angle);
$dirangle=(360-(M_PI/2+$angle)*180/M_PI+($dir?180:0))%360;
imagettftext($image, $size, $dirangle, $px, $py, $color, $fontfile, $t);
$box=imagettfbbox($size, 0, $fontfile, $t);
$dx=$box[2]-$box[0];
$da=abs(asin(($dx+$sbox)/$r));
if($dir){
$angle-=$da;
}else{
$angle+=$da;
}
}
}
Possible Solution
I'm not sure how to execute this but the possibility could be to work out the length of the curve if it was a full 360 circle unwrapped horizontally. Then divide the new width with the unwrapped width to create the value that correlates to how many degrees it needs to be altered.
I have this task working great! I have successfully wrote text to an image then displayed the image using php, however the problem I'm running into is getting the font size perfect and to fit within a contained area. Im using imagettftext()
I'm getting this to work however when i move the text to the desired location im manually changing the font to then get it to fit. I would like to text to perfectly fill a "box" inside the image.
Here is my code
Main.php
check out the promo code below<br />
<img src="imagem.php?promo=DISH120" alt="" />
imagem.php
$font = 'font-type.ttf';
$rImg = ImageCreateFromJPEG( "test.jpg" );
$color = imagecolorallocate($rImg, 255, 255, 255);
imagettftext($rImg, 20, 0, 660, 130, $color, $font, urldecode($_GET['promo']));
header('Content-type: image/jpeg');
imagejpeg($rImg, NULL,100);
Here is the image im writing
i want the text to write to the bottom right next to code, however when i make the font big enough to match the CODE height it way to wide.
ADDITION
<?php
function makeTextBlock($text, $fontfile, $fontsize, $width)
{
$words = explode(' ', $text);
$lines = array($words[0]);
$currentLine = 0;
for($i = 1; $i < count($words); $i++)
{
$lineSize = imagettfbbox($fontsize, 0, $fontfile, $lines[$currentLine] . ' ' . $words[$i]);
if($lineSize[2] - $lineSize[0] < $width)
{
$lines[$currentLine] .= ' ' . $words[$i];
}
else
{
$currentLine++;
$lines[$currentLine] = $words[$i];
}
}
return implode("\n", $lines);
}
?>
I found this function re formats a text string into a text block of a given width, this is kinda what im trying to achieve however, im not sure how to integrate this. I want a box which width and height never change that will be filled with text that its character count will change.
This sounds like an issue with the font you're using. Try to make sure that the font matches the font of the text in the image, so that when you increase the size of the font to fit the image, it doesn't go too wide.
Other things I'd point out:
Based on what you're doing, I don't recommend a $_GET parameter.
You should remove the image from memory once you're done with it, like this: imagedestroy($rImg);
I am creating images with some text, when rotation is 0 then its fine but when rotation is > 0 then image looks are bad due to text alignment, because by default alignment is left.Since each and every value is dynamic so we can not fix it,please help me.
$message = 'Thanks, Deep, for making time to have a coffee today Purushottam';
$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;
}
I am also attaching example template.
You can use imagettfbbox to calculate the string size in pixels. Then, with the width you will be able calculate the offset required to align the text to the right. Also, check out the imagettftext documentation for some examples of text alignment.
i am trying to break a long phrase depending on my skyscraper banner width size which can not afford more than three words, i searched the internet and found a script which break the text by setting the character long for the phrase, here is it.
<?
header("Content-type: image/png");
$string = $_GET['text']. ' Click Here';
$im = imagecreatefrompng("../../images/skyscrapper.png");
$orange = imagecolorallocate($im, 0, 0, 0);
$px = (imagesx($im) - 3.8 * strlen($string)) / 2;
$font = 'verdana.ttf';
// Break it up into pieces 10 characters long
$lines = explode('|', wordwrap($string, 10, '|'));
// Starting Y position
$y = 450;
// Loop through the lines and place them on the image
foreach ($lines as $line)
{
imagestring($im,3, $px, $y, $string, $orange);
// Increment Y so the next line is below the previous line
$y += 23;
}
imagepng($im);
imagedestroy($im);
?>
the problem is the output duplicate the phrase three times instead breaking the text as this screen shot
, can someone help to explain whats the problem and what should i do ?
You're not changing $string inside your loop. Shouldn't it be:
imagestring($im,3, $px, $y, $line, $orange);
^^^^^
instead?
Maybe replace
imagestring($im,3, $px, $y, $string, $orange);
with
imagestring($im,3, $px, $y, $line, $orange);
I have been using this simple script to generate images from text:
<?php
header('Content-type: image/png');
$color = RgbfromHex($_GET['color']);
$text = urldecode($_GET['text']);
$font = 'arial.ttf';
$im = imagecreatetruecolor(400, 30);
$bg_color = imagecolorallocate($im, 255, 255, 255);
$font_color = imagecolorallocate($im, $color[0], $color[1], $color[2]);
imagefilledrectangle($im, 0, 0, 399, 29, $bg_color);
imagettftext($im, 20, 0, 10, 20, $font_color, $font, $text);
imagepng($im);
imagedestroy($im);
function RgbfromHex($hexValue) {
if(strlen(trim($hexValue))==6) {
return array(
hexdec(substr($hexValue,0,2)), // R
hexdec(substr($hexValue,2,2)), // G
hexdec(substr($hexValue,4,2)) // B
);
}
else return array(0, 0, 0);
}
?>
I call the script with file.php?text=testing script&color=000000
Now I'd like to know how could I generate text with normal and bold fonts mixed in the same image, something like file.php?text=testing <b>script</b>&color=000000
Thanks to dqhendricks for helping me figure this out.
Here's a quick script I wrote, still needs lot of improvements but for the basic functionality it seems to be working fine:
<?php
header('Content-type: image/png');
$color = RgbfromHex($_GET['color']);
$im = imagecreatetruecolor(400, 30);
$white = imagecolorallocate($im, 255, 255, 255);
imagefilledrectangle($im, 0, 0, 399, 29, $white);
$tmp = $_GET['text'];
$words = explode(" ", $tmp);
$x = array(0,0,10); // DUMMY ARRAY WITH X POSITION FOR FIRST WORD
$addSpace = 0;
foreach($words as $word)
{
if($addSpace) $word = " ".$word; // IF WORD IS NOT THE FIRST ONE, THEN ADD SPACE
if(stristr($word, "<b>"))
{
$font = 'arialbd.ttf'; // BOLD FONT
$x = imagettftext($im, 20, 0, $x[2], 20, imagecolorallocate($im, $color[0], $color[1], $color[2]), $font, str_replace(array("<b>","</b>"), "", $word));
}
else
{
$font = 'arial.ttf'; // NORMAL FONT
$x = imagettftext($im, 20, 0, $x[2], 20, imagecolorallocate($im, $color[0], $color[1], $color[2]), $font, $word);
}
$addSpace = 1;
}
imagepng($im);
imagedestroy($im);
function RgbfromHex($hexValue) {
if(strlen(trim($hexValue))==6) {
return array(
hexdec(substr($hexValue,0,2)), // R
hexdec(substr($hexValue,2,2)), // G
hexdec(substr($hexValue,4,2)) // B
);
}
else return array(0, 0, 0);
}
?>
Note: This will only work for "bolding" single words separated by spaces and not for bolding part of a word.
Call the script with file.php?text=testing+<b>script</b>&color=000000
you will need to load an arial-bold font file, and do two separate imagettftext() calls, one with each font you want to use. as for parsing the string to find out which parts you would like to be bold, and where you should print each section of text, this sounds like it will become very complicated code. what are you even using this for? there may be better solutions for accomplishing the same thing.
Addition
Use the return value from the imagettftext() function to determine where the next text print should start.
From documentation:
Returns an array with 8 elements representing four points making the bounding box of the text. The order of the points is lower left, lower right, upper right, upper left. The points are relative to the text regardless of the angle, so "upper left" means in the top left-hand corner when you see the text horizontally. Returns FALSE on error.
Response for:
The parsing wouldn't be a problem, what I don't have clear is how I would find the X position for the second wordr in the example ?text=testing script. I mean how do I know where the first word ends so I can place the second one there with another imagettftext() and a bold font. – Meredith Jan 9 '11 at 2:43
funny how someone took the time to say "see edits for the answer to that" when they coulda just said to explode the string at the spaces, then each word is in an array..
<?PHP
$sentence = "I LOVE giving retarded answers that don't amount to jack!";
$sentence = explode(" ",$sentence );
for($s=0;$s<count($sentence);$s++){
#THERES YOUR INDIVIDUAL WORDS!
$word = $sentence[$s];
}
?>
Your X position would be simply $s for your logic. To get the second word you can do this:
<?PHP
$word1 = $sentence[0];
$word2 = $sentence[1];
$word3 = $sentence[2];
$word4 = $sentence[3];
?>
Yes, i named the $words just for a mental visual effect.
$sentence[1] would be word 2