2016-04-29 13 views
15

Vấn đề là khi sử dụng imagettfbbox để tính kích thước văn bản, hình chữ nhật quá nhỏ được trả về khi văn bản đầu vào bắt đầu bằng số. Đây là mã của tôi:imagettfbbox tính hình chữ nhật sai khi văn bản bắt đầu bằng số

$fontSize = 150; 
$font = "font/courier_new.ttf"; 
$text = $_GET["text"]; 

//Determine font dimensions 
$bbox = imagettfbbox($fontSize, 0, $font, $text); 
$bbox["width"]= abs($bbox[4]-$bbox[0]); 
$bbox["height"]= abs($bbox[5]-$bbox[1]); 

$im = imagecreatetruecolor($bbox["width"], $bbox["height"]); 

echo "<b>Image size:</b>\n"; 
print_r($bbox); 

// This part makes transparent background 
imagesavealpha($im, true); 
$bg = imagecolorallocatealpha($im, 254, 254, 254,127); 
$text_color= imagecolorallocate($im, 0, 0, 0); 
imagealphablending($im, false); 
imagefilledrectangle($im, 0, 0, imagesx($im), imagesy($im), $bg); 
imagealphablending($im, true); 


header("X-Img-Size: ".$bbox["width"]."x".$bbox["height"].""); 

imagettftext($im, $fontSize, 0, 0, $bbox["height"], $text_color, $font, $text); 

// This is output  
header("Content-Type: text/html"); 
ob_start(); 
imagepng($im); 
$image_data = ob_get_contents(); 
ob_end_clean(); 
imagedestroy($im); 

echo "<img src=\"data:image/png;base64,".base64_encode($image_data)."\" />"; 

Online test here

Đây là những kết quả tôi nhận được cho nhập văn bản khác nhau:

image description

image description

image description

Làm cách nào để khắc phục điều đó?

+2

này dường như là một vấn đề được biết đến; xem http://php.net/manual/en/function.imagettfbbox.php, đặc biệt. Câu trả lời của 'peterjwest3' với bản sửa lỗi được đề xuất. Tác giả của hàm phải có một số phím tắt ... Có vẻ như sử dụng ['FT_BBox'] (http://www.freetype.org/freetype2/docs/reference/ft2-basic_types.html#FT_BBox), ngoại trừ điều này * sẽ * "cung cấp cho descender của glyph" một cách chính xác. – usr2564301

+1

@ TomášZato - bạn đã đi đến http://php.net/manual/en/function.imagettfbbox.php và đọc qua các cách giải quyết được đề xuất, đặc biệt. từ "mike at mikeleigh dot com" từ 8 năm trước? Nếu có thì có lý do nào đó giải pháp/giải pháp được đề xuất của anh ấy sẽ không giải quyết được sự cố bạn đang gặp phải không? –

+0

@BobJarvis Tôi không thể thề là tôi đã sử dụng mọi cách giải quyết ở đó, nhưng đoạn mã này đã áp dụng một số mã gợi ý - những phương trình cho chiều rộng và chiều cao đến từ trang đó. Tôi sẽ thử cách giải quyết chính xác mà bạn đã đề cập. –

Trả lời

6

Vấn đề là do quan niệm sai lầm. Giá trị của imagettfbbox cũng xác định nơi bạn phải bắt đầu vẽ - và thường những tọa độ đó thậm chí còn âm. Tôi luôn cho rằng bạn có thể bắt đầu tại các tọa độ [0, 0]. Điều đó không đúng, tọa độ bản vẽ có thể là số âm.

Chức năng này, cũng được đề cập trong các nhận xét và có nguồn gốc từ đóng góp của người dùng PHP.net tính toán tọa độ bắt đầu, cũng như chiều rộng và chiều cao (chính xác trong mã được đề cập).

// Source: http://php.net/manual/en/function.imagettfbbox.php#75407 
function imagettfbboxextended($size, $angle, $fontfile, $text) { 
    /*this function extends imagettfbbox and includes within the returned array 
    the actual text width and height as well as the x and y coordinates the 
    text should be drawn from to render correctly. This currently only works 
    for an angle of zero and corrects the issue of hanging letters e.g. jpqg*/ 
    $bbox = imagettfbbox($size, $angle, $fontfile, $text); 

    //calculate x baseline 
    if($bbox[0] >= -1) { 
     $bbox['x'] = abs($bbox[0] + 1) * -1; 
    } else { 
     //$bbox['x'] = 0; 
     $bbox['x'] = abs($bbox[0] + 2); 
    } 

    //calculate actual text width 
    $bbox['width'] = abs($bbox[2] - $bbox[0]); 
    if($bbox[0] < -1) { 
     $bbox['width'] = abs($bbox[2]) + abs($bbox[0]) - 1; 
    } 

    //calculate y baseline 
    $bbox['y'] = abs($bbox[5] + 1); 

    //calculate actual text height 
    $bbox['height'] = abs($bbox[7]) - abs($bbox[1]); 
    if($bbox[3] > 0) { 
     $bbox['height'] = abs($bbox[7] - $bbox[1]) - 1; 
    } 

    return $bbox; 
} 

Nhưng nó là bắt buộc mà bạn sử dụng tọa độ x và y do chức năng này khi vẽ:

imagettftext($im, $fontSize, 0, $bbox["x"], $bbox["y"], $text_color, $font, $text); 
+0

Thật tuyệt vời khi bạn tự trả lời những gì dường như là một chuyên gia vấn đề. Cảm ơn! –

+0

@StijndeWitt Tôi sẽ không tìm ra nó mà không có bình luận về câu hỏi của tôi. –

Các vấn đề liên quan