php gd text break on image - php

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

Related

How to only horizontally align text on image in php gd library

I'm trying to only horizontally align text on an image in php gd library like you'd do with "text-align: center" so the text isn't going out of the image if it's too large.
<?php
// (A) OPEN IMAGE
$img = imagecreatefrompng('LOGO.PNG');
// (B) WRITE TEXT
$txt = "Divine Magnificent Endurance";
$font = "C:/xampp/htdocs/testImages/ArialCE.ttf";
$white = imagecolorallocate($img, 0, 0, 0);
$width = imagesx($img);
$height = imagesy($img);
$text_size = imagettfbbox(24, 0, $font, $txt);
$text_width = max([$text_size[2], $text_size[4]]) - min([$text_size[0], $text_size[6]]);
$text_height = max([$text_size[5], $text_size[7]]) - min([$text_size[1], $text_size[3]]);
$centerX = CEIL(($width - $text_width) / 2);
$centerX = $centerX<0 ? 0 : $centerX;
$centerY = CEIL(($height - $text_height) / 1.3);
$centerY = $centerY<0 ? 0 : $centerY;
imagettftext($img, 18, 0, $centerX, $centerY, $white, $font, $txt);
imagesavealpha($img, true);
// (C) OUTPUT IMAGE
header('Content-type: image/png');
imagepng($img);
imagedestroy($img);
I had to implement a similar functionality when generating avatars, I solved that by grabbing the third and sixth value of imagettfbbox, that is the lower right corner in the X position and the upper right in the Y position, having those I subtract that from the image height and width, then divide that value in half, round up and grab the absolute value, and those will be my x and y coordinates.
I played around with which values and math operations would produce the best results and this gave me the desired centering.
$centerY = abs(ceil(($height - $text_size[5]) / 2));
$centerX = abs(ceil(($width - $text_size[2]) / 2));
I wrote a post about it on my Dev account that could be of use. I hope that gives you some help in the right direction.

Right allignment of text in imagettftext function

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.

can some help me work this out

Here is my site. I'm trying to make its own testing URL for the moment:
http://boats.instantonlinesuccess.co.uk/boat-names.html
If you look at it you can see what I am trying to do. I'm trying to link the JavaScript to my PHP, so the writing appears with the effects / effect colours / colours. It's all generated via a PHP script which I'm trying to write.
Here is my PHP:
<?php header("Content-type: image/png");
$string = $_GET['text'];
$currentFont =$_GET['font'];
$currentTextColour = $_GET['colour'];
$currentEffect = $_GET['effect'];
$currentEffectColour = $_GET['effectcolour'];
$im = imagecreatefrompng("images/test.png");
$px = (imagesx($im) - 7.5 * strlen($string)) / 2;
//if you exactly know the RGB color indexes//
$rgb = imagecolorexact($im, 0, 0, 0);
//or keep the rgb color by position so at top 0 left 0
$rgb = imagecolorat($im, 0, 0);
imagecolortransparent($im, $rgb);
imagestring($im, 64, $px, 16, $string, $currentTextColour);
imagepng($im); imagedestroy($im);
?>
If you need the JavaScript, then let me know.
You could try changing your first line to this to debug the issue:
header('Content-Type: text/plain');

Using PHP GD to create image form text with different fonts

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

wrap and center text in gd and php

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

Categories