【问题标题】:PHP imagettftext baseline workaroundPHP imagettftext 基线解决方法
【发布时间】:2011-10-07 22:07:25
【问题描述】:

我正在写作以使用 PHP 将文本打印到图像。但是,imagettftext() 函数使用基线,而我需要将文本垂直居中。

所以,我要么需要一种方法来打印文本,其中 y 不是从顶部到基线的距离,而是从边界框的顶部到顶部,或者我需要一种方法来确定边界框顶部和基线之间的距离.

显然,我把你弄糊涂了。所以,要说清楚:我知道函数imagettfbbox()。使用该函数,我可以确定结果文本框的高度和宽度。但是,在使用imagettftext() 打印时,它的高度对于垂直对齐完全没有用,因为 Y 参数不是到框顶部(甚至是底部,但至少是我可以使用的高度)但是到文本基线的距离。

编辑:为什么我不接受最新的答案?

在答案下方查看我的最新评论,并使用此image 作为参考。

【问题讨论】:

  • 你需要做的是计算你想要文本去哪里的坐标。使用 imagettfbbox 查看文本的大小,然后从图像的高度中减去它并除以 2。
  • 嗯,就是这样! Imagettfbbox() 给了我边界框,很好但对于垂直对齐完全没用,因为 imagettftext 不使用到边界框顶部或底部的距离,而是使用到基线,这使得对齐文本很困难,因为我不知道基线相对于文本框的位置。
  • 感谢您提出这个问题,我也在寻找答案,但似乎没有可用的答案。我正在生成一些 ID 标签,并希望名称填充可用空间。对我来说,问题是挂起的信件(qypjg ...)。带有这些字母的单词以较小的字体占用可用高度(使用 imagettfbbox 计算),但不会填充空间,因为它们挂在空间底部下方。不是世界末日,但它确实让事情看起来不一致和偏离中心。

标签: php imagettftext baseline


【解决方案1】:

我不知道答案是否仍然感兴趣。但是,imagettfbbox() 函数为您提供的信息不仅仅是边界框的高度和宽度。它旨在返回 imagettftext() 所需的信息,以根据需要管理文本。

诀窍在于从 imagettfbbox() 返回的坐标与绝对左上角无关,而是与特定文本的字体基线相关。这是因为盒子是在点坐标中指定的,而这些通常是负数。

简而言之:

$dims = imagettfbbox($fontsize, 0, $font, $text);

$ascent = abs($dims[7]);
$descent = abs($dims[1]);
$width = abs($dims[0])+abs($dims[2]);
$height = $ascent+$descent;

...

// In the example code, for the vertical centering of the text, consider
// the simple following formula

$y = (($imageHeight/2) - ($height/2)) + $ascent;

这非常适合我的项目。 希望对您有所帮助。

对不起英语。 马可。

【讨论】:

  • 哇,Marco,这正是我一直在寻找的。我想我已经找到了一个解决方案,将字体大小的三分之一添加到高度(因为这似乎是基线和底部之间的差异),但您的解决方案更精确。谢谢!
【解决方案2】:

不完全确定您的要求...您能举个例子吗?也许imagettfbbox 是你需要的?

// get bounding box dims
$dims = imagettfbbox($fontsize, 0, $font, $quote);

// do some math to find out the actual width and height
$width = $dims[4] - $dims[6]; // upper-right x minus upper-left x 
$height = $dims[3] - $dims[5]; // lower-right y minus upper-right y

编辑:这是垂直居中文本的示例

<?php
$font = 'arial.ttf';
$fontsize = 100;
$imageX = 500;
$imageY = 500;

// text
$text = "FOOBAR";

// create a bounding box for the text
$dims = imagettfbbox($fontsize, 0, $font, $text);

// height of bounding box (your text)
$bbox_height = $dims[3] - $dims[5]; // lower-right y minus upper-right y

// Create image
$image = imagecreatetruecolor($imageX,$imageY);

// background color
$bgcolor = imagecolorallocate($image, 0, 0, 0);

// text color
$fontcolor = imagecolorallocate($image, 255, 255, 255);

// fill in the background with the background color
imagefilledrectangle($image, 0, 0, $imageX, $imageY, $bgcolor);

$x = 0; 
$y = (($imageY/2) - ($bbox_height/2)) + $fontsize;
imagettftext($image, $fontsize, 0, $x, $y , $fontcolor, $font, $text);

// tell the browser that the content is an image
header('Content-type: image/png');
// output image to the browser
imagepng($image);

// delete the image resource 
imagedestroy($image);
?>

【讨论】:

  • 不,这不是我需要的。我知道函数 imagettfbbox,但它计算边界框,而 imagettftext 使用到基线的距离作为 Y 参数,而不是到框的顶部或底部。
  • 好的,我认为您在这里混淆了自己或想多了。如果你想垂直对齐文本,是的,你需要 imagettfbbox()。要获得 imagettftext() 的 y 参数,您需要将图像的高度除以 2。这是您的垂直中心,我们称之为 $ivc。然后你把从 imagettfbbox() 计算的高度除以 2,我们称之为 $tvc。那么,$y = $ivc - $tvc;
  • 另外,您需要将字体大小添加到 $y 以解决此问题。编辑以添加垂直对齐文本的示例
  • 不,我试过一次。错了,如我创建的图形所示:img855.imageshack.us/img855/9894/alignment.jpg
  • 嗯,我不知道该告诉你什么,也许是你正在使用的字体或者你正在使用的字符集。也许它有问题或不完全受支持,或者 GD 库有其他问题。因为我的示例代码原样工作得很好。
猜你喜欢
  • 2019-07-02
  • 1970-01-01
  • 2011-02-09
  • 1970-01-01
  • 2020-04-25
  • 1970-01-01
  • 2019-09-19
  • 2011-03-08
相关资源
最近更新 更多