手書き → PDF
手書きサンプルから本物の.ttfを構築し、そのフォントでテキストをレンダリングして、あたかも書き手自身が書いたようなPDFを作成します。すべてローカルで実行され、サンプルがマシンの外に出ることはありません。
あらかじめユーザーに伝えるべき厳しい真実: これは1枚の写真から3000の漢字グリフを invent するAIではありません。フォントに含めることができるのは、サンプルに実際に書かれた文字だけです。つまり、ラテン文字のテキストには約60~100文字、中国語のテキストには文書内のすべての異なる文字(通常は数百文字、数千は非現実的)が必要です。不足している文字は中立的な手書きフォールバックで描画され、その旨が報告されます。決して黙って invent されることはありません。
0. ツールの場所
スキルディレクトリはこのSKILL.mdが置かれているフォルダです。ランチャーを通じてCLIを呼び出します:
- Windows:
<skill>\bin\hwpdf.cmd <command> ... - macOS/Linux:
<skill>/bin/hwpdf <command> ...
ランチャーがない場合は、まずインストールしてください(Windowsでは<skill>\install.ps1、それ以外では<skill>/install.sh)。または、すでに依存関係が利用可能な場合はpython <skill>/scripts/hwpdf.py <command> ...を実行します。hwpdf doctorがstatus okと表示することを最初に確認してください。表示されない場合は、インストーラーを実行し、依存関係エラーを報告してください。自分で対応しようとしないでください。
1. 取り込みフローの選択
| 状況 | フロー |
|---|---|
| デフォルト:ユーザーが本当の手書き文書を望んでいる | A. 練習シート(最高品質、完全自動セルマッピング) |
| ユーザーが手書きが既に含まれているPDFを渡してきた | D. PDF取り込み — まず埋め込みフォントを試し、次にテキストレイヤーからグリフを収穫 |
| ユーザーがすでに手書きの写真を1枚送ってきて、これ以上書きたくない | B. 自由形式写真(エージェントが切り出したグリフにラベル付け) |
ユーザーがすでに独自の.ttf/.otfを持っている | C. フォントのみ — 手順4に進み、プロファイルを保存 |
何かを生成する前に、文書のテキストを尋ねてください。練習シートに必要なのは文書が使用する文字だけなので、短いテキストなら短いシートで済みます。
フローA — 練習シート(推奨)
- 対象テキストをUTF-8ファイル(例:
hw/doc.txt)に保存し、次を実行:
これによりhwpdf template --text-file hw/doc.txt -d hwhw/template.pdf(およびhw/template.json)が作成されます。1ページ30セル、30異なる文字ごとに1ページ。ユーザーに正確に次のように伝えます:- 100% / 実際のサイズで印刷(「用紙に合わせる」は不可);
- 薄い灰色のグリフを濃いペン(0.5 mm以上)でなぞる — ボールペンは薄すぎます;
- 四隅の黒い四角マークが見えていて、マークされていない状態を保つ;
- 各ページを上から均等な光で撮影し、フレームいっぱいに収め、ファイルを送信する。
- 写真をページ順にスキャン:
四隅の四角マークから遠近法と小さな回転が補正されます。出力はhwpdf scan hw/page1.jpg hw/page2.jpg -d hwhw/glyphs.jsonとhw/glyphs/*.png。セルが「欠落」として返ってきた場合、グリフが書かれていないか、薄すぎることを意味します — どの文字かを伝え、それらのセルだけの再撮影を提案します。 - フォントを構築:
hwpdf font -d hw --family "Alex Hand" -o hw/font.ttf - レンダリング前にカバレッジを確認:
終了コードが0以外、またはhwpdf coverage --font hw/font.ttf --text-file hw/doc.txtmissingリストがある場合、それらの文字のグリフがないことを意味します。不足文字だけの小さな2枚目のシートを作成してマージすることで修正:
それ以外の場合は、中立的なフォールバックを受け入れ、その旨を明示的に伝えます。hwpdf template --chars "<missing chars>" -d hw2 hwpdf scan hw2/page1.jpg -d hw --append hwpdf font -d hw -o hw/font.ttf - レンダリング:
hwpdf render --font hw/font.ttf --text-file hw/doc.txt -o hw/letter.pdf --size 12 --paper ruled - 結果を確認。 ページをPNGにレンダリングし、視覚で検査:
判断:ストロークが細すぎる/太すぎる、行間が詰まりすぎている、文字が衝突している、またはマージンからはみ出している、明らかに間違っている点はないか?hwpdf preview --pdf hw/letter.pdf -d hw/preview --dpi 150--size、--leading、--jitter、--weight(フォントを再構築)、--paper none|ruled|gridで修正します。
フローD — ユーザーが手書きのPDFを渡してきた場合
これは、PDFにすでに形状が含まれているため、機能する場合に最も高速な方法です。
- 埋め込みフォントプログラムを試す(最良:完全なグリフセット、再トレース不要):
良い出力 =hwpdf extract-font --pdf user.pdf -d hwhw/fonts/内の.ttf/.otfで、実際の文字マップがあるもの(mapped> 20)。レポートが「subset/cid」と言っている場合はスキップします。 - そうでなく、PDFにテキストレイヤーがある場合(文字を選択できる場合)、レンダリングされたページからグリフを収穫します — テキストレイヤーがラベルを提供し、ラスターがインクを提供します:
hwpdf pdf-specimen --pdf user.pdf -d hw # 彼らのフォントだけを保持するには --font-name "<family>" を追加 hwpdf font -d hw --family "Alex Hand" -o hw/font.ttf - それ以外の場合はスキャンです:
hwpdf rasterize --pdf user.pdf -d hw/pages→ ページ画像に対してフローB、または練習シート(フローA)を依頼します。 - 結果をプロファイルとして保存(下記ステップ5)、その後レンダリング。
フローB — 自由形式写真
hwpdf segment hw/photo.jpg -d hw→hw/contact.png(番号付きサムネイル)+hw/crops/。hw/contact.pngを開き、番号を読み取ります。hw/labels.jsonを{"0":"A","1":"b",...}として作成するか、hwpdf label -d hw --pair "0=A 1=B 2=''"を使用します(""はブロブを削除:ドット、汚れ、ページ端、または2ストロークで描かれた文字の一部)。hwpdf font -d hw --labels hw/labels.json -o hw/font.ttf、その後上記の手順4~6。
筆記体/続け書きと複数ストロークのCJK文字はこのフローをエラー発生しやすくします。結果が悪い場合は、フローAに切り替え、その理由を説明します。
フローC — ユーザーがすでにフォントを持っている場合
hwpdf coverageとhwpdf renderを--font <their file>で実行し、その後プロファイルを保存します。
プロファイル — 安定した再利用可能な方法
プロファイルは、再現に必要なすべてを凍結します:フォントファイル(SHA-256とともにプロファイルにコピー)、そのデフォルト、そしてすぐに貼り付け可能なプロンプト。
hwpdf profile save --name alex --font hw/font.ttf --source "user's handwriting pdf"
hwpdf profile list
hwpdf render --profile alex --text-file letter.txt -o letter.pdf
- プロファイルは
~/.handwriting-pdf/profiles/<name>/に保存されます(profile.json、font.ttf、PROMPT.md)。HWPDF_PROFILE_DIRを設定して保存先を変更できます。 PROMPT.mdはユーザー向けに作成されます:任意のエージェント、任意のマシンに貼り付けると、同じフォントと同じレイアウトデフォルトで呼び出されます。- 見た目を調整する場合:一度に一つの変更を行い、レンダリング、
preview、比較し、その後hwpdf profile save --name alex --font hw/font.ttf --size ... --paper ...で新しいデフォルトにします。font --weight 1で太いストロークに再構築;その後プロファイルを再保存して変更を永続化します。 - PDFから構築されたプロファイルは、そのPDFに含まれる文字のみをカバーします。完全な文書を約束する前に、
hwpdf coverage --font <profile font> --text-file <new doc>で確認します。
合成 (Synth) — ユーザーが書いたことのない文字(実験的)
文書にはほとんどの場合、ユーザーが書いたことのない文字が必要です。中国語では例外ではなく標準です。正直さの順に2つの補完方法があります:
- 中立的フォールバック(デフォルト、予測可能):
render --fallback autoはシステムの手書きフォントを選択します。ページは彼らの手書きと印刷体/中立的な手書きが混ざり、renderはそのように描画されたすべての文字を報告します。 - 合成推論(
hwpdf synth、まだ実験的):彼らのスタイルの測定可能な部分(傾き、ストロークの太さ、xハイト、グリフ幅)を借用し、システムのスケルトングリフにスタンプすることで、完全な文字セットをカバーする2番目のフォントを構築します。
hwpdf synth doctor # どのエンジンが使用可能か、何が不足しているか
hwpdf synth build --style hw/font.ttf --charset common3500 -o hw/synth.ttf
hwpdf synth specimen --font hw/synth.ttf --real hw/font.ttf -o hw/sheet.png # 最初に検査
hwpdf synth verify --font hw/synth.ttf --charset common3500 # カバレッジ / 欠落
hwpdf synth eval --font hw/synth.ttf --real hw/font.ttf -o hw/report.md # レポート用の数値
hwpdf profile save --name alex --font hw/font.ttf --synth-font hw/synth.ttf
hwpdf render --profile alex --text-file doc.txt -o out.pdf # 合成がギャップを埋める
エンジン:stylefit(分析型 — ダウンロード不要、GPU不要、決定論的;中国語グリフはシステムのサンセリフスケルトンを保持し、ユーザーの傾き/太さのみを取得)およびstub(テストフィクスチャ、スタイル変換ではありません)。拡散エンジンdiff-fontはライセンスが未解決の重みが必要です(PLAN.md §8 S4)— synth doctorは偽装せずにそのように伝えます。
それが何であるかを伝える: 彼らが書いた文字は逐語的に再現されます;推論された文字は「印刷されたスケルトン上の彼らの傾きと太さ」です。推論された半分が「彼らに似ている」とユーザーに伝えないでください。出荷前に<font>.jsonのmeta.gate(rejectedは0であるべき)を確認し、見本を見てください。
ルール
- ローカルのみ。 サンプル、フォント、出力を決してアップロードしないでください。API呼び出しはありません。
- ユーザー自身の手書きのみ。 第三者の手書き、署名、レターヘッドの模倣は拒否し、署名/契約書/証明書/公式文書の生成も拒否します — 簡単に説明し(偽造、詐欺、証拠規則)、代わりに通常のタイプ文書を提案します。
- 品質を決して偽らない。 フォントが40グリフなら40と言います。フォールバックがページの半分を描画したなら、そう伝えます。欠落文字をそのまま報告します。
- ツールのせいにする前に再撮影を依頼する: ぼやけ、影、角の欠け、またはグリッド線で覆われた写真が最も一般的な失敗原因です。
- 作業ディレクトリ(
hw/)を保持します — ユーザーは後で文字を追加し、フォントを再構築できます。
コマンドリファレンス
| コマンド | 目的 |
|---|---|
hwpdf doctor | 依存関係 + システムフォントチェック |
hwpdf template --chars "abc" / --text-file doc.txt -d DIR | 練習シートPDF + メタデータ |
hwpdf scan IMG... [-d DIR] [--rotate 90] [--append] | 撮影したシート → グリフマスク(append = 既存の作業にマージ) |
hwpdf extract-font --pdf in.pdf -d DIR | PDFから埋め込みフォントを抽出(最良ケース:完全なTTF) |
hwpdf pdf-specimen --pdf in.pdf -d DIR [--font-name F] | PDFのテキストレイヤー + ラスターからラベル付きグリフを収穫 |
hwpdf rasterize --pdf in.pdf -d DIR [--dpi 300] | スキャンPDF → ページPNG |
hwpdf segment IMG... [-d DIR] [--thresh N] [--deskew] | 自由形式写真 → ブロブ + コンタクトシート |
hwpdf label -d DIR --order "ABC" / --pair "0=A 1=B" | ブロブを文字にマッピング |
hwpdf font -d DIR [--labels f] [--family NAME] [--weight -2..2] [--smooth 0..2] -o out.ttf | フォントを構築 |
hwpdf coverage --font f --text-file doc.txt | どの文字が欠落しているか |
hwpdf render --font f --text-file doc.txt -o out.pdf [--size 12] [--leading 1.8] [--paper ruled] [--jitter 1] [--ink "#1a1c24"] [--fallback auto|none|path] | PDF(--font system:cjk / system:latin = 組み込み手書きフォント。ユーザーにサンプルがなく、手書き風の見た目だけを望む場合) |
hwpdf render --profile NAME --text-file doc.txt -o out.pdf | 保存されたプロファイルのフォント + デフォルトを使用したPDF |
hwpdf profile save/list/show/remove ... | 再利用可能な手書きプロファイルを凍結/検査(PROMPT.mdを書き込み) |
hwpdf preview --pdf out.pdf -d DIR [--dpi 150] | PDFページ → 視覚レビュー用PNG |
hwpdf synth doctor / build / specimen / verify / charsets | オプションの推論エンジン:書かれたサブセットから完全な文字セットフォントを生成(合成セクションを参照) |
hwpdf selftest -d DIR [--messy] | 合成エンドツーエンドスモークテスト |
制限(関連する場合に明示)
- 文字ごとに1グリフ:筆記体の繋がりや、出現間の自然なばらつき、筆圧/インクのテクスチャはありません。スペーシングのジッターはシミュレートされますが、グリフ形状はシミュレートされません。
- CJK:フォントには書かれた文字のみが含まれます。1ページ30セル;300文字の手紙には10ページの練習シートが必要です。
hwpdf synth build --charset common3500はショートカットですが、推論されたCJKはユーザーの傾きを持つシステムサンセリフスケルトンであり、実際の筆致ではありません。 - PDFのテキストレイヤーは、生成されたフォントで実際のテキスト(検索可能/コピー可能)です。
- 写真には練習シートの四隅すべての黒い四角マークが写っている必要があります。