Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Chris Miller on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Spacing and Aligning Text

Status
Not open for further replies.

PCHomepage

Programmer
Feb 24, 2009
609
US
I created a simple function to take text and create an image from it and it working but I've not been able to work out how to set the spacing between the lines (if there is more than one) and right now they are too far apart. If more than one line, the width of each varies and I would like them to be centered with each other but cannot work out how to even begin to do that! Any ideas on these things?

PHP:
function textimage($string, $size, $FontName, $CenterAlign=false) {

	$FontPath = $_SERVER['DOCUMENT_ROOT'] . "/functions/truetype/";
	$font = $FontPath . $FontName;
	$stringbase = "Copyright © ". date("Y");

	if ($CenterAlign === true):
		$string = html_entity_decode($stringbase ."\n". $string);
		$text_dimensions = imagettfbbox($size,0,$font,$string);
		// Some code here
	else:
		$text_dimensions = imagettfbbox($size,0,$font,$string);
	endif;

	$width = abs($text_dimensions[4] - $text_dimensions[0] + 5);
	$height = abs($text_dimensions[5] - $text_dimensions[1]);

	$x_offset = ($width / 2) - ((min($text_dimensions[2],$text_dimensions[4]) - max($text_dimensions[0],$text_dimensions[6])) / 2);
	$y_offset = abs($text_dimensions[5]);
	$image = imagecreatetruecolor($width,$height);
	$background_color = imagecolorallocate($image,0xEE,0xEE,0xEE);

	$text_color = imagecolorallocate($image,0x00,0x00,0x55);
	$shadow_color = imagecolorallocate($image,0x77,0x77,0x77);
	imagefill($image,0,0,$background_color);
	$lines = explode('\n',$string);
	foreach ($lines as $line):
		imagettftext($image,$size,0,$x_offset,$y_offset,$text_color,$font,$line);
		$y_offset += 10;
	endforeach;

	header("Content-Type: image/png");
	header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
	header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past

	return imagepng($image);
	imagedestroy($image);
}

echo textimage("More Text Here", 10, "vineritc.ttf", true);
 
I forgot to say that this must be done using the GD library as ImageMagick is not available.
 
do you mean that you want to make the line closer together? if so, why not decrease the value of 10?
 
Yes, that's what I meant but they remain the same regardless of the value. The remain exactly as they were before I added the bit of code to set the spacing.
 
I found the problem with the line spacing. This:

PHP:
$lines = explode([COLOR=blue]'\n'[/color],$string);

should be this (double quotes):

PHP:
[code=PHP]$lines = explode([COLOR=blue]"\n"[/color],$string);

That being fixed, any ideas on how to center the lines? If centering isn't possible, right-aligning will be okay.
 
In my old age, it took a while but I finally figured it out. Note that most of the variable names have changed since my original posting. It probably needs a bit of cleaning up as there are likely still some lines of code that are no longer being used or that are redundant:

PHP:
function textimage($String,$FontName,$FontSize,$EnableShadow=TRUE,$CenterAlign=TRUE) {
	global $Height;
	$FontPath = $_SERVER['DOCUMENT_ROOT'] . "/functions/truetype/";
	$Font = $FontPath . $FontName;
	$String = html_entity_decode($String);
	$TextDimensions = imagettfbbox($FontSize,0,$Font,$String);
	$Width = abs($TextDimensions[4] - $TextDimensions[0] + 5);
	$Height = abs($TextDimensions[5] - $TextDimensions[1]);
	$y_offset = abs($TextDimensions[5]);
	$Image = imagecreatetruecolor($Width,$Height);
	$BGColor = imagecolorallocate($Image,0xEE,0xEE,0xEE);
	$TextColor = imagecolorallocate($Image,0x00,0x00,0x55);
	$ShadowColor = imagecolorallocate($Image,0x77,0x77,0x77);
	imagefill($Image,0,0,$BGColor);
	$Lines = explode("\n",$String);
	foreach ($Lines as $Line):
		if ($EnableShadow === TRUE):
			if ($CenterAlign === TRUE):			
				$x_offset = CenterText($FontSize,$Font,$Line,$Width);
			else:
				$x_offset = ($Width / 2) - ((min($TextDimensions[2],$TextDimensions[4]) - max($TextDimensions[0],$TextDimensions[6])) / 2);
			endif;
			imagettftext($Image,$FontSize,0,$x_offset+2,$y_offset+2,$ShadowColor,$Font,$Line);
			imagettftext($Image,$FontSize,0,$x_offset,$y_offset,$TextColor,$Font,$Line);
		else:
			if ($CenterAlign === TRUE):			
				$x_offset = CenterText($FontSize,$Font,$Line,$Width);
			else:
				$x_offset = ($Width / 2) - ((min($TextDimensions[2],$TextDimensions[4]) - max($TextDimensions[0],$TextDimensions[6])) / 2);
			endif;
			imagettftext($Image,$FontSize,0,$x_offset,$y_offset,$TextColor,$Font,$Line);
		endif;
		$y_offset += $FontSize * 1.8;
	endforeach;

	header("Content-Type: image/png");
	header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
	header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past

	return imagepng($Image);
	//return $x_offset;
	imagedestroy($Image);
}

