我明白你的意思。如果没有任何字距调整,您的输出将如下所示:
当我采取接受的答案 https://stackoverflow.com/questions/6926613/php-imagettftext-letter-spacing,这对于您的目的来说已经足够了,对于间距设置为这样的情况来说,它看起来像这样-0.5
:
注意之间的空间如何f
and e
仍然很大,而在其他地方字母甚至可以重叠。
造成这种情况的原因是什么?有办法预防吗?
让我们从绘制盒子开始,由imagettfbbox()
字母周围:
显然,这个惯例并没有完全按计划进行。您会期望水平重叠(如果存在)对于所有框都是相同的。
解释这个有点困难,它与字体字距调整 https://en.wikipedia.org/wiki/Kerning。字距调整可以减去字母前后的空格:
重要的是要认识到$x
你给予的位置imagettftext()
考虑到这种字距调整。所以即使你说一封信应该写在(x,y)
这不是返回的坐标之一imagettfbbox()
。该函数返回所绘制字母的边界框,如红色矩形所示。
现在让我们看看,有了这些知识,我们是否可以绘制均匀间隔的字母:
显然这是可能的。我使用的代码是这样的:
function imagettftextSpacing($image, $size, $x, $y, $color, $font, $text, $spacing = 0)
{
foreach (mb_str_split($text) as $char)
{
$frontBox = imagettfbbox($size, 0, $font, $char);
$charBox = imagettftext($image, $size, 0, $x - $frontBox[0], $y, $color, $font, $char);
$charW = $charBox[2] - $charBox[0];
$x += $charW + $spacing;
}
}
这会获取字符的水平偏移并在绘制字符时进行纠正。
虽然这是一个进步,但还没有完全令人满意。有些字母接触,有些则不接触。这是因为我们纠正了字符前面的字距调整,但没有纠正后面的字距调整。我们需要以某种方式找出后面的字距调整是什么,然后进行纠正。我把这段代码搞砸了:
function getBBoxW($bBox)
{
return $bBox[2] - $bBox[0];
}
function imagettftextSpacing($image, $size, $x, $y, $color, $font, $text, $spacing = 0)
{
$testStr = 'test';
$testW = getBBoxW(imagettfbbox($size, 0, $font, $testStr));
foreach (mb_str_split($text) as $char)
{
$fullBox = imagettfbbox($size, 0, $font, $char . $testStr);
imagettftext($image, $size, 0, $x - $fullBox[0], $y, $color, $font, $char);
$x += $spacing + getBBoxW($fullBox) - $testW;
}
}
我创建了一个单独的函数来获取边界框的宽度,因为我计算了很多,并且函数名称更清楚地表明了正在执行的操作。我使用一个测试字符串,并检查它的宽度,以便稍后计算它前面的字符的作用。我终于弥补了这一点。结果是这样的:
这显然更好,您很难发现它比本答案开头的示例间隔更近,但事实确实如此。
我不得不承认这相当复杂,我不知道你为什么要这样做。使用基本的 HTML 和 CSS 可以更好地完成同样的工作。