PHP imageftbbox imagettftext-简单字母间距/字距?
有人知道使用imagettftext进行字母间距/紧排的简单方法吗?我的脚本现在可以正常工作了,但是我可以使用CSS样式生成的文本PHP imageftbbox imagettftext-简单字母间距/字距?,php,imagettftext,Php,Imagettftext,有人知道使用imagettftext进行字母间距/紧排的简单方法吗?我的脚本现在可以正常工作了,但是我可以使用CSS样式生成的文本 字母间距:-0.01em 因此,它与页面上的标准文本匹配,但我看不出任何方法可以轻松做到这一点。我确实找到了以下与此相关的线索,但我已尝试将答案放入代码中,但没有一个达到预期效果 我目前的代码如下 <?php include 'deliverytimes.php'; $date = new DateTime(); $now = date("Y-m
字母间距:-0.01em代码>
因此,它与页面上的标准文本匹配,但我看不出任何方法可以轻松做到这一点。我确实找到了以下与此相关的线索,但我已尝试将答案放入代码中,但没有一个达到预期效果
我目前的代码如下
<?php
include 'deliverytimes.php';
$date = new DateTime();
$now = date("Y-m-d H:i:s");
$h = date("H:i:s");
$days = explode(",", $businessDaysToAdd);
if (count($days) > 1) {
$two_weekdays_later_1 = strtotime(date("Y-m-d H:i:s", strtotime($now)) . " +" . $days[0] . " weekdays $h");
$date_1 = new DateTime("@$two_weekdays_later_1");
$formattedDeliveryDate_1 = $date_1->format('jS M');
$formattedDeliveryDate_3 = $date_1->format('jS \o\f F');
$two_weekdays_later_2 = strtotime(date("Y-m-d H:i:s", strtotime($now)) . " +" . $days[1] . " weekdays $h");
$date_2 = new DateTime("@$two_weekdays_later_2");
$formattedDeliveryDate_2 = $date_2->format('jS M.');
$formattedDeliveryDate_4 = $date_2->format('jS \o\f F');
$formattedDeliveryDate1 = $formattedDeliveryDate_3;
$formattedDeliveryDate2 = $formattedDeliveryDate_4;
$formattedDeliveryDate = "If ordered today we estimate delivery to be approximately between " . $formattedDeliveryDate_1 . " and " . $formattedDeliveryDate_2;
} else {
$h = date("H:i:s");
$two_weekdays_later = strtotime(date("Y-m-d H:i:s", strtotime($now)) . " +" . $businessDaysToAdd . " weekdays $h");
$date = new DateTime("@$two_weekdays_later");
$formattedDeliveryDate = "If ordered today we estimate delivery approximately by " . $date->format('l, jS M.');
}
$defaultOutput = 'main';
$textMobile = isset($_REQUEST['mobile']) ? $_REQUEST['mobile'] : $defaultOutput;
switch($textMobile) {
case "main":
$textToUse = $formattedDeliveryDate;
break;
case "p1":
$textToUse = $formattedDeliveryDate1;
break;
case "p2":
$textToUse = $formattedDeliveryDate2;
break;
}
// Path to our font file
$font = './Inter-SemiBold.ttf';
$fontBold = './Inter-Bold.ttf';
$size = 24;
$size2 = 83;
$bbox = imageftbbox($size2, 0, $fontBold, $textToUse);
$width = 1020;
$height = 110;
$im = imagecreatetruecolor($width, $height);
$x = ($width - ($bbox[4] - $bbox [0])) / 2;
imagealphablending($im, false);
imagesavealpha($im, true);
$white = imagecolorallocate($im, 255, 255, 255);
$black = imagecolorallocate($im, 0, 0, 0);
$grey = imagecolorallocate($im, 161, 161, 168);
$trans = imagecolorallocatealpha($im, 255, 255, 255, 127);
imagefilledrectangle($im, 0, 0, $width, $height, $trans);
$defaultTextColour = 'white';
$textColour = isset($_REQUEST['colour']) ? $_REQUEST['colour'] : $defaultTextColour;
switch($textColour) {
case "white":
$textColourUse = $white;
break;
case "black":
$textColourUse = $black;
break;
case "grey":
$textColourUse = $grey;
break;
}
// Write it
imagettftext($im, $size2, 0, $x, -$bbox[7], $textColourUse, $fontBold, $textToUse);
// Output to browser
header('Content-Type: image/png');
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
imagepng($im);
imagedestroy($im);
我明白你的意思了。在不进行任何紧排的情况下,您的输出如下所示:
当我取下,这对于你们来说已经足够好了,间距设置为-0.5
:
注意f
和e
之间的空间仍然很大,而在其他地方,字母甚至可以重叠
这是什么原因造成的,有没有办法预防
让我们先画一个方框,由imagettfbbox()
在字母周围返回:
显然,这一常规并没有按计划进行。如果存在水平重叠,则所有框的水平重叠都是相同的
要解释这一点有点困难,它必须与。紧排可以减去字母前后的空格:
重要的是要认识到,您给imagettftext()
的$x
位置考虑了这种紧排。因此,即使您说应该在(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可以更好地完成同样的工作。Hi Kiko,再次感谢您提供了令人惊讶且信息丰富的答案-我现在必须尝试将其输入到我的代码中。你是对的,这很复杂,原因是我在eBay上使用它,我们没有javascript,没有jquery,只有纯HTML和CSS,所以要创建动态信息位,唯一的黑客就是使用PHP弹出一个图像文件。当然不知道-但工作限制非常严格。事实上,KIKO我在这里迷路了-我只是在破解一个朋友为我做的一些代码-我如何将你所做的代码放入我发布的代码中以创建所需的输出?@DannyShepherd用这个新的imagettftextSpacing()替换imagettftext()
请注意,两个参数已更改,角度已消失,我添加了间距。将文本居中是另一回事,我没有这样做。你必须计算字符的数量,加上你指定的间距,你可以重新居中。我尝试了以下方法,我更新了脚本中使用的字符的$,但是我在图像框中没有得到结果,是因为它正在消失还是出了什么问题@DannyShepherd您没有更改参数,角度的0
仍然存在,我删除了它,因为我不使用它。