引き続きStraightanswer.orgの改良を続けています。

Straightanswer.orgでは各問いと回答のOG画像に、回答を全文含めるようにしています。

今回の変更前は、全角文字と半角文字の両方がが回答に含まれていると、OG画像内の文字がガタガタになってしまっていました。

改良後のOG画像

これは改良後のOG画像です。

満足いくできに至っていませんが、改良前よりはだいぶマシになったと思います。

今回の改良前後の画像の比較

改良前のOG画像

これが変更前のOG画像の例です。

改良後のOG画像

これが同じ回答の変更後のOG画像です。

変更点

元々、Pythonのtextwrap.wrap関数ですべての文字を同じ幅として扱っていました。textwrap.wrapは指定の文字数で文字列を分割します。この分割された文字列のListを改行文字で結合してPillowに渡していました。

これをunicodedata.east_asian_width関数を使って、幅を1と2に分けて数えるようにしました。

抜粋した関数です。

def _compute_width(character: str) -> int:
    if unicodedata.east_asian_width(character) in {"F", "W", "A"}:
        return 2
    return 1

def wrap(text: str, max_width: int) -> Iterator[str]:
    assert max_width > 1
    line_width = 0
    line = []
    for character in text:
        width = _compute_width(character)
        if line_width + width > max_width:
            line_width = 0
            yield "".join(line)
            line = []
        line_width += width
        line.append(character)
    if line_width:
        yield "".join(line)

このwrapの返す文字列のIteratorを改行文字で結合してPillowに渡しています。

さらに改良したい点

等幅フォントを使っていないので、半角文字の幅がまちまちです。そのため、例にしたOG画像もですが一行の長さがまちまちになっています。等幅フォントを使って一行の長さを揃えたいのですが、Pillowに複数のフォントを指定することができないようで、実現できていません。今使っているNoto Sansは日本語フォントと等幅フォントが分かれています。

もう一つ、Twitterで形態素解析を使う案を教えてもらったのですが、これも実現できていません。

Straightanswer.orgの宣伝

Straightanswer.org

Straightanswer.orgにあなたの知識を分けてくれませんか?