テキストの幅の測定 (Python/PIL) 質問する

テキストの幅の測定 (Python/PIL) 質問する

私はサンプル文字列のレンダリングを計算するために次の2つの方法を使用していますフォントの種類とサイズを設定する場合:

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。なぜ相違があるのでしょうか? さらに、サンプル テキストが短いほど、これら 2 つの方法の相違が小さくなることにも気付きました。

ボンネットの下で何が起こっているのか?そして、どの幅が真実レンダリングされた文の幅は?最後に、両方の方法でほぼ同じ幅を報告するように調整することはできますか?

注: サンプルテキストの長さは445文字です

ベストアンサー1

字詰め

ここでは 2 つの異なることを行っています。

  • 長いテキストの幅を見つけます。
  • すべての文字の幅を調べ、それらを盲目的に加算する

等幅フォントを使用している場合は状況が異なる可能性がありますが、フォントは一般的に字詰めテキストをより滑らかに、そして少しタイトにします。

ウィキペディア言う:

タイポグラフィでは、字詰めプロポーショナル フォントの文字間隔を調整するプロセスで、通常は見た目に美しい結果を実現します。カーニングは個々の文字間の間隔を調整し、トラッキング (文字間隔) は文字の範囲にわたって間隔を均一に調整します。適切にカーニングされたフォントでは、各文字間の 2 次元の空白スペースの領域はすべて、視覚的に同じになります。

カーニングにより、AとVのセリフが重なり合って近づきます。

ここにいくつかありますDejaVuSansフォントのカーニング:

異なる文字幅を示すフォントカーニング

フードの下

内部的には、Pillow は 2 つのメソッドに対してあまり違いはありません。異なる方法で呼び出しているだけです。

方法 2 と同じ関数を使用して文全体の幅を取得する 3 番目の方法を追加すると、方法 1 で文全体を取得する場合と同じ幅も取得されます。

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

枕はこちらImageDraw.textsize(方法 1 と 3 から):

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)

1 行テキストの場合、これは方法 2 と同じように を返すだけですfont.getsize。(複数行テキストの場合は、行に分割して、複数の呼び出しの合計を返しますfont.getsize。)

おすすめ記事