在 PHP 中处理图像文字时,常常需要获取文字的宽度以便于排版和定位。传统上,很多开发者会使用 imagefontwidth() 函数来获得内置字体的字符宽度。但由于 imagefontwidth() 只能处理内置字体(且尺寸固定),其精度和灵活性有限,尤其在使用 TrueType 字体时无法满足需求。
本文将介绍如何用 imagettfbbox() 函数替代 imagefontwidth(),实现更准确的文字宽度测量,特别适用于自由使用 TTF 字体的场景。
imagefontwidth() 函数只接受内置字体的大小(1 到 5),返回指定字体中字符的宽度(以像素为单位)。但该函数无法测量任何字符串的整体宽度,也无法支持自定义字体大小和字体文件。
<?php
// 传统用法,获取内置字体大小为3时一个字符的宽度
$charWidth = imagefontwidth(3);
echo "字符宽度: $charWidth";
?>
这种方法无法准确得到任意字符串或自定义字体的宽度。
imagettfbbox() 是 PHP 提供的用于 TrueType 字体的函数,它返回一个数组,表示给定文字在图像上的边界框坐标。通过计算这些坐标,可以获得文字的宽度和高度。
array imagettfbbox(float $size, float $angle, string $fontfile, string $text)
$size:字体大小
$angle:角度(一般为 0)
$fontfile:字体文件路径(.ttf)
$text:需要测量的文字
返回 8 个整数组成的数组,表示文字边界框的四个顶点:
0 => lower left X
1 => lower left Y
2 => lower right X
3 => lower right Y
4 => upper right X
5 => upper right Y
6 => upper left X
7 => upper left Y
以下示例演示如何用 imagettfbbox() 来替代 imagefontwidth(),实现准确测量文字宽度。
<?php
// 文字内容
$text = "Hello, 世界!";
// 字体大小
$fontSize = 16;
// 角度
$angle = 0;
// 字体文件路径(假设字体文件位于服务器)
$fontFile = 'm66.net/fonts/arial.ttf';
// 获取文字边界框数组
$bbox = imagettfbbox($fontSize, $angle, $fontFile, $text);
// 计算宽度
// 右下角X - 左下角X
$textWidth = abs($bbox[2] - $bbox[0]);
echo "文字宽度为: " . $textWidth . " 像素";
?>
假设我们需要在宽度为 300px 的画布中居中绘制文字,可以先用 imagettfbbox() 获取文字宽度,然后计算起点:
<?php
// 创建画布
$imgWidth = 300;
$imgHeight = 50;
$image = imagecreatetruecolor($imgWidth, $imgHeight);
// 颜色定义
$bgColor = imagecolorallocate($image, 255, 255, 255);
$textColor = imagecolorallocate($image, 0, 0, 0);
// 填充背景
imagefill($image, 0, 0, $bgColor);
// 文字与字体参数
$text = "Hello, 世界!";
$fontSize = 20;
$angle = 0;
$fontFile = 'm66.net/fonts/arial.ttf';
// 获取文字宽度
$bbox = imagettfbbox($fontSize, $angle, $fontFile, $text);
$textWidth = abs($bbox[2] - $bbox[0]);
$textHeight = abs($bbox[5] - $bbox[1]);
// 计算X轴起点,实现水平居中
$x = ($imgWidth - $textWidth) / 2;
// 计算Y轴起点,实现垂直居中(注意 imagettftext 以基线为基准)
$y = ($imgHeight + $textHeight) / 2;
// 绘制文字
imagettftext($image, $fontSize, $angle, $x, $y, $textColor, $fontFile, $text);
// 输出图片
header('Content-Type: image/png');
imagepng($image);
imagedestroy($image);
?>
imagefontwidth() 仅适合内置字体且功能简单;
imagettfbbox() 能准确获取任意 TTF 字体的文字边界尺寸,测量文字宽度更精准;
使用 imagettfbbox(),可以实现更灵活的文字定位和排版需求,尤其适合自定义字体和复杂文本。
通过本文介绍的示例,你可以轻松将 imagefontwidth() 替换为 imagettfbbox(),提升图像文字处理的准确性和灵活性。