How does “imagettfbbox()” in PHP work?

前端 未结 3 896
悲哀的现实
悲哀的现实 2020-12-18 22:24

Could you please explain what exactly the return value of imagettfbbox() mean? The manual says:

imagettfbbox() returns an array with 8 el

相关标签:
3条回答
  • 2020-12-18 23:13

    The following resource explains this: http://www.tuxradar.com/practicalphp/11/2/6 (via archive.org)

    Just use abs(). This is from the resource above: "[the function] returns its values from the lower-left corner of the baseline of the text string, not the absolute lower-left corner. The baseline of a letter is where it would sit if you were hand writing it on lined paper"

    0 讨论(0)
  • 2020-12-18 23:13

    The answer of Alain Tiemblo and Charles only partly worked for me, a few characters, like '1' weren't pixel perfect.

    But the comment of blackbart at simail dot it on the same page worked very nice:

    I wrote a simple function that calculates the exact bounding box (single pixel precision). The function returns an associative array with these keys: left, top: coordinates you will pass to imagettftext width, height: dimension of the image you have to create

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

    0 讨论(0)
  • 2020-12-18 23:27

    You should take a look at the comment by "marclaz" on the imagettfbbox manual page :

    Please note that as imageTTFBbox and imageTTFText functions return an array of coordinates which could be negative numbers care must be taken with height and width calculations.

    The rigth way to do that is to use the abs() function:

    for an horizontal text:

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

    Then to center your text at ($x,$y) position the code should be like that:

    $x -= $width/2; $y += $heigth/2;
    
    imageTTFText($img,$size,0,$x,$y,$color,$font,$text);
    

    this because (0,0) page origin is topleft page corner and (0,0) text origin is lower-left readable text corner.

    0 讨论(0)
提交回复
热议问题