PyMuPDF 1.24.4 中文文档(七)(5)

本文涉及的产品
密钥管理服务KMS,1000个密钥,100个凭据,1个月
日志服务 SLS,月写入数据量 50GB 1个月
简介: PyMuPDF 1.24.4 中文文档(七)

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。这目前仅在fallbackTrue时才会生效。
  • fallbackbool)– 如果为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:将期刊保存到文件。

参数:

filenamestr*,*fp) - 可以是字符串形式的文件名,也可以是以“wb”方式打开的文件对象(或者是io.BytesIO()对象)。

journal_load(filename)
  • v1.19.0 中新增

仅限 PDF:从文件加载期刊。启用文档的期刊记录。如果已启用期刊记录,则会引发异常。

参数:

filenamestr*,*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=TrueneedPass=True)。键为 formatencryptiontitleauthorsubjectkeywordscreatorproducercreationDatemodDatetrapped。所有项的值都是字符串或 None

除了 formatencryption,对于 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 时间戳 YYYYMMDDhhmmssYYYY - 年,MM - 月,DD - 日,hh - 时,mm - 分,ss - 秒),以及

  • 是一个时区值(相对于 GMT 的时间间隔),包含一个符号(‘+’ 或 ‘-’),小时 (hh) 和分钟 (‘mm’,请注意引号!)。
  • 例如,巴拉圭的值可能看起来像 D:20150415131602-04’00’,对应于 2015 年 4 月 15 日下午 1 点 16 分 02 秒阿松森当地时间的时间戳。

类型:

字典

name

包含创建 Documentfilenamefiletype 值。

类型:

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.pyexport.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.pyexport.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。


相关文章
|
3月前
|
XML 数据安全/隐私保护 数据格式
PyMuPDF 1.24.4 中文文档(七)(3)
PyMuPDF 1.24.4 中文文档(七)
63 0
|
3月前
|
存储 文字识别 自然语言处理
PyMuPDF 1.24.4 中文文档(五)(2)
PyMuPDF 1.24.4 中文文档(五)
88 3
|
3月前
PyMuPDF 1.24.4 中文文档(五)(1)
PyMuPDF 1.24.4 中文文档(五)
46 3
|
3月前
|
存储 XML 编解码
PyMuPDF 1.24.4 中文文档(三)(1)
PyMuPDF 1.24.4 中文文档(三)
98 0
|
3月前
|
存储 Python
PyMuPDF 1.24.4 中文文档(四)(4)
PyMuPDF 1.24.4 中文文档(四)
40 0
|
3月前
|
文字识别 API 数据安全/隐私保护
PyMuPDF 1.24.4 中文文档(一)(4)
PyMuPDF 1.24.4 中文文档(一)
101 3
|
3月前
|
安全 API 数据安全/隐私保护
PyMuPDF 1.24.4 中文文档(一)(3)
PyMuPDF 1.24.4 中文文档(一)
112 2
|
3月前
|
存储 XML 编解码
PyMuPDF 1.24.4 中文文档(八)(3)
PyMuPDF 1.24.4 中文文档(八)
128 1
|
3月前
|
存储 XML 数据安全/隐私保护
PyMuPDF 1.24.4 中文文档(八)(2)
PyMuPDF 1.24.4 中文文档(八)
223 1
|
3月前
|
XML 编解码 文字识别
PyMuPDF 1.24.4 中文文档(八)(4)
PyMuPDF 1.24.4 中文文档(八)
159 1