0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PIL で生成した図の文字は、目視だけでははみ出しを取り切れなかった——3 件見逃し → レイアウト検査 4 種で 0

0
Posted at

記事用の図 8 枚を Pillow(PIL)で生成して、目で見て直して「もう大丈夫」と思ってから、生成器に「はみ出し検査」を足して数えたら、3 件残っていました。目視で取れる欠陥と機械で取れる欠陥は別物だった、という短い記録です。人 vs 機械ではなく、人+機械の話。

この記事の位置づけ(2026-09-26 追記)

  • この記事で新しく示すこと: 目視で直した図 8 枚に機械のはみ出し検査で 3 件残っていたこと。逆に、フォントに無い字の欠落は目視だけが見つけたこと。
  • 当てはまる範囲: Pillow で作った当方の図 8 枚です。
  • 言葉: 本文の「器」=点検や処理のための自作スクリプト、「毒」=チェックが効くか確かめるためにわざと壊した入力のことです。

時系列

  1. 8 枚を生成 → 目視で c1・c2 のフッターと最下段の切れを見つけて直す
  2. 「もう大丈夫」と判断して見せる → 指摘「所どころ文字が枠からはみ出ている」
  3. 生成器に レイアウト検査 4 種(はみ出し 3 種+重なり 1 種)を足す(描いた文字を全部記録して数える)
  4. さらに規則違反 3 件(安全余白への侵入 2・枠外右 1)が出る → 直す → 0

描画ログのレイアウト検査 4 種(右端の安全余白への侵入 2・枠外右 1・枠外下 0・重なり 0)と、検査が見ないもの(フォントに無い字の欠落・折り返し規則)。目視と機械は見るものが違う

レイアウト検査 4 種(生成器に埋め込んだ・簡易)

ImageDraw.text を包んで、描いた文字の左上・右端・行の高さを全部記録し、rect() で描いた枠も記録します。書き出す前に数えるのは 4 つ:

検査 条件 今回捕まえた
右端の安全余白(40 px)への侵入 文字の右端 > 画像幅 − 40(画像の外ではない) 2 件(右列のラベルと赤い注記・1580/1590 px・画像幅 1600)
枠外(右) 文字の左端を含む最小の枠の右端 − 12 を越える 1 件(39〜44 px 越え)
枠外(下) 文字の下端が枠の下端 − 4 を越える 0
文字の重なり 同じ行帯で x 範囲が重なる 0
_TEXTS, _RECTS = [], []
_orig = ImageDraw.ImageDraw.text
def _logged(self, xy, text, fill=None, font=None, *a, **k):
    _orig(self, xy, text, fill=fill, font=font, *a, **k)
    for i, ln in enumerate(str(text).split(chr(10))):
        _TEXTS.append((xy[0], xy[1] + i * font.size * 1.2, xy[0] + font.getlength(ln), ln, font.size))
ImageDraw.ImageDraw.text = _logged
# rect() で _RECTS に (x0, y0, x1, y1) を積み、save() の直前に 4 種を数えて 🔴 で印字。0 になるまで書き出さない

検査が見ていないもの(ここが本題)

レイアウト検査 4 種が 0 でも、今回使ったフォントに無い字(≥・β・✓・絵文字)が空白で描かれた欠落は、この検査では見えません。字集合との照合という別系統の検査です。目視で見つけたのはこちらでした。

逆に、目視で見逃した 3 件は数 px の越えで、縮小表示ではほぼ見えません。目視=全体の違和感と欠落/描画ログ検査=今回の描画条件で数 px の越えを機械的に拾う(getlength(文字送りの長さ)と行高の近似で、実際の描画 bbox ではない=字形が送り幅の外へ出る場合は捕まえない。厳密にするなら同じ描画条件で textbbox() を使う。この記事では「bbox 検査」と呼ばず「描画ログの簡易レイアウト検査」と呼びます)。見るものが違うので、どちらかで代替できません。

もう 1 つ。折り返し関数が「(」の直後で折れない規則になっていて、(bold-chars.txt) のような長い英字が枠を越えていました。検査は「越えた」を数えるだけで、原因(折り返し規則)は教えません。原因は現物を見て直す。

手順として

  1. 生成器に「描いた文字を全部記録する」フックを 1 本入れる
  2. 書き出す前に安全余白への侵入・枠外(右/下)・重なりを数える。0 になるまで書き出さない
  3. 検査が見ている範囲を名乗らせる(レイアウト 4 種/glyph 欠落は別)
  4. 目視は残す。見るのは全体の違和感と欠落で、数 px は機械に任せる
  5. 折り返し規則とフォントの字集合は、生成の前に毒(長い英字・無い字)で確かめる

検査器は人の目を置き換えるものではなく、人が苦手なところ(数 px・8 枚全部)だけを機械に渡すためのもの。


本家(検証の記録つき)

この記事の本家(検証環境・判定・証拠)は Sumitsuke Lab → 目視と bbox 検査は見るものが違う(検証の記録つき)。

AI の利用について

生成器と検査のコードは AI(Claude Code)が書き、目視の判定・「見ている範囲」の切り分け・公開の判断は人間が行いました。図は自分の記事のもの。

関連

検査器の収支を数える話は 緑を信じない——捕まえた 5 件・直した 22 件(失敗パターン実測録 #04・型③「器が別の物を見ている」の続き)。

次に読む: 検査を足す前に器の収支を数える——捕まえた 5 件と直した 22 件


この記事は Zenn にも同じ内容を掲載しています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?