当文本以数字开头时,imagettfbbox 计算出错误的矩形
imagettfbbox calculates wrong rectangle when text begins with number
问题是,当使用 imagettfbbox
计算文本尺寸时,当输入文本以数字开头时返回的矩形太小。这是我的代码:
$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)."\" />";
这些是我针对不同的输入文本得到的结果:
我该如何解决?
问题是误会造成的。 imagettfbbox
的值还定义了 你必须从哪里开始绘制 - 通常这些坐标甚至是负数。我一直假设您可以从 [0, 0]
坐标开始。事实并非如此,绘图坐标可以为负值。
此函数也在评论中提到,源自 PHP.net 用户贡献,计算起始坐标以及宽度和高度(在相关代码中是正确的)。
// 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;
}
但绘图时必须使用此函数给出的x和y坐标:
imagettftext($im, $fontSize, 0, $bbox["x"], $bbox["y"], $text_color, $font, $text);
问题是,当使用 imagettfbbox
计算文本尺寸时,当输入文本以数字开头时返回的矩形太小。这是我的代码:
$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)."\" />";
这些是我针对不同的输入文本得到的结果:
我该如何解决?
问题是误会造成的。 imagettfbbox
的值还定义了 你必须从哪里开始绘制 - 通常这些坐标甚至是负数。我一直假设您可以从 [0, 0]
坐标开始。事实并非如此,绘图坐标可以为负值。
此函数也在评论中提到,源自 PHP.net 用户贡献,计算起始坐标以及宽度和高度(在相关代码中是正确的)。
// 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;
}
但绘图时必须使用此函数给出的x和y坐标:
imagettftext($im, $fontSize, 0, $bbox["x"], $bbox["y"], $text_color, $font, $text);