测量文本宽度(Python/PIL)

2024-05-18 21:41:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用以下两种方法计算设置字体类型和大小时呈现的样本字符串的宽度:

font = ImageFont.truetype("/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf", 14)
sample = "Lorem ipsum dolor sit amet, partem periculis an duo, eum lorem paulo an, mazim feugiat lobortis sea ut. In est error eirmod vituperata, prima iudicabit rationibus mel et. Paulo accumsan ad sit, et modus assueverit eum. Quod homero adversarium vel ne, mel noster dolorum te, qui ea senserit argumentum complectitur. Duo at laudem explicari deterruisset, eu quo hinc mnesarchum. Vel autem insolens atomorum at, dolorum suavitate voluptatum duo ex."
#METHOD 1
draw_txt = ImageDraw.Draw(img)
width, height = draw_txt.textsize(sample, font=font)
print width
#METHOD 2
width = 0
for c in sample:
    width += font.getsize(c)[0]
print width

METHOD 1产生3236的宽度,而METHOD 2产生3270。为什么不一致?此外,我还注意到样本文本越短,这两种方法之间的差异就越小。

引擎盖下面怎么了?哪个宽度可以被认为是呈现句子的宽度?最后,我是否可以做一些调整,使两个方法的报告宽度大致相同?

注意:示例文本的长度为445个字符


Tags: sample方法an宽度widthmethodet样本
1条回答
网友
1楼 · 发布于 2024-05-18 21:41:31

紧排

你在这里做两件不同的事:

  • 查找长文本的宽度。
  • 找出所有字符的宽度,然后盲目地将它们相加

如果使用的是单空间字体,情况可能会有所不同,但字体通常使用称为字距调整的字体,以使文本更平滑、更紧凑。

Wikipedia说:

In typography, kerning is the process of adjusting the spacing between characters in a proportional font, usually to achieve a visually pleasing result. Kerning adjusts the space between individual letter forms, while tracking (letter-spacing) adjusts spacing uniformly over a range of characters. In a well-kerned font, the two-dimensional blank spaces between each pair of characters all have a visually similar area.

Kerning brings A and V closer with their serifs over each other

这里有一些kerning of the DejaVuSans font

font kerning showing different char widths

在引擎盖下

在引擎盖下,枕头对你的两种方法没有多大影响。只是你用不同的方式给他们打电话。

如果您添加第三种方法以使用与方法2中相同的函数获取整个句子的宽度,您也将获得与方法1中获取整个句子相同的宽度:

# METHOD 3
width = font.getsize(sample)[0]
print width

这是枕头^{}(来自方法一和方法三):

def textsize(self, text, font=None, *args, **kwargs):
    """Get the size of a given string, in pixels."""
    if self._multiline_check(text):
        return self.multiline_textsize(text, font, *args, **kwargs)

    if font is None:
        font = self.getfont()
    return font.getsize(text)

对于单行文本,这只是返回font.getsize,与方法2相同。(对于多行文本,它只是将其拆分成行并返回几个font.getsize调用的和。)

相关问题 更多 >

    热门问题