python - 使用 PyPDF2 检测 PDF 中的 Embedded Subset 字体
问题描述
我使用 PyPDF2 修改了以下脚本以遍历 PDF 并确定 PDF 是否包含未嵌入的字体。它适用于找出 PDF 中所有字体的列表,以及其中嵌入了哪些字体。但是,某些 PDF 具有仅嵌入所用字体子集的字体(请参阅https://blogs.mtu.edu/gradschool/2010/04/27/how-to-determine-if-fonts-are-embedded / ) - 如何确定 PDF 中是否嵌入了字体子集?谢谢!
from PyPDF2 import PdfFileReader
import sys
fontkeys = set(['/FontFile', '/FontFile2', '/FontFile3'])
def walk(obj, fnt, emb):
if '/BaseFont' in obj:
fnt.add(obj['/BaseFont'])
elif '/FontName' in obj and fontkeys.intersection(set(obj)):
emb.add(obj['/FontName'])
for k in obj:
if hasattr(obj[k], 'keys'):
walk(obj[k], fnt, emb)
if type(obj) == PyPDF2.generic.ArrayObject: # You can also do ducktyping here
for i in obj:
if hasattr(i, 'keys'):
walk(i, all_fonts, embedded_fonts)
return fnt, emb
if __name__ == '__main__':
fname = sys.argv[1]
pdf = PdfFileReader(fname)
fonts = set()
embedded = set()
for page in pdf.pages:
obj = page.getObject()
f, e = walk(obj['/Resources'], fonts, embedded)
fonts = fonts.union(f)
embedded = embedded.union(e)
unembedded = fonts - embedded
print 'Font List'
pprint(sorted(list(fonts)))
if unembedded:
print '\nUnembedded Fonts'
pprint(unembedded)
解决方案
按照惯例,PDF 文件中子集字体的 PostScript 名称的名称以 XXXXXX+ 开头,其中“X”是任何大写的 ASCII 字符。
请参阅 PDF 参考手册(1.7 版)的第 5.3 节
此外,字体描述符中存在的 CharSet 或 CIDSet 可用于指示子集字体(这两个都是可选的)。
但是,所有这些都是“约定”,没有实际的保证方法可以确保没有任何这些约定的字体实际上不是子集字体。
推荐阅读
- c# - 无法隐式转换字典列表
ICollection 的类型参数 - c# - SerialPort.GetPortNames() 导致 ContextSwitchDeadlock 异常,为什么?
- c99 - 我是否正确阅读了 C99 语法?
- javascript - 从数据组件访问上传的文件
- javascript - 如何将数据从节点 js 发布到 codeigniter?
- java - @ApplicationPath 注解可以用在接口上吗?
- node.js - Docker容器在运行时抛出错误
- apache-nifi - Nifi 通过进程组传递属性
- php - 提交 CI 表单时没有任何反应
- google-cloud-firestore - 了解分布式系统中的一致性