This handles the centering:

PHP:
function CenterText($FontSize,$Font,$String,$BoxWidth) {
	$TextDimensions = imagettfbbox($FontSize,0,$Font,$String);
    $xi = abs($TextDimensions[4]);
    $x = intval(($BoxWidth - $xi) / 2);
    return $x;
}

. . . and right now it is called like this but I'll be changing it to work as a standard image:

PHP:
echo textimage("Copyright © ". date("Y") . "\nMore Text Here", "vineritc.ttf", 9, TRUE, TRUE);

Can anyone think of a way to make the copyright symbol larger? Right now, it is just a tiny dot.
 
yes. a bit odd.

speaking as a copyright lawyer the (c) sigil is a shorthand notation for Copyright. so this
Copyright Justin Adie 2014
is synonymous with
(c) Justin Adie 2014

the important thing is the designation, the copyright holder and the year from which the copyright runs.

there are slight differences in US law in that the US runs a copyright registration system. but I don't believe this undermines the basic principle that (c) and copyright are effectively synonymous/alternatives.
 
I think it can be left as it is but I was also thinking in terms of it being useful for things other than the copyright where I might want to make certain symbols larger.

By the way, on the link above to the sample generated image, I used a third-party function to give it a nice Alpha shadow which simply replaces imagettftext(() in the code I posted.
 
The function is now live on the Web site and I also applied it to some of the other images where it is working fine. I did notice, however, than on larger text-images where it is more noticeable the right side of the drop-shadow is being chopped off so I'll need to add some extra spacing to that side.
 
I just noticed that while it looks good on a PC's Firefox or other browser, the background is noticeably different on an iPad's Safari so I'll need to work out how to give it a transparency. Any ideas would be appreciated!
 
Adding the transparency turned out to be relatively easy by adding:

PHP:
imagesavealpha($Image, TRUE);
$TransColor = imagecolorallocatealpha($Image, 0, 0, 0, 127);
imagefill($Image, 0, 0, $TransColor);

. . . and removing these two lines

PHP:
$BGColor = imagecolorallocate($Image,0xEE,0xEE,0xEE);
imagefill($Image,0,0,$BGColor);

so that you end up with something like this:

PHP:
$Width = abs($TextDimensions[4] - $TextDimensions[0] + 5);
$Height = abs($TextDimensions[5] - $TextDimensions[1]);
$y_offset = abs($TextDimensions[5]);
$Image = imagecreatetruecolor($Width,$Height);
[COLOR=blue]imagesavealpha($Image, TRUE);
$TransColor = imagecolorallocatealpha($Image, 0, 0, 0, 127);
imagefill($Image, 0, 0, $TransColor);[/color]
$TextColor = imagecolorallocate($Image,0x00,0x00,0x55);
$ShadowColor = imagecolorallocate($Image,0x77,0x77,0x77);

To view the image, I created a script that loads in HTML like an image using img src:

PHP:
<?php
header('Content-Type: image/png');
require("image_functions.php");

if (isset($_GET['AuthorName'])):
	$Year = date("Y");
	$AuthorName = str_replace("and","&",urldecode($_GET['AuthorName']));
	$String = "Copyright &copy; $Year\n$AuthorName";
	$Size = 10;
	$Angle = 0;
elseif (isset($_GET['Category'])):
	$String = urldecode($_GET['Category']);
	$Size = 15;
	$Angle = 0;
elseif (isset($_GET["Home"])):
	[COLOR=red]//$String = $_GET["Home"];[/color]
	[COLOR=blue]$String = "Welcome to"."\nSite Name";[/color]
	$Size = 28;
	$Angle = 0;
else:
	$String = "Copyright &copy; Author Name";
	$Size = 10;
	$Angle = 0;
endif;

echo textimage($String, "vineritc.ttf", $Size, $Angle, TRUE, TRUE);

?>

A question, though. When I pass a string to the script a line with \n in it, it prints the \n to the image and does not wrap. Even when I give it the string hard-coded as a value of $String it does the same thing unless I concatenate it at the line break. See the red and blue lines above: the unremarked bloe line works, the remarked red one does not. Is there a workaround for this behavior so that the \n gets done, rather than just presented to the screen as-is?
 
I meant to say that neither of these work (with or without spaces around \n):

PHP:
[COLOR=red]//$String = $_GET["Home"];
//$String = "Welcome to\nSite Name";[/color]
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top