什么是确定文字正确的方式,从边界框负责协调?(What is the correct way to

2019-07-30 15:06发布

给一个调用的结果imagettfbbox()什么是正确的,完美的像素点,以提供imagettftext()使得文本不会超出它的边框?

我确定的宽度/高度,并从这样的边界框的基线的X / Y:

$box = imagettfbbox($size, $angle, $font, $text);
$boxXCoords = array($box[0], $box[2], $box[4], $box[6]);
$boxYCoords = array($box[1], $box[3], $box[5], $box[7]);
$boxWidth = max($boxXCoords) - min($boxXCoords);
$boxHeight = max($boxYCoords) - min($boxYCoords);
$boxBaseX = abs(min($boxXCoords));
$boxBaseY = abs(min($boxYCoords));

然后我画一矩形并填充我的边界框的尺寸的图像:

imagefilledrectangle($image, 0, 0, $boxWidth - 1, $boxHeight - 1, $color);

在那之后,我绘制文本:

imagettftext($image, $size, $angle, $boxBaseX, $boxBaseY, $color, $font, $text);

然而,这导致通过一两个像素超出矩形延伸的文本。 我见过几次试图固定在PHP的这个问题imagettfbbox()的文件,但他们都只是建议减去一个或两个像素在这里和那里,这似乎是一个黑客攻击我。 这里发生了什么,为什么我们应该需要捏造的数字把事情做好?

Answer 1:

我相信这是基于什么样的地方用单像素精度文本的图像上没有完美的方式imagettfbbox()返回,并使用的.ttf非等宽字体。 在在PHP手册不少网友贴出的方式来做到这一点(有和没有捏造的数字); 我建议使用jodybrabec的简单功能上的PHP手册,它会计算出准确的边界框。 我已经测试这一个且仅在极端情况下在一个方向上定位在最1像素关闭的文本。 不过,如果你添加一些填充(哪怕是只有2或3个像素)到您的图像文本将成为时间的图像100%的尺寸范围内。



Answer 2:

当你不减去从每个在这条线的尺寸会发生什么:

imagefilledrectangle($image, 0, 0, $boxWidth - 1, $boxHeight - 1, $color);

而是这样做:

imagefilledrectangle($image, 0, 0, $boxWidth, $boxHeight, $color);


Answer 3:

该SlightlyMagic HQ卡发电机项目呈现卡的策略卡牌游戏魔术:聚会。 发电机是由PHP内置了先进的文本渲染引擎。我不知道计算背后的逻辑,但渲染是死准确此应用程序的目的。 下面是正确的计算边界框(功能HQ Card Generator 8.x/scripts/classes/font.php ):

private function convertBoundingBox ($bbox) {
    // Transform the results of imagettfbbox into usable (and correct!) values.
    if ($bbox[0] >= -1)
        $xOffset = -abs($bbox[0] + 1);
    else
        $xOffset = abs($bbox[0] + 2);
    $width = abs($bbox[2] - $bbox[0]);
    if ($bbox[0] < -1) $width = abs($bbox[2]) + abs($bbox[0]) - 1;
    $yOffset = abs($bbox[5] + 1);
    if ($bbox[5] >= -1) $yOffset = -$yOffset;
    $height = abs($bbox[7]) - abs($bbox[1]);
    if ($bbox[3] > 0) $height = abs($bbox[7] - $bbox[1]) - 1;
    return array(
        'width' => $width,
        'height' => $height,
        'xOffset' => $xOffset, // Using xCoord + xOffset with imagettftext puts the left most pixel of the text at xCoord.
        'yOffset' => $yOffset, // Using yCoord + yOffset with imagettftext puts the top most pixel of the text at yCoord.
        'belowBasepoint' => max(0, $bbox[1])
    );
}


Answer 4:

我知道这是有点晚了,但imagettfbbox是不点的像素。

在imagettftext代替点大小的像素的字体大小



文章来源: What is the correct way to determine text coordinates a from bounding box?