13

您能否解释一下究竟是什么imagettfbbox()意思的返回值?手册说

imagettfbbox() 返回一个包含 8 个元素的数组,代表四个点,成功时为文本的边界框,错误时为 FALSE。[...此处的点表...] 这些点与文本无关,与角度无关,因此“左上角”表示在左上角水平查看文本。

但是,我发现它不是很清楚。例如,返回值:

array(-1, 1, 61, 1, 61, -96, -1, -96)

指以下几点:

(-1, -96) ------ (61, -96)
    |                |
    |                |
    |                |
    |                |
    |                |
    |                |
 (-1, 1) -------- (61, 1)              

我应该如何解释它们?

为什么会有负值?

4

3 回答 3

13

您应该查看手册页上“marclaz”的评论imagettfbbox

请注意,由于 imageTTFBbox 和 imageTTFText 函数返回可能是负数的坐标数组,因此必须注意计算高度和宽度。

正确的方法是使用 abs() 函数:

对于水平文本:

$box = @imageTTFBbox($size,0,$font,$text); $width = abs($box[4] -
$box[0]); $height = abs($box[5] - $box[1]);

然后将您的文本居中在 ($x,$y) 位置,代码应该是这样的:

$x -= $width/2; $y += $heigth/2;

imageTTFText($img,$size,0,$x,$y,$color,$font,$text);

这是因为 (0,0) 页面原点是左上角,而 (0,0) 文本原点是左下角可读文本角。

于 2012-09-09T10:18:27.020 回答
2

以下资源对此进行了解释: http://www.tuxradar.com/practicalphp/11/2/6(通过archive.org)

只需使用abs()。这来自上面的资源:“[函数]从文本字符串基线的左下角返回它的值,而不是绝对的左下角。如果你是,字母的基线是它所在的位置手写在横格纸上”

于 2012-09-09T10:17:32.160 回答
0

Alain Tiemblo 和 Charles 的回答对我来说只是部分有效,一些字符,比如“1”不是像素完美的。

但是同一页面上simail dot it 的 blackbart 的评论非常好:

我写了一个简单的函数来计算精确的边界框(单像素精度)。该函数返回一个具有以下键的关联数组:left,top:您将传递给 imagettftext 的坐标 width,height:您必须创建的图像的尺寸

function calculateTextBox($font_size, $font_angle, $font_file, $text) { $box = imagettfbbox($font_size, $font_angle, $font_file, $text); if( !$box ) return false; $min_x = min( array($box[0], $box[2], $box[4], $box[6]) ); $max_x = max( array($box[0], $box[2], $box[4], $box[6]) ); $min_y = min( array($box[1], $box[3], $box[5], $box[7]) ); $max_y = max( array($box[1], $box[3], $box[5], $box[7]) ); $width = ( $max_x - $min_x ); $height = ( $max_y - $min_y ); $left = abs( $min_x ) + $width; $top = abs( $min_y ) + $height; // to calculate the exact bounding box i write the text in a large image $img = @imagecreatetruecolor( $width << 2, $height << 2 ); $white = imagecolorallocate( $img, 255, 255, 255 ); $black = imagecolorallocate( $img, 0, 0, 0 ); imagefilledrectangle($img, 0, 0, imagesx($img), imagesy($img), $black); // for sure the text is completely in the image! imagettftext( $img, $font_size, $font_angle, $left, $top, $white, $font_file, $text); // start scanning (0=> black => empty) $rleft = $w4 = $width<<2; $rright = 0; $rbottom = 0; $rtop = $h4 = $height<<2; for( $x = 0; $x < $w4; $x++ ) for( $y = 0; $y < $h4; $y++ ) if( imagecolorat( $img, $x, $y ) ){ $rleft = min( $rleft, $x ); $rright = max( $rright, $x ); $rtop = min( $rtop, $y ); $rbottom = max( $rbottom, $y ); } // destroy img and serve the result imagedestroy( $img ); return array( "left" => $left - $rleft, "top" => $top - $rtop, "width" => $rright - $rleft + 1, "height" => $rbottom - $rtop + 1 ); }

于 2019-01-14T06:49:38.993 回答