PyMuPDF 1.24.4 中文文档(七)(4)https://developer.aliyun.com/article/1559548
警告:
从 PDF 中返回的基本名称不变。因此,它可能包含(例如空格)可能使其不适合作为操作系统文件名的字符。请采取适当措施。
注意:
- 一般返回的basename 不是原始文件名,但可能具有某些相似性。
- 如果参数
named == True
,则返回具有以下键的字典:{'name': 'T1', 'ext': 'n/a', 'type': 'Type3', 'content': b''}
。
xref_xml_metadata()
- 新功能,版本为 v1.16.8
仅限 PDF:返回文档的 XML 元数据的xref
。
has_links()
has_annots()
- 新功能,版本为 v1.18.7
仅限 PDF:检查文档中是否有链接或批注。
返回值:
True / False。与字段相反,字段也存储在 PDF 文档的中心位置,链接/批注的存在只能通过解析每个页面来检测到。这些方法被调整为高效地执行此操作,并在对于页面答案为True时立即返回。但是,对于有数千页的 PDF,如果未找到链接/批注,则答案可能需要一些时间[6]。
subset_fonts(verbose=False, fallback=False)
仅限 PDF:研究文档中的文本可用字体。如果支持某个字体并且可以减小大小,则将该字体替换为其字符子集版本。
在保存文档之前立即使用此方法。
参数:
- verbose (bool) – 将各种进度信息写入 sysout。这目前仅在
fallback
为True
时才会生效。 - fallback(bool)– 如果为
True
,则使用使用包fontTools的废弃算法(因此必须安装)。如果使用建议的值False
(默认),则使用 MuPDF 的本机功能 – 这非常快速,并且可以对更广泛的字体类型进行子集化。然后不需要安装包 fontTools。
在创建使用大型字体(通常用于亚洲文字的字体)的新 PDF 时,可以获得最大的好处。当使用 Story 类或方法Page.insert_htmlbox()
时,可能会自动包含多个字体,而程序员可能并不知晓。
在所有这些情况下,实际使用的 Unicode 集合大多数情况下与使用的字体中可用的字形数量相比非常小。使用这种方法可以轻松将嵌入的字体二进制文件减少两个数量级,从几兆字节减少到几十千字节。
创建字体子集会留下大量未使用的 PDF 对象(“幽灵”)。因此,在保存文件时,请务必进行压缩和垃圾回收。我们建议使用Document.ez_save()
。
显示/隐藏历史记录 * 新功能在 v1.18.7 版本中引入。
- v1.18.9 版本中更改。
- v1.24.2 版本中更改为使用 MuPDF 的本机功能。
journal_enable()
- 新功能在 v1.19.0 版本中引入。
仅 PDF:启用日志记录。在开始记录操作之前使用此功能。
journal_start_op(name)
- 新功能在 v1.19.0 版本中引入。
仅 PDF:开始记录由字符串“name”标识的*“操作”*。如果 PDF 启用了日志记录,但尚未开始操作,则更新将失败。
journal_stop_op()
- 新功能在 v1.19.0 版本中引入。
仅 PDF:停止当前操作。在操作的开始和结束之间进行的更新属于同一工作单元,并将一起撤销/重做。
journal_position()
- 新功能在 v1.19.0 版本中引入。
仅 PDF:返回当前操作编号和总操作计数。
返回:
一个元组(step, steps)
包含当前操作编号和日志中操作总数。如果step为 0,则表示位于日志顶部。如果step等于steps,则表示位于底部。更新 PDF 时,除了撤销或重做外,还将自动删除当前条目之后的所有日志条目,并且新更新将成为日志中的最后一个条目。被删除日志条目对应的更新将永久丢失。
journal_op_name(step)
- 新功能在 v1.19.0 版本中引入。
仅 PDF:返回操作编号为step的名称。
journal_can_do()
- 新功能在 v1.19.0 版本中引入。
仅 PDF:显示当前日志位置是否可以向前(“重做”)和/或向后(“撤销”)执行。
返回:
一个字典{"undo": bool, "redo": bool}
。如果值为True
,则相应的方法可用。
journal_undo()
- 新功能在 v1.19.0 版本中引入。
仅 PDF:撤销日志中的当前步骤。这将移动到日志的顶部。
journal_redo()
- 新功能在 v1.19.0 版本中引入。
仅 PDF:重新应用(重做)日志中的当前步骤。这将移动到日志的底部。
journal_save(filename)
- v1.19.0 中新增
仅限 PDF:将期刊保存到文件。
参数:
filename(str*,*fp) - 可以是字符串形式的文件名,也可以是以“wb”方式打开的文件对象(或者是io.BytesIO()
对象)。
journal_load(filename)
- v1.19.0 中新增
仅限 PDF:从文件加载期刊。启用文档的期刊记录。如果已启用期刊记录,则会引发异常。
参数:
filename(str*,*fp) - 期刊的文件名(字符串)或以“rb”方式打开的文件对象(或者是io.BytesIO()
对象)。
save_snapshot()
- v1.19.0 中新增
仅限 PDF:保存文档的“快照”。这是一种具有特殊的增量保存格式的 PDF 文档,与期刊兼容 - 因此不提供保存选项。对于新文档,无法保存快照。
这是一份普通的 PDF 文档,没有任何使用限制。如果未作任何更改,则可与其期刊一起使用以执行撤销/重做操作或继续更新。
outline
包含文档的第一个 Outline 条目(或None
)。可以作为遍历所有大纲项目的起点。对于加密但未经过身份验证的文档,访问此属性将引发AttributeError。
类型:
Outline
is_closed
False 表示文档仍处于打开状态。如果已关闭,则大多数其他属性和方法将已删除/禁用。此外,对于引用此文档的 Page 对象(即使用Document.load_page()
创建的对象)及其依赖对象将不再可用。为了参考,Document.name
仍然存在,并将包含原始文档的文件名(如果适用)。
类型:
bool
is_dirty
True 表示这是一个 PDF 文档且包含未保存的更改,否则为False。
类型:
bool
is_pdf
True 表示这是一个 PDF 文档,否则为False。
类型:
bool
is_form_pdf
False 表示这不是 PDF 文档或没有表单字段,否则为根表单字段的数量(没有祖先的字段)。
(v1.16.4 中更改) 返回(根)表单字段的总数。
类型:
bool,int
is_reflowable
True 表示文档具有可变的页面布局(如电子书或 HTML)。在这种情况下,您可以在文档创建(打开)过程中或通过layout()
方法设置所需的页面尺寸。
类型:
bool
is_repaired
- v1.18.2 中新增
True 表示在打开过程中修复了 PDF(因为存在重大结构问题)。对于非 PDF 文档始终为False。如果为真,则更多详细信息已存储在TOOLS.mupdf_warnings()
中,并且Document.can_save_incrementally()
将返回False。
类型:
bool
is_fast_webaccess
- v1.22.2 中新增
True 表示 PDF 处于线性化格式。对于非 PDF 文档,则为False。
类型:
bool
markinfo
- v1.22.2 中新增
指示/MarkInfo
值的字典。如果未指定,则返回空字典。如果不是 PDF,则返回None
。
类型:
dict
pagemode
- v1.22.2 中新增
包含 /PageMode
值的字符串。如果未指定,默认返回“UseNone”。如果不是 PDF,则返回 None
。
类型:
str
pagelayout
- 新功能在 v1.22.2 版本中引入
包含 /PageLayout
值的字符串。如果未指定,默认返回“SinglePage”。如果不是 PDF,则返回 None
。
类型:
str
version_count
- 新功能在 v1.22.2 版本中引入
计算文档中存在版本的整数。如果不是 PDF,则为零;否则为增量保存数加一。
类型:
int
needs_pass
指示文档是否受密码保护以防止访问。即使在文档已验证之后,此指示器仍然保持不变。如果为真,则禁止增量保存。
类型:
bool
is_encrypted
此指示器最初等于Document.needs_pass
。验证成功后,它设置为 False 反映当前情况。
类型:
bool
permissions
- 自 v1.16.0 版更改:现在是一个由位指示器组成的整数。先前是一个字典。
包含访问文档的权限。这是一个整数,包含各自位位置上的 bool 值。例如,如果 doc.permissions & pymupdf.PDF_PERM_MODIFY > 0,则可以更改文档。有关详细信息,请参阅 文档权限。
类型:
int
metadata
作为 Python 字典或 None
(如果 is_encrypted=True 和 needPass=True)。键为 format、encryption、title、author、subject、keywords、creator、producer、creationDate、modDate、trapped。所有项的值都是字符串或 None
。
除了 format 和 encryption,对于 PDF 文档,关键名称与 PDF 关键字 /Creator、/Producer、/CreationDate、/ModDate、/Title、/Author、/Subject、/Trapped 和 /Keywords 显而易见地对应。
- format 包含文档格式(例如 ‘PDF-1.6’,‘XPS’,‘EPUB’)。
- encryption 可以是
None
(无加密),或者命名加密方法的字符串(例如 ‘标准 V4 R4 128 位 RC4’)。请注意,即使 needs_pass=False,也可能指定加密方法 甚至。在这种情况下,可能未授予所有权限。查看有关详细信息的Document.permissions
。 - 如果日期字段包含有效数据(这并不一定是情况!),它们是以 PDF 特定时间戳格式 “D:” 的字符串,其中
- 是 12 位 ISO 时间戳 YYYYMMDDhhmmss(YYYY - 年,MM - 月,DD - 日,hh - 时,mm - 分,ss - 秒),以及
- 是一个时区值(相对于 GMT 的时间间隔),包含一个符号(‘+’ 或 ‘-’),小时 (hh) 和分钟 (‘mm’,请注意引号!)。
- 例如,巴拉圭的值可能看起来像 D:20150415131602-04’00’,对应于 2015 年 4 月 15 日下午 1 点 16 分 02 秒阿松森当地时间的时间戳。
类型:
字典
name
包含创建 Document 的 filename 或 filetype 值。
类型:
str
page_count
包含文档的页数。对于没有页面的文档,可能返回 0。函数 len(doc)
也会返回这个结果。
类型:
整数
chapter_count
- 新版本 v1.17.0
包含文档中章节的数量。仅适用于支持章节的文档类型(当前为 EPUB)。其他文档将返回 1。
类型:
整数
last_location
- 新版本 v1.17.0
包含文档最后一页的(章节,页号)。仅适用于支持章节的文档类型(当前为 EPUB)。对于其他文档,如果没有页面,将返回 (0, page_count - 1)
和 (0, -1)
。
类型:
整数
FormFonts
在 /AcroForm 对象中定义的表单字段字体名称列表。如果不是 PDF,则为 None
。
类型:
列表
注
对于改变 PDF 结构的方法(insert_pdf()
、select()
、copy_page()
、delete_page()
等),请注意程序中的对象或属性可能已无效或变为孤立。例如 Page 对象及其子对象(链接、注释、小部件)、保存旧页面计数的变量、目录等等。请记得保持这些变量的更新或删除孤立的对象。同时参考 确保 PyMuPDF 中重要对象的一致性。
set_metadata()
示例
清除元数据信息。如果您因隐私/数据保护问题而这样做,请确保将文档另存为新文件,并设置 garbage > 0。只有这样旧的 /Info 对象才会被物理删除。在这种情况下,您可能还想清除由几个 PDF 编辑器插入的任何 XML 元数据:
>>> import pymupdf >>> doc=pymupdf.open("pymupdf.pdf") >>> doc.metadata # look at what we currently have {'producer': 'rst2pdf, reportlab', 'format': 'PDF 1.4', 'encryption': None, 'author': 'Jorj X. McKie', 'modDate': "D:20160611145816-04'00'", 'keywords': 'PDF, XPS, EPUB, CBZ', 'title': 'The PyMuPDF Documentation', 'creationDate': "D:20160611145816-04'00'", 'creator': 'sphinx', 'subject': 'PyMuPDF 1.9.1'} >>> doc.set_metadata({}) # clear all fields >>> doc.metadata # look again to show what happened {'producer': 'none', 'format': 'PDF 1.4', 'encryption': None, 'author': 'none', 'modDate': 'none', 'keywords': 'none', 'title': 'none', 'creationDate': 'none', 'creator': 'none', 'subject': 'none'} >>> doc._delXmlMetadata() # clear any XML metadata >>> doc.save("anonymous.pdf", garbage = 4) # save anonymized doc
set_toc()
演示
这展示了如何修改或添加目录。还可以查看示例目录中的 import.py 和 export.py。
>>> import pymupdf >>> doc = pymupdf.open("test.pdf") >>> toc = doc.get_toc() >>> for t in toc: print(t) # show what we have [1, 'The PyMuPDF Documentation', 1] [2, 'Introduction', 1] [3, 'Note on the Name fitz', 1] [3, 'License', 1] >>> toc[1][1] += " modified by set_toc" # modify something >>> doc.set_toc(toc) # replace outline tree 3 # number of bookmarks inserted >>> for t in doc.get_toc(): print(t) # demonstrate it worked [1, 'The PyMuPDF Documentation', 1] [2, 'Introduction modified by set_toc', 1] # <<< this has changed [3, 'Note on the Name fitz', 1] [3, 'License', 1]
insert_pdf()
示例
(1) 连接两个文档并包括它们的目录:
>>> doc1 = pymupdf.open("file1.pdf") # must be a PDF >>> doc2 = pymupdf.open("file2.pdf") # must be a PDF >>> pages1 = len(doc1) # save doc1's page count >>> toc1 = doc1.get_toc(False) # save TOC 1 >>> toc2 = doc2.get_toc(False) # save TOC 2 >>> doc1.insert_pdf(doc2) # doc2 at end of doc1 >>> for t in toc2: # increase toc2 page numbers t[2] += pages1 # by old len(doc1) >>> doc1.set_toc(toc1 + toc2) # now result has total TOC
显然,在更普遍的情况下可以找到类似的方法。只需确保一行中的层次级别不会增加超过一层。在 toc2 段前后插入虚拟书签可以解决这些情况。在示例目录的脚本 join.py 中可以找到一个现成的 GUI(wxPython)解决方案。
(2) 更多示例:
>>> # insert 5 pages of doc2, where its page 21 becomes page 15 in doc1 >>> doc1.insert_pdf(doc2, from_page=21, to_page=25, start_at=15)
>>> # same example, but pages are rotated and copied in reverse order >>> doc1.insert_pdf(doc2, from_page=25, to_page=21, start_at=15, rotate=90)
>>> # put copied pages in front of doc1 >>> doc1.insert_pdf(doc2, from_page=21, to_page=25, start_at=0)
其他示例
从 PDF 中提取所有引用页面的图像并保存为单独的 PNG 文件:
for i in range(doc.page_count): imglist = doc.get_page_images(i) for img in imglist: xref = img[0] # xref number pix = pymupdf.Pixmap(doc, xref) # make pixmap from image if pix.n - pix.alpha < 4: # can be saved as PNG pix.save("p%s-%s.png" % (i, xref)) else: # CMYK: must convert first pix0 = pymupdf.Pixmap(pymupdf.csRGB, pix) pix0.save("p%s-%s.png" % (i, xref)) pix0 = None # free Pixmap resources pix = None # free Pixmap resources
旋转 PDF 的所有页面:
>>> for page in doc: page.set_rotation(90)
脚注
对本页面有任何反馈吗?
本软件按原样提供,没有任何明示或暗示的保证。此软件按许可证分发,未经授权不得复制、修改或分发。请参阅 artifex.com 的许可信息或联系美国旧金山 CA 94129 Mesa 街 108A 号的 Artifex Software Inc. 了解更多信息。
本文档涵盖所有版本直至 1.24.4。
set_metadata()
示例
清除元数据信息。如果您因隐私/数据保护问题而执行此操作,请确保将文档保存为一个新文件,并设置 garbage > 0。只有这样,旧的 /Info 对象才会从文件中物理移除。在这种情况下,您可能还想清除由多个 PDF 编辑器插入的任何 XML 元数据:
>>> import pymupdf >>> doc=pymupdf.open("pymupdf.pdf") >>> doc.metadata # look at what we currently have {'producer': 'rst2pdf, reportlab', 'format': 'PDF 1.4', 'encryption': None, 'author': 'Jorj X. McKie', 'modDate': "D:20160611145816-04'00'", 'keywords': 'PDF, XPS, EPUB, CBZ', 'title': 'The PyMuPDF Documentation', 'creationDate': "D:20160611145816-04'00'", 'creator': 'sphinx', 'subject': 'PyMuPDF 1.9.1'} >>> doc.set_metadata({}) # clear all fields >>> doc.metadata # look again to show what happened {'producer': 'none', 'format': 'PDF 1.4', 'encryption': None, 'author': 'none', 'modDate': 'none', 'keywords': 'none', 'title': 'none', 'creationDate': 'none', 'creator': 'none', 'subject': 'none'} >>> doc._delXmlMetadata() # clear any XML metadata >>> doc.save("anonymous.pdf", garbage = 4) # save anonymized doc
set_toc()
演示
这展示了如何修改或添加目录。还可以查看示例目录中的 import.py 和 export.py。
>>> import pymupdf >>> doc = pymupdf.open("test.pdf") >>> toc = doc.get_toc() >>> for t in toc: print(t) # show what we have [1, 'The PyMuPDF Documentation', 1] [2, 'Introduction', 1] [3, 'Note on the Name fitz', 1] [3, 'License', 1] >>> toc[1][1] += " modified by set_toc" # modify something >>> doc.set_toc(toc) # replace outline tree 3 # number of bookmarks inserted >>> for t in doc.get_toc(): print(t) # demonstrate it worked [1, 'The PyMuPDF Documentation', 1] [2, 'Introduction modified by set_toc', 1] # <<< this has changed [3, 'Note on the Name fitz', 1] [3, 'License', 1]
insert_pdf()
示例
(1) 合并包含其目录的两个文档:
>>> doc1 = pymupdf.open("file1.pdf") # must be a PDF >>> doc2 = pymupdf.open("file2.pdf") # must be a PDF >>> pages1 = len(doc1) # save doc1's page count >>> toc1 = doc1.get_toc(False) # save TOC 1 >>> toc2 = doc2.get_toc(False) # save TOC 2 >>> doc1.insert_pdf(doc2) # doc2 at end of doc1 >>> for t in toc2: # increase toc2 page numbers t[2] += pages1 # by old len(doc1) >>> doc1.set_toc(toc1 + toc2) # now result has total TOC
显然,在更一般的情况下可以找到类似的方式。只需确保行内的层次级别不增加超过一级。在 toc2 段前后插入虚拟书签可以解决这类情况。在示例目录的 join.py 中可以找到一个现成的 GUI(wxPython)解决方案。
(2) 更多示例:
>>> # insert 5 pages of doc2, where its page 21 becomes page 15 in doc1 >>> doc1.insert_pdf(doc2, from_page=21, to_page=25, start_at=15)
>>> # same example, but pages are rotated and copied in reverse order >>> doc1.insert_pdf(doc2, from_page=25, to_page=21, start_at=15, rotate=90)
>>> # put copied pages in front of doc1 >>> doc1.insert_pdf(doc2, from_page=21, to_page=25, start_at=0)
其他示例
提取 PDF 中所有页面引用的图像并保存为单独的 PNG 文件:
for i in range(doc.page_count): imglist = doc.get_page_images(i) for img in imglist: xref = img[0] # xref number pix = pymupdf.Pixmap(doc, xref) # make pixmap from image if pix.n - pix.alpha < 4: # can be saved as PNG pix.save("p%s-%s.png" % (i, xref)) else: # CMYK: must convert first pix0 = pymupdf.Pixmap(pymupdf.csRGB, pix) pix0.save("p%s-%s.png" % (i, xref)) pix0 = None # free Pixmap resources pix = None # free Pixmap resources
旋转 PDF 的所有页面:
>>> for page in doc: page.set_rotation(90)
脚注
对本页面有任何反馈吗?
本软件按原样提供,没有任何明示或暗示的保证。此软件按许可证分发,未经授权不得复制、修改或分发。请参阅 artifex.com 的许可信息或联系美国旧金山 CA 94129 Mesa 街 108A 号的 Artifex Software Inc. 了解更多信息。
本文档涵盖所有版本直至 1.24.4。