测量文本宽度(Python/PIL) [英] Measuring width of text (Python/PIL)

查看:724
本文介绍了测量文本宽度(Python/PIL)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下两种方法来为设置的字体类型和大小计算示例字符串的呈现的宽度:

I'm using the following two methods to calculate a sample string's rendered width for a set font-type and size:

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.为什么会有差异?而且,我还注意到示例文本越短,这两种方法之间的差异越小.

METHOD 1 yields a width of 3236, whereas METHOD 2 yields 3270. Why the discrepancy? Moreover, I've also noticed that shorter the sample text, smaller the discrepancy between these two methods.

幕后到底发生了什么?可以认为哪个宽度是渲染句子的 true 宽度?最后,我可以做些调整以使两种方法报告的宽度大致相同吗?

What's going on under the hood? And which width can be thought of as the true width of the rendered sentence? Lastly, is there a tweak I can do to have both methods report approximately the same widths?

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

推荐答案

紧缩

您在这里做两种不同的事情:

Kerning

You're doing two different things here:

  • 查找长文本的宽度.
  • 找到所有字符的宽度,然后盲目地将它们加在一起

如果您使用的是等宽字体,则可能会有所不同,但是字体通常使用字距调整来使文本更平滑更紧密.

If you were using a monospace font, things might be different, but fonts generally use something called kerning to make the text smoother and a bit tighter.

维基百科说:

在印刷术中,字距调整是调整比例字体中字符之间的间距的过程,通常是为了获得视觉上令人愉悦的结果.字距调整可调整单个字母形式之间的间距,而跟踪(字母间距)可在一系列字符范围内均匀地调整间距.在字体紧缩的情况下,每对字符之间的二维空格都在视觉上具有相似的区域.

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.

以下是 DejaVuSans字体的字距:

在幕后,Pillow对两种方法的作用并没有太大不同.只是您以不同的方式称呼他们.

Under the hood, Pillow isn't doing much different for your two methods. It's just you're calling them in different ways.

如果您添加第三个方法来使用与方法二相同的功能来获取整个句子的宽度,那么您也将获得与方法一相同的宽度来获取整个句子:

If you add a third method to get the width of the whole sentence using the same function as in method two, you'll also get the same width as getting the whole sentence as in method one:

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

这是枕头的 ImageDraw.textsize (从方法一和方法三开始):

Here's Pillow's ImageDraw.textsize (from methods one and three):

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,与方法二相同. (对于多行文本,它只是将其拆分为几行,并返回几个font.getsize调用的总和.)

For single-line text, this is just returning the font.getsize, the same as method two. (And for multiline text, it just splits it into lines and returns the sum of several font.getsize calls.)

这篇关于测量文本宽度(Python/PIL)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