Forum Moderators: coopster
I would like to implement a section of this text wrap function inside the above codes loop.
<?php
function make_wrapped_txt($txt, $color = 000000, $space = 4, $font = 4, $w = 300)
{
if (strlen($color) != 6)
$color = 000000;
$int = hexdec($color);
$h = imagefontheight($font);
$fw = imagefontwidth($font);
$txt = explode("\n", wordwrap($txt, ($w / $fw), "\n"));
$lines = count($txt);
$im = imagecreate($w, (($h * $lines) + ($lines * $space)));
$bg = imagecolorallocate($im, 255, 255, 255);
$color = imagecolorallocate($im, 0xFF & ($int >> 0x10), 0xFF & ($int >> 0x8),
0xFF & $int);
$y = 0;
foreach ($txt as $text)
{
$x = (($w - ($fw * strlen($text))) / 2);
imagestring($im, $font, $x, $y, $text, $color);
$y += ($h + $space);
}
header('Content-type: image/jpeg');
die(imagejpeg($im));
}
?> Here is the modified version of the code that works for me based on the post I found in the forum here. THANKS AGAIN!
(sorry so verbose, still learning gd)
<?php
header("Content-type: image/png"); $imgHgt = 300;
$imgWidth= 400;
/*$imgColorHex="487239";*/
$txt1 = $_GET['text1'];
$txt2 = $_GET['text2'];
$txt3 = $_GET['text3'];
$txt4 = $_GET['text4'];
$txt5 = $_GET['text5'];
$txt6 = $_GET['text6'];
$txt = array($txt1,$txt2,$txt3,$txt4,$txt5,$txt6);
$fntSize = array(18,14,12,10,12,24);
$fntHex = array('00FF00','FFFFFF','000000','00FF00','ff00ff','ff0000');
$fntShad = array(1,0,0,0,0,0);
putenv('GDFONTPATH=' . realpath('.'));
$fnt = array('arial','arialbd','verdana','verdanab','verdanab','verdanab');
// Fonts are in the same directory as the script //
// Yes, I will make the arrays properly in the end //
/* eg foreach($_GET as $keyname => $value) { or sim */
// may also just make a function out of it all and call it //
// from the PERL script I made that parses the form data. //
/*did not need $font = "arial"; */
/*did not need $background = @imagecreate($imgWidth, $imgHgt) or die("Cannot Initialize new GD image stream"); */
/* did not need $background_color = imagecolorallocate($background, 0, 0, 254); */
$background = imagecreatefrompng("image/blank.png");
$t = count($txt);
$totY = 5;
$i = 0;
while ($i < $t)
{
if($fntShad[$i] == 1)
{
$bbox = imageftbbox($fntSize[$i], 0, $fnt[$i], $txt[$i], array("linespacing" => 1));
$width = abs($bbox[0]) + abs($bbox[2]);
$height = abs($bbox) + abs($bbox[5]);
$xcoord = (($imgWidth - $width) / 2) + 2;
$ycoord = $height + $totY + 2;
$int = hexdec("000000");
$arr = array("red" => 0xFF & ($int >> 0x10),
"green" => 0xFF & ($int >> 0x8),
"blue" => 0xFF & $int);
$tcolor = ImageColorAllocate($background, $arr["red"], $arr["green"], $arr["blue"]);
imagettftext($background, $fntSize[$i], 0, $xcoord, $ycoord, $tcolor, $fnt[$i], $txt[$i]);
$totY = $ycoord + 5;
$i++;
}
else
{
$bbox = imageftbbox($fntSize[$i], 0, $fnt[$i], $txt[$i], array("linespacing" => 1));
$width = abs($bbox[0]) + abs($bbox[2]);
$height = abs($bbox[1]) + abs($bbox[5]);
$xcoord = (($imgWidth - $width) / 2) + 2;
$ycoord = $height + $totY + 2;
$int = hexdec($fntHex[$i]);
$arr = array("red" => 0xFF & ($int >> 0x10),
"green" => 0xFF & ($int >> 0x8),
"blue" => 0xFF & $int);
$tcolor = ImageColorAllocate($background, $arr["red"], $arr["green"], $arr["blue"]);
imagettftext($background, $fntSize[$i], 0, $xcoord, $ycoord, $tcolor, $fnt[$i], $txt[$i]);
$totY = $ycoord + 5;
$i++;
}
}
imagepng($background);
ImageDestroy($background);
}
?>
All help / suggetion is appreciated... Don't worry about the shaded font part of the loop, just one section and I can take it from there. I think..
Thanks for any assistance...
Here is another snippet of cod I found that I will be using for a reference.
<?php
//the width of the biggest char @
$fontwidth = 11;//each chargroup has char-ords that have the same proportional displaying width
$chargroup[0] = array(64);
$chargroup[1] = array(37,87,119);
$chargroup[2] = array(65,71,77,79,81,86,89,109);
$chargroup[3] = array(38,66,67,68,72,75,78,82,83,85,88,90);
$chargroup[4] = array(35,36,43,48,49,50,51,52,53,54,55,56,57,60,61,62,63, 69,70,76,80,84,95,97,98,99,100,101,103,104,110,111,112, 113,115,117,118,120,121,122,126);
$chargroup[5] = array(74,94,107);
$chargroup[6] = array(34,40,41,42,45,96,102,114,123,125);
$chargroup[7] = array(44,46,47,58,59,91,92,93,116);
$chargroup[8] = array(33,39,73,105,106,108,124);
//how the displaying width are compared to the biggest char width
$chargroup_relwidth[0] = 1; //is char @
$chargroup_relwidth[1] = 0.909413854;
$chargroup_relwidth[2] = 0.728241563;
$chargroup_relwidth[3] = 0.637655417;
$chargroup_relwidth[4] = 0.547069272;
$chargroup_relwidth[5] = 0.456483126;
$chargroup_relwidth[6] = 0.36589698;
$chargroup_relwidth[7] = 0.275310835;
$chargroup_relwidth[8] = 0.184724689;
//build fast array
$char_relwidth = null;
for ($i=0;$i<count($chargroup);$i++){
for ($j=0;$j<count($chargroup[$i]);$j++){
$char_relwidth[$chargroup[$i][$j]] = $chargroup_relwidth[$i];
}
}
//get the display width (in pixels) of a string
function get_str_width($str){
global $fontwidth,$char_relwidth;
$result = 0;
for ($i=0;$i<strlen($str);$i++){
$result += $char_relwidth[ord($str[$i])];
}
$result = $result * $fontwidth;
return $result;
}
//truncates a string at a certain displaying pixel width
function truncate_str_at_width($str, $width, $trunstr='...'){
global $fontwidth,$char_relwidth;
$trunstr_width = get_str_width($trunstr);
$width -= $trunstr_width;
$width = $width/$fontwidth;
$w = 0;
for ($i=0;$i<strlen($str);$i++){
$w += $char_relwidth[ord($str[$i])];
if ($w > $width)
break;
}
$result = substr($str,0,$i).$trunstr;
return $result;
}
?>
I know I am close to being able to determine the width of the text image based on the font used and breaking it into two strings at a whitespace, then remove that whitespace. Even if I must hard code all the font size vars.
Please help! I am stuck!
<?php
header("Content-type: image/png");
$imgHgt = 300;
$imgWidth= 400;
$txt1 = $_GET['text1'];
$txt2 = $_GET['text2'];
$txt3 = $_GET['text3'];
$txt4 = $_GET['text4'];
$txt5 = $_GET['text5'];
$txt6 = $_GET['text6'];
$txt = array($txt1,$txt2,$txt3,$txt4,$txt5,$txt6);
$fntSize = array(18,14,12,10,12,24);
$fntHex = array('00FF00','FFFFFF','000000','00FF00','ff00ff','ff0000');
putenv('GDFONTPATH=' . realpath('.'));
$fnt = array('arial','arialbd','verdana','verdanab','verdanab','verdanab');
$background = imagecreatefrompng("images/blank.png");
$t = count($txt);
$totY = 5;
$i = 0;
while ($i < $t) {
$bbox = imageftbbox($fntSize[$i], 0, $fnt[$i], $txt[$i], array("linespacing" => 1));
$width = abs($bbox[0]) + abs($bbox[2]);
$height = abs($bbox[1]) + abs($bbox[5]);
$xcoord = (($imgWidth - $width) / 2) + 2;
$ycoord = $height + $totY + 2;
$int = hexdec($fntHex[$i]);
$arr = array("red" => 0xFF & ($int >> 0x10),
"green" => 0xFF & ($int >> 0x8),
"blue" => 0xFF & $int);
$tcolor = ImageColorAllocate($background, $arr["red"], $arr["green"], $arr["blue"]);
//WOULD I CALL IT HERE?
make_wrapped_txt($txt[$i], $color = $fntHex[$i], $space = 4, $font = $fnt[$i], $w = 380);
//Then do I do with the below line?
imagettftext($background, $fntSize[$i], 0, $xcoord, $ycoord, $tcolor, $fnt[$i], $txt[$i]);
$totY = $ycoord + 5;
$i++;
}
imagepng($background);
ImageDestroy($background);
function make_wrapped_txt($txt, $color = 000000, $space = 4, $font = 4, $w = 300)
{
if (strlen($color) != 6)
$color = 000000;
$int = hexdec($color);
$h = imagefontheight($font);
$fw = imagefontwidth($font);
$txt = explode("\n", wordwrap($txt, ($w / $fw), "\n"));
$lines = count($txt);
$im = imagecreate($w, (($h * $lines) + ($lines * $space)));
$bg = imagecolorallocate($im, 255, 255, 255);
$color = imagecolorallocate($im, 0xFF & ($int >> 0x10), 0xFF & ($int >> 0x8),
0xFF & $int);
$y = 0;
foreach ($txt as $text)
{
$x = (($w - ($fw * strlen($text))) / 2);
imagestring($im, $font, $x, $y, $text, $color);
$y += ($h + $space);
}
//I get rid of these last two?
header('Content-type: image/jpeg');
die(imagejpeg($im));
}
?>
Please help!
Instead of trying to figure out GD with this old a$$ brain, I attempted to just attack it another way.
I decided to try and multiply the character size by the amount of characters to determine the strings length on my own. Instead of hacking up others code, figure it out myself. Then I thought what the heck, now I would need to split it on whitespace, calculate length again and so on. No dice. What if there was no whitespace or other delimiter?
So, I figured I should add up the characters (multiplied by size) until I reached the max width $var up to each whitespace then split. But, if no (white)space delimiter, split at the max set width $var as a last resort.
Then, for each new string created, send it through the GD loop.
(The height is not a problem, the page that sends over the variables displays an html preview of what the generated image should resemble.)
Great right? Sounds feasible! Maybe for someone else, not me. I got as far as:
<?php
header("Content-type: image/png"); $imgHgt = 300;
$imgWidth= 400;
/*$imgColorHex="487239";*/
$txt1 = $_GET['text1'];
$txt2 = $_GET['text2'];
$txt3 = $_GET['text3'];
$txt4 = $_GET['text4'];
$txt5 = $_GET['text5'];
$txt6 = $_GET['text6'];
$txt = array($txt1,$txt2,$txt3,$txt4,$txt5,$txt6);
$fntSize = array(18,14,12,10,12,24);
$fntHex = array('00FF00','FFFFFF','000000','00FF00','ff00ff','ff0000');
$fntShad = array(1,0,0,0,0,0);
putenv('GDFONTPATH=' . realpath('.'));
$fnt = array('arial','arialbd','verdana','verdanab','verdanab','verdanab');
/*$font = "arial"; */
/*$background = @imagecreate($imgWidth, $imgHgt) or die("Cannot Initialize new GD image stream"); */
/*$background_color = imagecolorallocate($background, 0, 0, 254); */
$background = imagecreatefrompng("images/blank.png");
$t = count($txt);
$totY = 5;
$i = 0;
while ($i < $t) {
$charcount = strlen($txt[$i]);
$sentencewidth = ($charcount * $fntSize[$i]);
if ($sentencewidth > 380) {
/// ARRRGHHH //// I HATE BEING STUPID /////
}
$bbox = imageftbbox($fntSize[$i], 0, $fnt[$i], $txt[$i], array("linespacing" => 1));
$width = abs($bbox[0]) + abs($bbox[2]);
$height = abs($bbox[1]) + abs($bbox[5]);
$xcoord = (($imgWidth - $width) / 2) + 2;
$ycoord = $height + $totY + 2;
$int = hexdec($fntHex[$i]);
$arr = array("red" => 0xFF & ($int >> 0x10),
"green" => 0xFF & ($int >> 0x8),
"blue" => 0xFF & $int);
$tcolor = ImageColorAllocate($background, $arr["red"], $arr["green"], $arr["blue"]);
imagettftext($background, $fntSize[$i], 0, $xcoord, $ycoord, $tcolor, $fnt[$i], $txt[$i]);
$totY = $ycoord + 5;
$i++;
}
imagepng($background);
ImageDestroy($background);
}
?>
I just want our car club members to be able to lay lines of text over an image. I do all this, including the sites hosting, for free. It's a family thing. But, three whole days of trying to figure this out if getting ridiculous!
My attempts using the wrap in gd forced me to create a new "transparent" bounding box and jump through a bunch of other hoops to get it into position and so on...
My solution was crude but, quite effective:
As gd processed the string with the font size already set, I grabbed the $w and $h of the string.
If the string was greater than my max width $var, I counted characters in the string and with a little division I determined how many characters would fit into the max width. Then foreach split on whitespace before that count if it was not already whitespace. Works for my app.
The downfall with my code would be if there was no whitespace in the string or if the whitespace was part of something like a phone number or time. No biggie for my app though and I could solve all that if I wanted to. Since there is an html preview page that points those issues out. Would have to be done intentionally so, GIGO is their prob.
When done, I will post in the proper PERL area of this forum. I should always just stick with PERL, I would have been done a week ago. Really so much better than PHP, for me...