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?

Recommended Answers

All 5 Replies

Try with imagettfbbox() as suggested in this comment:

Also, consider to use mb_strtolower() and mb_convert_case() instead of strtolower() and ucwords() because the latters will not work correctly with special characters. In your case just use:

$name = mb_convert_case($Name, MB_CASE_TITLE, "UTF-8");

Reference: http://php.net/mb_convert_case

Bye!

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

<?php
    $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.

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.

@toxicandy

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:

Array
(
    [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:

<?php

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

imagepng($im);
imagedestroy($im);

Bye!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.