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.
Related
How do I centralize and align text above my main image?
The result of this code is this image:
https://i.imgur.com/Dk5pYJM.jpg
I wish it would look like this:
https://i.imgur.com/mED295l.jpg
but I do not understand much of moving the images and texts.
<?php
$fontname = 'verdana.ttf';
$i = 30;
$quality = 85;
function create_image($user){
global $fontname;
global $quality;
$file = md5($user[1]['text'].rand(30454, 343434)).".jpg";
//if (!file_exists($file)) {
$im = imagecreatefromjpeg("fundo.jpg");
$logo = imagecreatefromjpeg("img.jpeg");
$color['grey'] = imagecolorallocate($im, 255, 255, 255);
$y = imagesy($im) - $height - 365;
$font_size = 25;
$logo_x = imagesx($logo);
$logo_y = imagesy($logo);
foreach ($user as $value){
$x = center_text($value['text'], $font_size);
imagettftext($im, $font_size, 0, $x, $y+$i, $color["grey"], $fontname, $value['text']);
$i = $i+32;
}
imagecopymerge($im, $logo, 37, 370, 0, 0, $logo_x, $logo_y, 100);
imagejpeg($im, $file, $quality);
//}
return $file;
}
function center_text($string, $font_size) {
global $fontname;
$image_width = 720;
$dimensions = imagettfbbox($font_size, 0, $fontname, $string);
return ceil(($image_width - $dimensions[4]) / 2);
}
$user = array(
array('text'=> 'Our adge lacks gravitas. That’s whyaadasdasdasdasdsadasdasdasdas')
);
$filename = create_image($user);
?>
<img src="<?=$filename;?>" /><br/><br/>
Aligning text in an image using PHP's image functions is always a bit of a puzzle.
First, you need to know the x and y coordinates of the point at the bottom center of where the text should go (anchor point). This is probably half the width of the outer image for the x and the y value of the top of the smaller image in the center (minus a margin value) for the y.
After this, you have to calculate where your text has to be put (x and y) so that it will align above the smaller image in the center (centered above the anchor point).
For this you use imagettfbbox to calculate what the bounding box's coordinates will be if the text is put at x=0 y=0. Then you use these values to calculate the coordinates of the bottom center of this bounding box.
$bounding_box = imagettfbbox(......);
/* lower right x - lower left x, divided by 2 */
$relative_x = ( $bounding_box[2] - $bounding_box[0] ) / 2;
/* lower left y */
$relative_y = $bounding_box[1];
Subtracting these relative values from our first calculated anchor point, gives you the coordinates to put the text using imagettftext.
See http://php.net/manual/en/function.imagettfbbox.php for which array value is which coordinate value.
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 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);
I am working on a captcha image type script and I am wanting to alternate each letters color on my image, so far I have it working pretty much except the color values are not what I expected
The colors in this $multi_text_color variable should be the colors that it randomly picks and shows, it does work in randomly picking the color array value
however the colors it is putting on the image are 3 colors no where near to what I want, so am I doing something wrong here?
<?PHP
// note this is just the part I am having trouble with, I have taken everything else out that adds line and tilts the letters and stuff so just the color settings are in this bit
// My this part of my script takes each number/letter in a string and makes it a random color to put on the image
// set color values
$multi_text_color = "#FF3E96,#6A5ACD,#90EE90";
// put colors above into an array
$colors = explode(',', $multi_text_color);
// cycle through everything to add the letters/numbers to image
for($i = 0; $i < $characters; ++$i) {
$idx = rand(0, 2);
// notice my $colors variable has random number for the color array
$r = substr($colors[$idx], 1, 2); // shows: f6 or 8d or FF
$g = substr($colors[$idx], 3, 2); // shows: 3E or 32 or 5c
$b = substr($colors[$idx], 5, 2); // shows: 96 or 47 or fd
$font_color = imagecolorallocate($image, "$r", "$g", "$b");
// finish it up
imagettftext($image, $font_size, $angle, $x, $y, $font_color, $this->font, $code{$i});
}
?>
imagecolorallocate() takes integers as parameters, not stings. Convert $r, $g and $b to integer first using hexdec().
If you are using hex numbers you need to convert them to decimals first.
$font_color = imagecolorallocate($image, hexdec($r), hexdec($g), hexdec($b));