PHP GD实现单词内字母分色及imagettftext间距适配问题
解决PHP imagettftext分色文字间距适配问题
你遇到的问题根源是硬编码了第二段文字的X坐标——不同字符的宽度差异很大(比如窄字符i和宽字符w),固定数值肯定没法适配所有单词。正确的做法是用imagettfbbox()动态计算第一段文字的实际宽度,以此作为第二段文字的起始位置。
核心思路
imagettfbbox()会返回文字的边界框数组,其中索引2对应文字右下角的X坐标(当起始X为0时,这个值就是文字的总宽度)。把第二段文字的X坐标设为这个宽度值,就能让两段文字完美衔接,间距完全匹配字体的自然字距。
修改后的完整代码
$text = strtoupper('bluewhite'); $font = 'font.ttf'; $fontSize = 100; $angle = 0; $baseY = 120; // 文字基线Y坐标 // 创建足够大的画布(避免文字超出) $im = imagecreatetruecolor(1200, 2100); imagealphablending($im, true); imagesavealpha($im, true); // 定义颜色 $white = imagecolorallocate($im, 255, 255, 255); $blue = imagecolorallocate($im, 66, 139, 200); // 提取两段文字 $part1 = substr($text, 0, 4); $part2 = substr($text, 4); // 计算第一段文字的边界框,获取实际宽度 $bbox = imagettfbbox($fontSize, $angle, $font, $part1); $part1Width = $bbox[2] - $bbox[0]; // 右下角X - 左下角X = 文字宽度 // 绘制第一段文字 imagettftext($im, $fontSize, $angle, 0, $baseY, $blue, $font, $part1); // 用第一段的宽度作为第二段的起始X坐标,保证无缝衔接 imagettftext($im, $fontSize, $angle, $part1Width, $baseY, $white, $font, $part2); // 动态计算总宽度,精准裁剪(可选,避免多余空白) $totalBbox = imagettfbbox($fontSize, $angle, $font, $text); $totalWidth = $totalBbox[2] - $totalBbox[0]; $totalHeight = $totalBbox[1] - $totalBbox[7]; // 顶部Y - 底部Y = 文字高度 $crop = imagecrop($im, [ 'x' => $totalBbox[0], // 从文字最左侧开始裁剪 'y' => $totalBbox[7], // 从文字最底部开始裁剪 'width' => $totalWidth, 'height' => $totalHeight ]); // 处理透明背景 imagealphablending($crop, false); imagesavealpha($crop, true); // 开启才能保留透明通道 header('Content-Type: image/png'); imagepng($crop, null, 9); imagedestroy($crop); imagedestroy($im);
关键细节说明
imagettfbbox()的参数必须和imagettftext()完全一致(字号、角度、字体文件),否则计算出的宽度会不准确。- 如果需要手动调整两段文字的间距,可以在
$part1Width基础上加上固定偏移值(比如$part1Width + 5),但通常不需要,字体本身的字距已经是自然状态。 - 裁剪部分改成动态计算总宽度和高度,能避免固定裁剪尺寸导致的文字被截断或多余空白。
- 注意
imagesavealpha($crop, true)必须开启,否则透明背景会变成黑色。
内容的提问来源于stack exchange,提问作者demooon
相关产品推荐
相关产品推荐

