PDFへのフォント埋め込みの有無の確認
PDFはテキスト、フォント、画像などが記述されたファイルであり、アプリケーションで開くたびにレンダリングがなされています。そのため、PDFで指定されたフォントがPDFをレンダリングする環境に存在しないと、文書をうまく表示できず、文字化けしてしまいます。このように、PDFを開く環境によって文字化けしてしまうと困るので、環境に依存せず等しく表示できるようにPDFにフォントが埋め込まれていることがあります。pythonでPDFへのフォント埋め込みの有無を確認することができるのでその方法をまとめます。
環境
Goole colabratory
実装
使用する際はPDF_PATHを実際のPATHに書き換えてください。
# モジュールのインストール
!pip -q install PyPDF2
from PyPDF2 import PdfReader
# PATHを自分のPDFに合わせて置き換え
PDF_PATH = "/content/****.pdf"
def list_fonts_with_embedding(pdf_path: str):
reader = PdfReader(pdf_path)
seen = {}
for page in reader.pages:
resources = page.get("/Resources")
if not resources:
continue
resources = resources.get_object()
fonts = resources.get("/Font")
if not fonts:
continue
fonts = fonts.get_object()
for name, fref in fonts.items():
f = fref.get_object()
base = str(f.get("/BaseFont", ""))
subtype = str(f.get("/Subtype", ""))
embedded = False
embed_key = None
# まずは直下の FontDescriptor を見る
fd = f.get("/FontDescriptor")
if fd:
fd = fd.get_object()
for k in ("/FontFile", "/FontFile2", "/FontFile3"):
if k in fd:
embedded = True
embed_key = k
break
# Type0 (CID) の場合は DescendantFonts を辿る
if not embedded and subtype == "/Type0":
desc = f.get("/DescendantFonts")
if desc:
try:
df = desc[0].get_object()
base = str(df.get("/BaseFont", base))
fd2 = df.get("/FontDescriptor")
if fd2:
fd2 = fd2.get_object()
for k in ("/FontFile", "/FontFile2", "/FontFile3"):
if k in fd2:
embedded = True
embed_key = k
break
except Exception:
pass
seen[(base, subtype)] = (embedded, embed_key)
rows = []
for (base, subtype), (embedded, embed_key) in sorted(seen.items()):
rows.append({
"使用フォント名": base,
"フォント形式": subtype,
"埋め込み有無": embedded, # ← ここが True なら埋め込み
"格納ストリーム": embed_key # /FontFile /FontFile2 /FontFile3 のどれか
})
return rows
rows = list_fonts_with_embedding(PDF_PATH)
for r in rows:
print(r)
実行例
実際に実行すると、以下のような出力になります。
{'使用フォント名': '/CTNVZN+CMBX12', 'フォント形式': '/Type1', '埋め込み有無': True, '格納ストリーム': '/FontFile3'}
{'使用フォント名': '/EBDEKI+CMMI9', 'フォント形式': '/Type1', '埋め込み有無': True, '格納ストリーム': '/FontFile3'}
{'使用フォント名': '/FHMYDA+CMR7', 'フォント形式': '/Type1', '埋め込み有無': True, '格納ストリーム': '/FontFile3'}
{'使用フォント名': '/FJZRGE+CMMI10', 'フォント形式': '/Type1', '埋め込み有無': True, '格納ストリーム': '/FontFile3'}
{'使用フォント名': '/HGLWXW+CMBX9', 'フォント形式': '/Type1', '埋め込み有無': True, '格納ストリーム': '/FontFile3'}
{'使用フォント名': '/IJGBIV+CMR9', 'フォント形式': '/Type1', '埋め込み有無': True, '格納ストリーム': '/FontFile3'}
フォントの種類ごとに結果が表示され、'埋め込み有無'がTrueになっていれば埋め込みがなされています。