已知CourierNewPSMT字体,如何解析PDF中的CID编码文本?
解析CourierNewPSMT字体对应的CID编码文本
1. 直接从PDF字体中提取CID映射表
大部分情况下,PDF里的嵌入字体即使没有ToUnicode表,也会包含内部的CID到字符的映射。用fitz(PyMuPDF)可以直接获取这层映射:
import fitz doc = fitz.open("your_file.pdf") page = doc[0] # 取目标页面 # 遍历页面字体 for font in page.get_fonts(): font_id = font[0] font_name = font[3] if font_name == "CourierNewPSMT": # 获取字体的CID映射 cid_map = doc.extract_font(font_id).get("cid_to_unicode") # 测试映射:比如cid:3 if 3 in cid_map: print(f"cid:3 对应字符: {cid_map[3]}")
如果extract_font返回的字典里没有cid_to_unicode,可以尝试读取字体的原始cmap表,用fonttools库解析:
from fonttools.ttLib import TTFont # 先提取字体文件到本地 font_data = doc.extract_font(font_id)["fontfile"] with open("courier_new_psmt.ttf", "wb") as f: f.write(font_data) # 解析字体的cmap表 ttfont = TTFont("courier_new_psmt.ttf") cmap = ttfont.getBestCmap() # CID通常对应cmap中的键,直接查找 print(f"cid:3 对应字符: {chr(cmap[3])}")
2. 确认CourierNewPSMT的ROS规则
CourierNewPSMT属于Adobe标准拉丁字符集的CID字体,对应的ROS是Adobe-Identity-0(Registry=Adobe, Ordering=Identity, Supplement=0)。这类字体的CID编码直接对应字体内部的字符索引,不需要额外的ROS映射表,只需要读取字体本身的cmap映射即可。
3. 扩展暴力破解的映射表
如果你已经有部分CID-字符的映射,可以结合CourierNewPSMT的字符集(基本拉丁、拉丁扩展A/B等)来补全:
- 该字体的CID顺序通常和Unicode的基本拉丁区(U+0020到U+007E)、扩展拉丁区(U+00A0到U+00FF)顺序对应
- 可以通过对比已破解的CID和对应Unicode值,推断出CID与Unicode的偏移量,批量生成完整映射
4. 处理无映射的极端情况
如果上述方法都失效,还可以通过PDF的内容流反向推导:
# 提取页面的原始内容流 content = page.get_text("raw") # 查找包含(cid:xxx)的片段,结合字体的绘制指令,匹配字符形状对应的Unicode # 或者用OCR工具(比如pytesseract)识别页面区域,对应CID位置的字符
内容的提问来源于stack exchange,提问作者Franciska
相关产品推荐
相关产品推荐

