【问题标题】:Measuring width of text (Python/PIL)测量文本宽度(Python/PIL)
【发布时间】:2019-12-04 05:14:36
【问题描述】:

我使用以下两种方法来计算一个示例字符串的渲染 width 设置字体类型和大小:

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。为什么会出现差异?此外,我还注意到示例文本越短,这两种方法之间的差异就越小。

引擎盖下发生了什么?哪个宽度可以被认为是渲染句子的 true 宽度?最后,我可以做一些调整来让两种方法报告大致相同的宽度吗?

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

【问题讨论】:

    标签: python python-imaging-library text-processing pillow


    【解决方案1】:

    字距调整

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

    • 查找长文本的宽度。
    • 求所有字符的宽度,盲目相加

    如果您使用的是等宽字体,情况可能会有所不同,但字体通常使用一种称为 kerning 的方法来使文本更平滑、更紧凑。

    Wikipedia 说:

    在排版中,kerning 是按比例字体调整字符间距的过程,通常是为了获得视觉上令人愉悦的结果。字距调整单个字母形式之间的间距,而跟踪(字母间距)在一系列字符上均匀地调整间距。在紧排字体中,每对字符之间的二维空格都有一个视觉上相似的区域。

    这里有一些kerning of the DejaVuSans font

    引擎盖下

    在底层,Pillow 对您的两种方法并没有太大的不同。只是你称呼他们的方式不同而已。

    如果你添加第三种方法来获取整个句子的宽度,使用与方法二中相同的函数,你也会得到与方法一中获取整个句子相同的宽度:

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

    这是 Pillow 的 ImageDraw.textsize(来自方法一和三):

    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 调用的总和。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-23
      • 2013-11-30
      • 2021-12-06
      • 1970-01-01
      • 1970-01-01
      • 2015-09-27
      • 2021-10-05
      相关资源
      最近更新 更多