So I am working on a system for work where certificates are automatically generated. I have this working but I want to make it better, instead of a super long case statement that centers the name of the person on the image by absolute positioning I want to make it work automatically. I have thought of a algorithm that will work but I need one part to make it complete. Basically the algorithm works like this:

(Width of Image / 2) - (Width of Name /2) and $xpos = the result.

The code to write the text to the image is:

imagettftext($image, 48, 0, $xpos, 600, $textColor, $font, ucwords(strtolower($Name)));

Is there anyway to find the Width of the Name? I can get the width of the Image but I cannot find the width of the Name. Currently the $xpos is just a defined number. Any help?

Edited by toxicandy

3 Years
Discussion Span
Last Post by cereal

How do I find the width of the string with that though? Do I make it an image and then get the width of that?

How would I structure the algorithm then? I would need to have the size before I input it into the Xpos. The Code you provided, does that allow me to position it to a set position?


Edit: I added an example.

There is a PHP function called ps_stringwidth. It looks promising 'BUT', it needs Adobe font metrics file to calculate the width. Another one is called mb_strwidth. The most feasible usage of mb_strwidth is to calculate the sum of all characters within string. e.g. h e l l o w o r l d is calculated by the characters width and the spaces.

Example imlementation as shown in PHP.net

    $b = "H e l l o  W o r l d";
    printf("length of string: %d \n", mb_strlen($b, 'UTF-8'));
    for ($i=0; $i < mb_strlen($b, 'UTF-8'); $i++){
        $ch = mb_substr($b, $i, 1, 'UTF-8');
        $chlen = strlen($ch);
        $hexs = '';
        for ($j=0; $j < $chlen; $j++)
            $hexs = $hexs . sprintf("%x", ord($ch[$j]));
        printf ("width=%d => '%s' |hex=%s\n", $chlen, $ch, $hexs );

gives us this

length of string: 20 width=1 => 'H' |hex=48 width=1 => ' ' |hex=20 width=1 => 'e' |hex=65 width=1 => ' ' |hex=20 width=1 => 'l' |hex=6c width=1 => ' ' |hex=20 width=1 => 'l' |hex=6c width=1 => ' ' |hex=20 width=1 => 'o' |hex=6f width=1 => ' ' |hex=20 width=1 => ' ' |hex=20 width=1 => 'W' |hex=57 width=1 => ' ' |hex=20 width=1 => 'o' |hex=6f width=1 => ' ' |hex=20 width=1 => 'r' |hex=72 width=1 => ' ' |hex=20 width=1 => 'l' |hex=6c width=1 => ' ' |hex=20 width=1 => 'd' |hex=64

1 point is approximately equal to 1.333 pixels. We can get the sum of the string and then multiply the sum by 1.333 gives you the size of the total size of the string in pixels. Multiply the sum in pixels with the desired font-size gives us the total width of the string in pixels.

Edited by veedeoo: info added.


I posted an example, but after calculating it, there is no way it can be valid. Sorry, I have to remove it. It will not do any help to your question.

Edited by veedeoo: info added.



With imagettfbbox() you can precalculate the width of the string and add the space that you want to both sides, for example if you want 50px per side you will do:

$font = './arial.ttf';
$fontsize = 14;

$bbox = imagettfbbox($fontsize, 0, $font, 'Powered by PHP ' . phpversion());

If you print $bbox you get:

    [0] => 0
    [1] => 4
    [2] => 294
    [3] => 4
    [4] => 294
    [5] => -15
    [6] => 0
    [7] => -15

These are the coordinates of the string, we need $bbox[4] because it represents the upper right corner, X position and $bbox[0] because it is the lower left corner, X position. With $bbox[4] we can generate the width of the image:

$imgx = $bbox[4]+100;

where 100 is the number of pixels we want to add (50 per side). With this you can start to create the image:

$imgy = 100;
$im = imagecreatetruecolor($imgx, $imgy);

now to center horizontally the text we have to perform this:

$xpos = $bbox[0] + ($imgx / 2) - ($bbox[4] / 2);

It will output 50, but if instead of $imgx = $bbox[4]+100; you want to double the sizes:

$imgx = $bbox[4]*2;

It will adapt to the new sizes accordingly to the font size. The same procedure can be done to determine the vertical alignment. The final example script looks like this:


// Path to our font file
$font = './arial.ttf';
$fontsize = 14;
$string = 'Powered by PHP ' . phpversion();

// Calculate the width of the text
$bbox = imagettfbbox($fontsize, 0, $font, $string);

// sizes
$imgy = $bbox[5] + 100;
$imgx = $bbox[4] + 100;
$xpos = $bbox[0] + ($imgx / 2) - ($bbox[4] / 2);
$ypos = $bbox[1] + ($imgy / 2) - ($bbox[5] / 2);

// Create the image
$im = imagecreatetruecolor($imgx, $imgy);
$fontcolor = imagecolorallocate($im, 235, 190, 65);
$backgroundcolor = imagecolorallocate($im, 90, 60, 120);

// Set the background color
imagefilledrectangle($im, 0, 0, $imgx-1, $imgy-1, $backgroundcolor);

// Write the text
imagettftext($im, $fontsize, 0, $xpos, $ypos-5, $fontcolor, $font, $string);

// Output to browser
header('Content-Type: image/png');



Edited by cereal

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.