When using PHP to process images, we often use the imagefontwidth() function to get the character width of a specific font size, thereby calculating the exact placeholding of text in the image. However, many developers will encounter a troublesome problem: the width returned by imagefontwidth() always does not match the actual display effect, resulting in text position confusing or truncating. This article will analyze the causes of this problem in depth and provide a reliable solution.
imagefontwidth(int $font) is one of the functions provided by the PHP GD library to get the pixel width of a character in a specified font size. It only works with bitmap fonts built into the GD library, and the font size is usually an integer value (1 to 5).
Sample code:
$width = imagefontwidth(5);
echo "The font width is:$width Pixels";
The problems usually occur in the following aspects:
imagefontwidth() is only valid for built-in bitmap fonts and is not applicable to TrueType fonts (TTFs). Many developers use imagettftext () to render TTF fonts incorrectly, and this will inevitably lead to wrong results.
Even if you use built-in fonts, remember that imagefontwidth() returns the width of a single character. If you are rendering an entire string, you need to multiply by the string length:
$font = 5;
$text = "Hello";
$width = imagefontwidth($font) * strlen($text);
If the string contains multibyte characters (such as Chinese), then the length returned by strlen() will be inaccurate, and you need to use mb_strlen() instead:
$width = imagefontwidth($font) * mb_strlen($text, 'UTF-8');
Although PHP's bitmap fonts do not need to be loaded manually, if you are using a custom font path or system font, different rendering functions may be mixed, resulting in an understanding error.
Use imagefontwidth() directly to ensure that the font number is in the range of 1~5, and use strlen() or mb_strlen() :
$font = 3;
$text = "Welcome";
$width = imagefontwidth($font) * strlen($text);
For TTF fonts, imagefontwidth() is invalid. You must use imagettfbbox() to get the bounding box of the string under the specified font, and then calculate the width according to the coordinates:
$fontFile = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf";
$fontSize = 14;
$text = "Welcome";
$bbox = imagettfbbox($fontSize, 0, $fontFile, $text);
$width = abs($bbox[2] - $bbox[0]);
In this example, $bbox returns an array of 8 elements representing the four corners of the text border. The width can be calculated by the horizontal axis difference between the upper right corner and the upper left corner.
$img = imagecreate(200, 50);
$bg = imagecolorallocate($img, 255, 255, 255);
$color = imagecolorallocate($img, 0, 0, 0);
$fontFile = "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf";
$text = "Hello World";
$fontSize = 12;
$bbox = imagettfbbox($fontSize, 0, $fontFile, $text);
$textWidth = abs($bbox[2] - $bbox[0]);
$x = (200 - $textWidth) / 2;
$y = 30;
imagettftext($img, $fontSize, 0, $x, $y, $color, $fontFile, $text);
header("Content-Type: image/png");
imagepng($img);
imagedestroy($img);
In this way, we ensure that even TTF fonts get accurate width and centering position.
Don't mix imagestring() and imagettftext() : they are suitable for bitmap and TTF fonts, respectively.
The result returned by imagefontwidth() is not affected by DPI settings, but imagettfbbox() calculates logical pixels and is affected by font files.
If deployed to another server, be sure to confirm that the font file path exists and is accessible. For example: https://m66.net/fonts/DejaVuSans.ttf
When imagefontwidth() returns the wrong width, most of the cases are because of using incompatible font types or ignoring the product of the total number of characters. Understanding the scope of this function and using imagettfbbox() instead when dealing with TTF fonts is the key to solving the problem. Only by selecting the tools correctly can you get the desired precise layout and effect when processing images.