Centering 2 lines of text, X and Y

GD and GD2 are useful libraries for creating graphics on-the-fly. Discuss your PHP GD and GD2 scripts here.

Moderators: onion2k, General Moderators

Post Reply
WDUK
Forum Newbie
Posts: 2
Joined: Sun Aug 20, 2006 5:47 pm

Centering 2 lines of text, X and Y

Post by WDUK »

Hey,
I'm trying to create an adult swim image generator (you know the black screen with white text, very simple).
I thought of doing this as an introduction to PHP GD.

Now I need the main text centered, and I can do this fine with 1 line of text, that's no problem.
It's when there are 2 lines of text it gets a bit tricky, it doesn't properly centre.
I've tried various things, but due to inexperience with PHP, they havn't been sucsessful, and I've nearly give up. Plus I know I've screwed up my maths somewhere.

Here is what I have so far, and I've marked with comments the section I am having trouble with

Code: Select all

<?php

//Define Basics
$image = ImageCreate(800,600);
$text1 = "Welcome to [adult swim]";
$text2 = "Testing centering for 2 lines";
$subtext = "[adult swim]";
$font = "adultswim.ttf";
$size = 30;
$subsize = 15;
$black = ImageColorAllocate($image, 0, 0, 0);
$white = ImageColorAllocate($image, 255, 255, 255);
$suby = 550;
$angle = 0;

//See if it's 2 lines instead of 1
if($text2 == ""){

	//Function to determine centre for 1 line
	function pc_ImageTTFCenter($image, $text1, $font, $size) {

	    // find the size of the image
	    $xi = ImageSX($image);
	    $yi = ImageSY($image);

	    // find the size of the text
	    $box = ImageTTFBBox($size, $angle, $font, $text1);

	    $xr = abs(max($box[2], $box[4]));
	    $yr = abs(max($box[1], $box[3]));

 	   // compute centering
	    $x = intval(($xi - $xr) / 2);
	    $y = intval(($yi + $yr) / 2);

	    return array($x, $y);
}

//Create 1 lined text
list($x, $y) = pc_ImageTTFCenter($image, $text1, $font, $size);
ImageTTFText($image, $size, $angle, $x, $y, $white, $font, $text1);

}

else {
  
//WHERE PROBLEM STARTS =(

	//Function to determine centre for 2 lines
	//Line 1 Centre
	function pc_ImageTTFCenter1($image, $text1, $font, $size) {

	    // find the size of the image
	    $xi1 = ImageSX($image);
	    $yi1 = ImageSY($image);

	    // find the size of the text
		$box1 = ImageTTFBBox($size, $angle, $font, $text1);

	    $xr1 = abs(max($box1[2], $box1[4]));
	    $yr1 = abs(max($box1[1], $box1[3]));

 	   // compute centering
	    $x1 = intval(($xi1 - $xr1) / 2);
	    $y1 = intval(($yi1 + $yr1) / 2);

	    return array($x1, $y1);
}
	//Line 2 Centre
	function pc_ImageTTFCenter2($image, $text2, $font, $size) {

	    // find the size of the image
	    $xi2 = ImageSX($image);
	    $yi2 = ImageSY($image);

	    // find the size of the text
		$box2 = ImageTTFBBox($size, $angle, $font, $text2);

	    $xr2 = abs(max($box2[2], $box2[4]));
	    $yr2 = abs(max($box2[1], $box2[3]));

 	   // compute centering
	    $x2 = intval(($xi2 - $xr2) / 2);
	    $y2 = intval(($yi2 + $yr2) / 2);

	    return array($x2, $y2);
}

	//Find Y position
	function pc_Yalignment($text1, $font, $size, $y1, $y2) {

	    // find the size of the text
		$box3 = ImageTTFBBox($size, $angle, $font, $text1);

	    $yr3 = abs(max($box3[1], $box3[7]));
	    $yalign = intval($yr3 / 2);

 	   // compute centering
	    $y3a = intval($y1 - $yalign);
	    $y3b = intval($y2 + ($yr3 + $yalign));

	    return array($y3a, $y3b);
}

//Create 2 lined text
list($x1) = pc_ImageTTFCenter1($image, $text1, $font, $size);
list($x2) = pc_ImageTTFCenter2($image, $text2, $font, $size);
list($y3a, $y3b) = pc_Yalignment($text1, $font, $size, $y1, $y2);
ImageTTFText($image, $size, $angle, $x1, $y3a, $white, $font, $text1);
ImageTTFText($image, $size, $angle, $x2, $y3b, $white, $font, $text2);

//WHERE PROBLEM ENDS =)

/*Temp error page
echo "<b><font size=10>[sorry folks]</b></font><p>";
echo "Currently only 1 line can be created at this moment in time</br>";
echo "This generator is currently in Alpha stage</br>";
die; */

}

