PHP中的“imagettfbbox()”如何工作?

时间:2012-09-09 09:46:42

标签: php gd

您能解释一下imagettfbbox()的确切回报是什么意思吗? The manual says

  

imagettfbbox()返回一个包含8个元素的数组,表示四个元素   使得文本的边界框成功并且为FALSE的点   错误。 [......这里的要点......]   无论角度如何,这些点都与文本有关,因此“上部   left“表示左上角水平看文本。

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

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

表示以下几点:

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

我该如何解释它们?

为什么会出现负值?

3 个答案:

答案 0 :(得分:10)

您应该查看comment by "marclaz" on the imagettfbbox manual page

  

请注意,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)页面原点是topleft page corner和(0,0)text   原点是左下方可读的文字角。

答案 1 :(得分:1)

以下资源解释了这一点: http://www.tuxradar.com/practicalphp/11/2/6

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

答案 2 :(得分:0)

Alain Tiemblo和Charles的回答仅对我有用,有些字符(例如“ 1”)并不是像素完美的。

但是同一页面上的comment of blackbart at simail dot it的效果非常好:

  

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

     

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 ); }