想象一下:queryFontMetrics()函数在windows和linux上给出了不同的结果

时间:2016-03-31 11:18:14

标签: php linux imagick

php版本:5.4.22
Imagick版本:3.2.0RC1

我使用 queryFontMetrics()函数计算文本宽度。

我的代码:

<?php
$font = 'Arial.ttf';
$im = new \Imagick();              
$draw = new \ImagickDraw();                 
$draw->setFont($font);
$draw->setFontSize(10);

$text = 'Bathroom';  
$attriutes = $im->queryFontMetrics($draw, $text);
echo '<br>string : '.$text;
echo '<br>calculated width in pixel : '.$attriutes['textWidth'];

$text = 'TTTTTTTTT';  
$attriutes = $im->queryFontMetrics($draw, $text);
echo '<br>string : '.$text;
echo '<br>calculated width in pixel : '.$attriutes['textWidth'];
?>

linux上的结果(Linux ubuntu 3.16.0-23-generic)

  

字符串:浴室
  计算出的像素宽度:44.828125
  string:TTTTTTTTT
  以像素计算的宽度:53.765625

Windows 7上的结果

  

字符串:浴室
  以像素计算的宽度:47
  string:TTTTTTTTT
  以像素计算的宽度:63

为什么会发生这种情况? php中是否还有其他可以精确计算文本宽度的库?

1 个答案:

答案 0 :(得分:2)

在这个论坛上,我找到了这个。

  

由于Arial是微软受版权保护的字体,我们怀疑它不是   可在您的主机上使用。如果没有,ImageMagick会选择一个默认字体   在每台机器上可能有所不同。另一个区别是   Freetype库。不同版本可能会返回不同的结果   字体指标。如果你的脚本有ImageMagick 6.5.9-0和   在Linux主机上的Freetype 2.3.11和它一致   返回:

x_ppem = 14
y_ppem = 14
ascender = 11
descender = -4
width = 4
height = 17
max_advance = 15
     

表示默认字体(因为Arial不可用)。

如果您使用identify -list Type命令

你会得到这样的结果。

enter image description here

建议

characterWidth和characterHeight

  • 这些似乎与您为字体指定的大小有关,并且似乎与字体不同(大小相同)。因此,它们对我来说并不是特别有用(至少对我而言)。它们不是字体将使用多少空间的可靠指标。

<强>上升器

  • ascender是字体在基线之上的一部分。它与字符无关 - 字体中每个字符的上升值都相同。

<强>伸

  • 下降程序是字体低于基线的部分。它表示为负数。添加上升器和下降器的绝对值可以得到...

<强> textHeight不同

  • 这是字体可用的总高度。对于字体中的每个字符都是相同的,无论其大小写或字符似乎占用多少空间。这可用于在输出段落等时确定行高。

<强>输出textWidth

  • 此值因字符而异,并且是字符的宽度。如果boundingBox不提供可用值,则此选项很有用(请参阅下面的boundingBox)。当逐个定位字符时 - 不要使用textWidth,请使用originX(见下文)。

<强> maxHorizo​​ntalAdvance

  • 恐怕我还没弄明白这个目的。对于字体中的每个字符都是相同的。对于大小为67的字体Arial Italic,值为89,比M或相同大小的W报告的前进宽得多。

<强> boundingBox的

  • 返回一个关联数组,描述包含该字符的矩形的四个点(x1,y1,x2,y2)。这些值是相对于原点(即您在图像中绘制字符的位置的坐标)。返回的矩形非常准确,完全包含打印字符的所有部分 - 但boundingBox仅适用于单个字符。它不会给出多个角色的准确数字(根据我的经验)。绘制框时,需要将“x”值添加到原点,并从原点中减去“y”值。您不能依赖于边界框来获取SPACE字符。它返回一个(0,0,0,0)的boundingBox。 textWidth(见上文)在这里派上用场。

originX和originY

  • 这些标题不准确。 originX和originY中返回的值实际上是advanceX和advanceY。这些值为您提供下一个字符相对于当前字符的位置。

另请阅读此stackoverflow quesion