//Align the bottom sub-logo to the right
function pc_ImageTTFAlign($image, $subtext, $font, $subsize) {

    $sbox = ImageTTFBBox($subsize, $angle, $font, $subtext);
    $sxr = max($sbox[0], $sbox[2]);
    $subx = intval(730 - $sxr);

    return array($subx);
}

//Create little logo
list($subx) = pc_ImageTTFAlign($image, $subtext, $font, $subsize);
ImageTTFText($image, $subsize, $angle, $subx, $suby, $white, $font, $subtext);

//Create visible picture
header('Content-type: image/png');
ImagePng($image);

//Remove image from server cache
ImageDestroy($image);
?>
I'm sorry if the coding is a bit sloppy, I've been working off tutorials and the like.
I will eventually develop it so it will accept HTML Form entries, but at the moment, I am trying to sort out the core first.

Your help would be appreciated =)
User avatar
onion2k
Jedi Mod
Posts: 5263
Joined: Tue Dec 21, 2004 5:03 pm
Location: usrlab.com

Post by onion2k »

I'm a bit busy to figure out exactly what your code is doing, but it's an interesting puzzle so I've worked out a solution. Mine works for any number of lines:

Code: Select all

<?php

	$font = "AIRSTREA.TTF";
	$size = 10;
	$angle = 0;
	$arrText[] = "This is line 1";
	$arrText[] = "This is line 2";
	$arrText[] = "This is line 3";
	$arrText[] = "This is line 4";
	$arrText[] = "This is line 5";
	$arrText[] = "This is line 6";
	$arrText[] = "This is line 7";
	$arrText[] = "This is line 8";
	$aggHeight = 0;
	$seperation = 10;

	$image = ImageCreate(800,600); 
	$black = ImageColorAllocate($image, 0, 0, 0);
	$white = ImageColorAllocate($image, 255, 255, 255);

	$ix = imagesx($image);
	$iy = imagesy($image);

	imageline($image,0,$iy/2,$ix,$iy/2,$white); //Draw a line across the middle of the image
	imageline($image,$ix/2,0,$ix/2,$iy,$white); //Draw a line down the centre of the image

	foreach ($arrText as $t) {
		$s = ImageTTFBBox($size, $angle, $font, $t);
		$arrTextSize[$t]['width'] = abs($s[4] - $s[0]); //Get the width
		$arrTextSize[$t]['height'] = abs($s[5] - $s[1]); //Get the height
		$totalHeight += abs($s[5] - $s[1])+$seperation; //Add to the totalHeight
	}
	$totalHeight -= ($seperation/2); // Correct the totalHeight by 1/2 a seperation;

	foreach ($arrTextSize as $t => $data) {

		$x = ($ix - $data['width'])/2; //Width is the width of the image - the width of the line / 2;
		$y = (($iy - $totalHeight)/2) + $data['height'] + $aggHeight; //Height is the height of the image - the height of all the lines / 2 + the height of the line (to correct GD drawing the text from the bottom) + seperator
		$aggHeight += $data['height']+$seperation; //Keep a running total of the heights
	
		ImageTTFText($image, $size, $angle, $x, $y, $white, $font, $t);
		
	}

	header('Content-type: image/png');
	ImagePng($image);

	ImageDestroy($image);

?>
WDUK
Forum Newbie
Posts: 2
Joined: Sun Aug 20, 2006 5:47 pm

Cheers

Post by WDUK »

Aww, cheers, works a charm!
Just adapted it a bit, and works beautifully

Thank you very much
I'll try and study what's going on in the script, and hopefully understand PHP a little more :)
Post Reply