◇ChatGPTでフォント情報取得プログラム生成

ChatGPTだけでプログラム
"C:/Windows/Fonts"下のttcファイルを読み、情報をCSVに落とすプログラムをChatCPTで作成しました。
ChatGPTに対しいろいろ誘導は行いましたが、生成したコードは完全にChatCPTによるものです。
型にはまったプログラムの作成には役に立ちますね。
しかし、知恵がある訳ではないので、人間相手のように、ヒントを与えるとそれを学びながら、賢くなっていくということはなく、失敗を学習することもないので、間違った解答がループすることも多くあります。
Aの間違いを指摘すると、Bを出し、その間違いを指摘するとまたAを出すといった形です。間違った解答がループしていることを認識できないようで、「その解答は前に間違いだと指摘した」と言っても同じ解答が繰り返されます。
for文の書き方だとか、細かい質問は役にたちますが、まだ大きなものは難しいですね。
そんな中、この成果が得られました。
こういう形でフォント情報を拾い出します。
フォントファイル,フォント名,属性名,値,説明 BIZ-UDGothicB.ttc,BIZ UDゴシック - Bold,-,-,- -,-,Ascender,1802,フォントの上部の最大高さ -,-,Descender,-246,フォントの下部の最大の深さ -,-,Line Gap,0,行間の追加のスペース -,-,Font Width,1108,フォントの幅 -,-,Font Height,2048,フォントの高さ -,-,tableTag,OS/2,不明 -,-,version,3,テーブルのバージョン -,-,xAvgCharWidth,1024,平均文字幅 -,-,usWeightClass,700,フォントのウェイトクラス -,-,usWidthClass,5,フォントの幅クラス -,-,fsType,4,フォントのタイプフラグ -,-,ySubscriptXSize,1024,下付き文字のXサイズ -,-,ySubscriptYSize,1556,下付き文字のYサイズ -,-,ySubscriptXOffset,0,下付き文字のXオフセット -,-,ySubscriptYOffset,307,下付き文字のYオフセット -,-,ySuperscriptXSize,1024,上付き文字のXサイズ -,-,ySuperscriptYSize,1556,上付き文字のYサイズ -,-,ySuperscriptXOffset,0,上付き文字のXオフセット -,-,ySuperscriptYOffset,0,上付き文字のYオフセット -,-,yStrikeoutSize,102,打ち消し線の太さ -,-,yStrikeoutPosition,727,打ち消し線の位置 -,-,sFamilyClass,0,フォントファミリーのクラスおよびサブクラス -,-,ulUnicodeRange1,3758097143,Unicode範囲1 -,-,ulUnicodeRange2,717745656,Unicode範囲2 -,-,ulUnicodeRange3,18,Unicode範囲3 -,-,ulUnicodeRange4,0,Unicode範囲4 -,-,achVendID,MRSW,ベンダーIDを示す4文字のASCII文字列 -,-,fsSelection,32,フォントの選択フラグ -,-,usFirstCharIndex,32,使用可能な最初の文字のインデックス -,-,usLastCharIndex,65535,使用可能な最後の文字のインデックス -,-,sTypoAscender,1802,タイポグラフィのアセンダー -,-,sTypoDescender,-246,タイポグラフィのディセンダー -,-,sTypoLineGap,0,タイポグラフィのラインギャップ -,-,usWinAscent,1802,Windowsでのアセンダーの値 -,-,usWinDescent,246,Windowsでのディセンダーの値 -,-,ulCodePageRange1,537001985,コードページ範囲1 -,-,ulCodePageRange2,0,コードページ範囲2 -,-,sxHeight,1108,不明 -,-,sCapHeight,1567,大文字の高さ -,-,usDefaultChar,0,デフォルトの文字インデックス -,-,usBreakChar,32,改行文字のインデックス -,-,usMaxContext,6,コンテキストの最大数 BIZ-UDGothicR.ttc,BIZ UDゴシック - Regular,-,-,- -,-,Ascender,1802,フォントの上部の最大高さ -,-,Descender,-246,フォントの下部の最大の深さ -,-,Line Gap,0,行間の追加のスペース -,-,Font Width,1108,フォントの幅 -,-,Font Height,2048,フォントの高さ ・・・
一番重要なのはファイル名とフォント名の対応ですが、その他も気になる情報ですので、抜き出すようにしました。
生成されたコード
import csv import os import argparse from typing import Any, Dict, List, Tuple from fontTools.ttLib import TTCollection # os2_tableの属性名と説明の辞書 os2_table_attr_descriptions: Dict[str, str] = { "achVendID": "ベンダーIDを示す4文字のASCII文字列", "fsFirstCharIndex": "使用可能な文字の最初のインデックス", "fsLastCharIndex": "使用可能な文字の最後のインデックス", "fsSelection": "フォントの選択フラグ", "fsType": "フォントのタイプフラグ", "panose": "フォントのPANOSEナンバー", "sCapHeight": "大文字の高さ", "sFamilyClass": "フォントファミリーのクラスおよびサブクラス", "sTypoAscender": "タイポグラフィのアセンダー", "sTypoDescender": "タイポグラフィのディセンダー", "sTypoLineGap": "タイポグラフィのラインギャップ", "ulCodePageRange1": "コードページ範囲1", "ulCodePageRange2": "コードページ範囲2", "ulUnicodeRange1": "Unicode範囲1", "ulUnicodeRange2": "Unicode範囲2", "ulUnicodeRange3": "Unicode範囲3", "ulUnicodeRange4": "Unicode範囲4", "usBreakChar": "改行文字のインデックス", "usDefaultChar": "デフォルトの文字インデックス", "usFirstCharIndex": "使用可能な最初の文字のインデックス", "usLastCharIndex": "使用可能な最後の文字のインデックス", "usMaxContex": "コンテキストの最大数", "usMaxContext": "コンテキストの最大数", "usWeightClass": "フォントのウェイトクラス", "usWidthClass": "フォントの幅クラス", "usWinAscent": "Windowsでのアセンダーの値", "usWinDescent": "Windowsでのディセンダーの値", "version": "テーブルのバージョン", "xAvgCharWidth": "平均文字幅", "yStrikeoutPosition": "打ち消し線の位置", "yStrikeoutSize": "打ち消し線の太さ", "ySubscriptXOffset": "下付き文字のXオフセット", "ySubscriptXSize": "下付き文字のXサイズ", "ySubscriptYOffset": "下付き文字のYオフセット", "ySubscriptYSize": "下付き文字のYサイズ", "ySuperscriptXOffset": "上付き文字のXオフセット", "ySuperscriptXSize": "上付き文字のXサイズ", "ySuperscriptYOffset": "上付き文字のYオフセット", "ySuperscriptYSize": "上付き文字のYサイズ", } # フォントメトリクスの説明の辞書 font_metrics_descriptions: Dict[str, str] = { "Ascender": "フォントの上部の最大高さ", "Descender": "フォントの下部の最大の深さ", "Line Gap": "行間の追加のスペース", "Font Width": "フォントの幅", "Font Height": "フォントの高さ", } def parse_args(): parser = argparse.ArgumentParser(description="Extract font information from TTC files to CSV") parser.add_argument("directory", help="The directory containing TTC font files") parser.add_argument("-out", help="Output CSV file name", default="font_info.csv") parser.add_argument("-omit", nargs="*", help="Attributes to omit") return parser.parse_args() def get_font_info(font_file_name: str, output_file: str, omit: List[str]) -> None: try: ttc: TTCollection = TTCollection(font_file_name) font: Any = ttc.fonts[0] # 最初のフォントを選択 # フォント情報を取得 family_name: str style_name: str family_name, style_name = get_font_name(font) font_metrics: List[Tuple[str, int]] = get_font_metrics(font) # CSVに書き込み with open(output_file, "a", newline="", encoding="utf-8") as csvfile: writer: Any = csv.writer(csvfile) if os.path.getsize(output_file) == 0: # ファイルが空の場合 writer.writerow(["フォントファイル", "フォント名", "属性名", "値", "説明"]) # ヘッダー行を書き込む writer.writerow([os.path.basename(font_file_name), f"{family_name} - {style_name}", "-", "-", "-"]) for info in font_metrics: if info[0] not in omit: writer.writerow(["-", "-", info[0], info[1], font_metrics_descriptions.get(info[0], "-")]) # os2_tableの属性を書き込み for attr_name, attr_value in font["OS/2"].__dict__.items(): if not attr_name.startswith("__") and attr_name not in omit: attr_description: str = os2_table_attr_descriptions.get(attr_name, "不明") writer.writerow(["-", "-", attr_name, attr_value, attr_description]) except Exception as e: print(f"Error processing {font_file_name}: {e}") def get_font_name(font: Any) -> Tuple[str, str]: family_name: str = None style_name: str = None if "name" in font: for name in font["name"].names: if name.nameID == 1: family_name = name.string.decode(name.getEncoding()) elif name.nameID == 2: style_name = name.string.decode(name.getEncoding()) return family_name, style_name def get_font_metrics(font: Any) -> List[Tuple[str, int]]: font_info: List[Tuple[str, int]] = [] try: if "OS/2" in font: os2_table: Any = font["OS/2"] font_info.append(["Ascender", os2_table.sTypoAscender]) font_info.append(["Descender", os2_table.sTypoDescender]) font_info.append(["Line Gap", os2_table.sTypoLineGap]) font_info.append(["Font Width", getattr(os2_table, 'sxHeight', 0)]) # sxHeightがない場合はデフォルトの値を使う font_info.append(["Font Height", os2_table.sTypoAscender - os2_table.sTypoDescender + os2_table.sTypoLineGap]) except Exception as e: print(f"Error processing font metrics: {e}") return font_info if __name__ == "__main__": args = parse_args() # 既存のCSVファイルがあれば削除 if os.path.exists(args.out): os.remove(args.out) fonts_dir: str = args.directory for filename in os.listdir(fonts_dir): if filename.lower().endswith(".ttc"): font_path: str = os.path.join(fonts_dir, filename) print(f"Processing {filename}") get_font_info(font_path, args.out, args.omit if args.omit else [])
ダウンロード
コードは次の場所からダウンロードできます。
http://k-hiura.cocolog-nifty.com/blog/files/fontinfo.zip
次のものからなっています。
fontInfo +-- getFontCSV.py ChatCPTが生成したコード +-- getFontCSV.bat getFontCSV.pyを起動するバッチ +-- font_info.csv getoFontCSV.pyの出力 `-- font_info.xlsx csvから作ったexcel
参考までに◇複数CSVから複数シートのEXCEL-BOOKを作るのツールを用いてexel化したものも置きました
| 固定リンク