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);
Related
Hope you are doing great.
I’m still a newbie with php so after making some reading and while checking some posts here I was able to put some text over an image with the imagecreatefrompng() function using the PHP GD, users will come to a form and they will be able to enter their name and the name will be written over the image , unfortunately I have been unable to align the text center horizontally, I tried all ways possible (my ways obviously and must be wrong) with imagettfbbox but I failed in all my attempts, could you please guys help me out a little bit to align the string center horizontally? Also since I’m using a kind of alternative big font I need that the size decrease if the name entered is kind of long so this way it will not surpass the image limits and will stay at the center. I’m getting the value of the text from a form as you may check at the beginning of my code:
<?php
$nombre=$_POST['nombre'];
//Set the Content Type
header('Content-type: image/jpeg');
// Create Image From Existing File
$jpg_image = imagecreatefromjpeg('fabian.jpg');
// Allocate A Color For The Text
$white = imagecolorallocate($jpg_image, 255, 255, 255);
// Set Path to Font File
$font_path = 'fabian.TTF';
// Set Text to Be Printed On Image , I set it to uppercase
$text =strtoupper($nombre);
// Print Text On Image
imagettftext($jpg_image, 75, 0, 50, 400, $white, $font_path, $text);
// Send Image to Browser
imagepng($jpg_image);
// Clear Memory
imagedestroy($jpg_image);
?>
Your help will be highly appreciated, later on I will break my head trying to save the image by clicking a submit button since I do not want the users to save the image by right clicking on it.
Thanks pals!
You need the width of the image and the width of the text to relate both.
// get image dimensions
list($img_width, $img_height,,) = getimagesize("fabian.jpg");
// find font-size for $txt_width = 80% of $img_width...
$font_size = 1;
$txt_max_width = intval(0.8 * $img_width);
do {
$font_size++;
$p = imagettfbbox($font_size, 0, $font_path, $text);
$txt_width = $p[2] - $p[0];
// $txt_height=$p[1]-$p[7]; // just in case you need it
} while ($txt_width <= $txt_max_width);
// now center the text
$y = $img_height * 0.9; // baseline of text at 90% of $img_height
$x = ($img_width - $txt_width) / 2;
imagettftext($jpg_image, $font_size, 0, $x, $y, $white, $font_path, $text);
You can use stil/gd-text class to align the text. Disclaimer: I am the author.
<?php
use GDText\Box;
use GDText\Color;
$jpg_image = imagecreatefromjpeg('fabian.jpg');
$textbox = new Box($jpg_image);
$textbox->setFontSize(75);
$textbox->setFontFace('fabian.TTF');
$textbox->setFontColor(new Color(255, 255, 255));
$textbox->setBox(
50, // distance from left edge
50, // distance from top edge
200, // textbox width
100 // textbox height
);
// text will be aligned inside textbox to center horizontally and to top vertically
$textbox->setTextAlign('center', 'top');
$textbox->draw(strtoupper($nombre));
However it is not a complete answer, because it can't decrease font size automatically.
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'm adding annotation text to a newPseudoImage which works fine but I'd like to make the text scale to fit the image size.
Any ideas how I might do this?
$im = new Imagick();
$draw = new ImagickDraw();
$draw->setFillColor($color);
$draw->setFont($font);
$draw->setFontSize(($width, $height) / 100) * 15);
$draw->setGravity(Imagick::GRAVITY_CENTER);
$im->newPseudoImage($width, $height, "canvas:{$bg}");
$im->annotateImage($draw, 0, 0, 0, $text);
$draw->clear();
$draw->destroy();
$im->setImageFormat('gif');
header("Content-Type: image/gif");
echo $im;
I think you could use the imageftbbox function to help you out.
This will give you the bounding box for a text string, with the given ttf font, size, and angle.
You could create a loop to increase or decrease the font size as long as the text is not fitting the image properly.
<?php
$bbox = imageftbbox(12, 0, 'Arial.ttf', 'This is a test');
$width_of_text = $bbox[2] - $bbox[0];
You could look at the $width_of_text and adjust the font size as long as the font isn't scaled to your liking. Keep in mind, as you increase the font, the width and height will grow.
Depending on what you are trying to scale it to that may help.
I'm facing the same issue and although I've not tried this yet as I'm away from my machine, I'm going to give this a go.
Using the query font metrics function of the class I will be able to get the calculated width of the text and then compare it with the specified width of its container. I'll make adjustments to the font size and repeat until its near enough. You could get it quite accurate this way but bare in mind possible performance issues if you have multiple text items in the image.
On the other hand, if you weren't concerned about styling the text as much you could use caption.
This is a slightly naive solution (I could have used binary search to find the proper font size) , but it works for me.
In my example I want to place text on a box in the image, so I calculate the proper font size with imageftbbox.
$size = $MAX_FONT_SIZE;
while (true){
$bbox = imageftbbox($size, 0, $font, $text );
$width_of_text = $bbox[2] - $bbox[0];
if ($width_of_text > $MAX_TEXT_WIDTH) {
$size -= 1;
}
else {
break;
}
}
$height_of_text = ($bbox[3] - $bbox[1]);
$draw->setFontSize( $size );
$image->annotateImage($draw, $TEXT_WIDTH_CENTER - $width_of_text/2, $TEXT_HEIGHT_CENTER - $height_of_text/2, 0, $text);
I am writing to print text to an image using PHP. However, the function imagettftext() uses the baseline, whereas I need the text vertically centered.
So, I either need a method to print text with y not the distance from top to baseline, but from top to top of bounding box OR I need a method using which I could determine the distance between top of bounding box and baseline.
Apparently, I am confusing you. So, to make it clear: I am aware of the function imagettfbbox(). Using that function I can determine height and width of resulting text box. Its height, however, is utterly useless for vertical alignment when printing with imagettftext(), because the Y parameter is not the distance to the top of the box (or even the bottom, but at least something I could have used having the height) but the distance to the baseline of the text within.
EDIT: Why am I not accepting the latest answer?
See my latest comment below the answer, and use this image as a reference.
I do not know if the answer still interested.However, the imagettfbbox() function give you more information than simply the height and the width of the bounding box. It's designed exactly to return information needed by the imagettftext() to manage the text as you want.
The trick lies in the fact that the coordinates returned from imagettfbbox() are not related to the absolute top left corner, but to the baseline of the font for the particular text. This is the reason because the box is specified in point coordinates, and these are often negative.
In short:
$dims = imagettfbbox($fontsize, 0, $font, $text);
$ascent = abs($dims[7]);
$descent = abs($dims[1]);
$width = abs($dims[0])+abs($dims[2]);
$height = $ascent+$descent;
...
// In the example code, for the vertical centering of the text, consider
// the simple following formula
$y = (($imageHeight/2) - ($height/2)) + $ascent;
This works perfectly for my projects.
Hope this help.
Sorry for english.
Marco.
Not entirely sure what your asking...can you give an example? Perhaps imagettfbbox is what you need?
// get bounding box dims
$dims = imagettfbbox($fontsize, 0, $font, $quote);
// do some math to find out the actual width and height
$width = $dims[4] - $dims[6]; // upper-right x minus upper-left x
$height = $dims[3] - $dims[5]; // lower-right y minus upper-right y
edit: Here is an example of vertically centered text
<?php
$font = 'arial.ttf';
$fontsize = 100;
$imageX = 500;
$imageY = 500;
// text
$text = "FOOBAR";
// create a bounding box for the text
$dims = imagettfbbox($fontsize, 0, $font, $text);
// height of bounding box (your text)
$bbox_height = $dims[3] - $dims[5]; // lower-right y minus upper-right y
// Create image
$image = imagecreatetruecolor($imageX,$imageY);
// background color
$bgcolor = imagecolorallocate($image, 0, 0, 0);
// text color
$fontcolor = imagecolorallocate($image, 255, 255, 255);
// fill in the background with the background color
imagefilledrectangle($image, 0, 0, $imageX, $imageY, $bgcolor);
$x = 0;
$y = (($imageY/2) - ($bbox_height/2)) + $fontsize;
imagettftext($image, $fontsize, 0, $x, $y , $fontcolor, $font, $text);
// tell the browser that the content is an image
header('Content-type: image/png');
// output image to the browser
imagepng($image);
// delete the image resource
imagedestroy($image);
?>
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);