◇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化したものも置きました
| 固定リンク

