首页 > 其他分享 >PyMuPDF-1-24-4-中文文档-七-

PyMuPDF-1-24-4-中文文档-七-

时间:2024-06-17 15:56:08浏览次数:11  
标签:24 xref PyMuPDF 文档 PDF Document page 页面

PyMuPDF 1.24.4 中文文档(七)

原文:https://pymupdf.readthedocs.io/en/latest/

存档

原文:pymupdf.readthedocs.io/en/latest/archive-class.html

  • v1.21.0 版新增内容

此类表示文件夹和容器文件(如 ZIP 和 TAR 存档)的泛化。存档允许像它们都是一个文件夹层次结构树的一部分一样访问任意文件夹集合、ZIP/TAR 文件和单个二进制数据元素。

在 PyMuPDF 中,存档目前仅被 Story 对象使用,用于指定查找字体、图像和其他资源的位置。

方法/属性 简短描述
Archive.add() 向存档添加新数据
Archive.has_entry() 检查给定名称是否为成员
Archive.read_entry() 读取给定名称的数据
Archive.entry_list 存档条目列表[字典]

类 API

class Archive
__init__(self[, content[, path]])

创建一个新的存档。如果没有参数,则创建一个空存档。

如果提供,content可以是以下之一:

  • 另一个存档:将该存档作为新存档的子存档。

  • 一个字符串:这必须是本地文件夹或文件的名称。同时支持pathlib.Path对象。

    • 一个文件夹将被转换为子存档,因此可以通过它们的名称访问其文件(以及任何子文件夹)。
    • "rb"模式读取一个文件,这些二进制数据(一个bytes对象)将被视为单一成员子存档。在这种情况下,path参数是强制性的,并且应该是可以找到/检索此项的成员名称。
  • 一个zipfile.ZipFiletarfile.TarFile对象:将被添加为子存档。

  • 一个 Python 二进制对象(bytesbytearrayio.BytesIO):这将添加一个单一成员子存档。在这种情况下,path参数是强制性的,并且应该是可以找到/检索此项的成员名称。

  • 一个元组(data, name):这将添加一个成员名称为name的单一成员子存档。data可以是 Python 二进制对象或本地文件名(在这种情况下,其二进制文件内容将被使用)。如果需要指定path,请使用此格式。

  • 一个 Python 序列:这是一种方便的格式,用于指定上述任何组合。

如果提供,path必须是一个字符串。

  • 如果content是二进制数据或文件名,则此参数是强制性的,并且必须是数据可被找到的名称。

  • 否则,此参数是可选的。它可用于模拟文件夹名称或挂载点,在此子存档的元素下可以找到。例如,此规范 Archive((data, "name"), "path") 意味着 data 将通过元素名称 "path/name" 找到。其他子存档也是如此:要检索 ZIP 子存档的成员,它们的名称必须以 "path/" 为前缀。此参数的主要目的可能是区分重复名称。

注意

如果存档中存在重复的条目名称,则始终会找到/检索到该名称的最后一个条目。在创建存档或向存档追加更多数据时(参见 Archive.add()),不会检查重复项。使用 path 参数可以防止这种情况发生。

add(content[, path])

添加一个子存档。参数的含义与上述解释完全相同。当然,在这里 content 参数是不可选的。

has_entry(name)

检查条目是否存在于任何子存档中。

参数:

name (str) – 条目的完全限定名称。因此,必须包括添加了条目的子存档的任何 path 前缀。

返回:

TrueFalse

read_entry(name)

检索条目的数据。

参数:

name (str) – 条目的完全限定名称。因此,必须包括添加了条目的子存档的任何 path 前缀。

返回:

条目的二进制数据 (bytes)。如果未找到,将会引发异常。

entry_list

存档的子存档列表。每个列表项都是具有以下键的字典:

  • entries – 此子存档中顶层条目名称的列表。

  • fmt – 子存档的格式。这是字符串之一:“dir”(文件夹),“zip”(ZIP 存档),“tar”(TAR 存档),或“tree”用于单个二进制条目或文件内容。

  • path – 此子存档添加时path参数的值。

示例:

>>> from pprint import pprint
>>> import pymupdf
>>> dir1 = "fitz-32"  # a folder name
>>> dir2 = "fitz-64"  # a folder name
>>> img = ("nur-ruhig.jpg", "img")  # an image file
>>> members = (dir1, img, dir2)  # we want to append these in one go
>>> arch = pymupdf.Archive()
>>> arch.add(members, path="mypath")
>>> pprint(arch.entry_list)
[{'entries': ['310', '37', '38', '39'], 'fmt': 'dir', 'path': 'mypath'},
{'entries': ['img'], 'fmt': 'tree', 'path': 'mypath'},
{'entries': ['310', '311', '37', '38', '39', 'pypy'],
'fmt': 'dir',
'path': 'mypath'}]
>>> 

对此页面有任何反馈吗?


此软件按原样提供,不附带任何明示或暗示的保证。此软件在许可下分发,并且除非根据该许可的条款明确授权,否则不得复制、修改或分发。有关详细信息,请参阅 artifex.com 的许可信息或联系位于美国加利福尼亚州旧金山市 Mesa 街 39 号 108A 室的 Artifex Software Inc.。

此文档涵盖所有版本直到 1.24.4。

Discord logo

颜色空间

原文:pymupdf.readthedocs.io/en/latest/colorspace.html

表示一个 Pixmap 的颜色空间。

类 API

class Colorspace
__init__(self, n)

构造函数

参数:

n (int) – 标识颜色空间的数字。可能的值为CS_RGBCS_GRAYCS_CMYK

name

标识颜色空间的名称。例如:pymupdf.csCMYK.name = ‘DeviceCMYK’

类型:

str

n

定义一个像素的颜色所需的字节数。例如:pymupdf.csCMYK.n == 4

类型:

int

预定义的颜色空间

为了节省输入,已存在三种可用情况的预定义颜色空间对象。

  • csRGB = pymupdf.Colorspace(pymupdf.CS_RGB)

  • csGRAY = pymupdf.Colorspace(pymupdf.CS_GRAY)

  • csCMYK = pymupdf.Colorspace(pymupdf.CS_CMYK)

对这个页面有任何反馈吗?


此软件按原样提供,不带任何明示或暗示的担保。此软件根据许可分发,并且未经授权不得复制、修改或分发。请参阅artifex.com的许可信息或联系 Artifex Software Inc.,39 Mesa Street,Suite 108A,San Francisco CA 94129,美国获取更多信息。

此文档涵盖了所有版本,直到 1.24.4。

Discord logo

DisplayList

原文:pymupdf.readthedocs.io/en/latest/displaylist.html

DisplayList 是一个包含绘图命令(文本、图像等)的列表。其目的是双重的:

  1. 作为减少页面解析的缓存机制

  2. 作为多线程设置中的数据结构,其中一个线程解析页面,另一个线程呈现页面。PyMuPDF 当前不支持这个方面。

显示列表由页面中的对象填充,通常通过执行Page.get_displaylist()来执行。还存在一个独立的构造函数。

通过调用其方法之一 run(), get_pixmap()get_textpage() 来“重放”列表(一次或多次)。

方法 简短描述
run() 通过设备运行显示列表。
get_pixmap() 生成一个像素图
get_textpage() 生成一个文本页
rect 显示列表的 mediabox

类 API

class DisplayList
__init__(self, mediabox)

创建一个新的显示列表。

参数:

mediabox (矩形) – 页面的矩形。

返回类型:

DisplayList

run(device, matrix, area)

通过设备运行显示列表。设备将用其“命令”(即文本提取或图像创建)填充显示列表。显示列表以后可以多次“读取”页面,而无需重新从文档文件解释它。

您最有可能使用以下专门的运行方法之一 – get_pixmap()get_textpage()

参数:

  • device (设备) – 设备

  • matrix (矩阵) – 用于应用于显示列表内容的转换矩阵。

  • area (矩形) – 仅在此区域内可见的部分将在运行设备时被考虑。

get_pixmap(matrix=pymupdf.Identity, colorspace=pymupdf.csRGB, alpha=0, clip=None)

通过绘制设备运行显示列表并返回像素图。

参数:

  • matrix (矩阵) – 要使用的矩阵。默认为单位矩阵。

  • colorspace (色彩空间) – 所需的色彩空间。默认为 RGB。

  • alpha (int) – 确定是否(0,默认)包含透明通道。

  • clip (irect_like) – 限制渲染到此区域与DisplayList.rect的交集。

返回类型:

Pixmap

返回:

显示列表的像素图。

get_textpage(flags)

通过文本设备运行显示列表并返回文本页。

参数:

flagsint)– 控制将哪些信息解析为文本页。PyMuPDF 中的默认值为 3 = TEXT_PRESERVE_LIGATURES | TEXT_PRESERVE_WHITESPACE,即 ligatures 保留,空白字符保留(不转换为空格),且不包括图像。参见 Text Extraction Flags。

返回类型:

TextPage

返回:

显示列表的文本页。

rect

包含显示列表的媒体框。如果通过 Page.get_displaylist() 创建,则与页面的矩形相等。

类型:

Rect

对此页面有任何反馈吗?


本软件按原样提供,不附带任何明示或暗示的担保。此软件根据许可证分发,未经授权不得复制、修改或分发。请参阅 artifex.com 上的许可信息或联系美国加利福尼亚州旧金山 Mesa Street 39 号 108A 套房的 Artifex Software Inc. 获取更多信息。

此文档涵盖所有版本直到 1.24.4。

Discord logo

文档

原文:pymupdf.readthedocs.io/en/latest/document.html

此类表示一个文档。它可以从文件或内存构建。

此类还存在别名open,即pymupdf.Document(...)pymupdf.open(...)完全相同。

有关嵌入文件的详细信息,请参阅附录 3。

注意

从 v1.17.0 开始,仅支持EPUB 文件的新页面寻址机制。此文档类型在内部组织为章节,因此可以通过其所谓的“位置”最有效地找到页面。位置是一个由章节号和该章节中的页号组成的元组(chapter, pno),两个数字都是从零开始计数的。

尽管仍然可以通过(绝对)页码定位页面,但这样做可能意味着必须在地址页面之前对完整的 EPUB 文档进行布局。如果文档非常庞大,这可能会对性能产生显著影响。使用页面的(章节,页号)可以避免这种情况发生。

为了保持一致的 API,PyMuPDF 支持所有文件类型的页面位置语法 - 没有此功能的文档只有一个章节。Document.load_page()和等效的索引访问现在也支持位置参数。

有多种方法可以在页面号和位置之间进行转换,确定章节数,每章的页数,计算下一个和前一个位置,以及文档的最后一页位置。

方法/属性 简短描述
Document.add_layer() 仅限 PDF:创建新的可选内容配置
Document.add_ocg() 仅限 PDF:添加新的可选内容组
Document.authenticate() 访问加密文档
Document.bake() 仅限 PDF:使注释/字段内容永久化
Document.can_save_incrementally() 检查是否可以增量保存
Document.chapter_page_count() 章节中的页数
Document.close() 关闭文档
Document.convert_to_pdf() 将版本写入内存中的 PDF 文件
Document.copy_page() 仅限 PDF:复制页面引用
Document.del_toc_item() 仅限 PDF:删除单个 TOC 项目
Document.delete_page() 仅限 PDF:删除页面
Document.delete_pages() PDF only: 删除多个页面
Document.embfile_add() PDF only: 添加新的嵌入文件
Document.embfile_count() PDF only: 嵌入文件数量
Document.embfile_del() PDF only: 删除嵌入文件条目
Document.embfile_get() PDF only: 提取嵌入文件缓冲区
Document.embfile_info() PDF only: 嵌入文件元数据
Document.embfile_names() PDF only: 嵌入文件列表
Document.embfile_upd() PDF only: 更改嵌入文件
Document.extract_font() PDF only: 提取字体(通过 xref
Document.extract_image() PDF only: 提取嵌入图像(通过 xref
Document.ez_save() PDF only: 以不同默认设置保存
Document.find_bookmark() 排版后文档中书签位置的检索
Document.fullcopy_page() PDF only: 复制页面
Document.get_layer() PDF only: ON、OFF、RBGroups 中 OCGs 列表
Document.get_layers() PDF only: 可选内容配置列表
Document.get_oc() PDF only: 获取图像/表单 XObject 的 OCG /OCMD xref
Document.get_ocgs() PDF only: 所有可选内容组的信息
Document.get_ocmd() PDF only: 获取 OCMD 的定义
Document.get_page_fonts() PDF only: 页面引用的字体列表
Document.get_page_images() PDF only: 页面引用的图像列表
Document.get_page_labels() PDF only: 页面标签定义列表
Document.get_page_numbers() PDF only: 获取具有给定标签的页码
Document.get_page_pixmap() 按页码创建页面的位图
Document.get_page_text() 按页码提取页面的文本
Document.get_page_xobjects() 仅限 PDF:页面引用的 XObjects 列表
Document.get_sigflags() 仅限 PDF:确定签名状态
Document.get_toc() 提取目录
Document.get_xml_metadata() 仅限 PDF:读取 XML 元数据
Document.has_annots() 仅限 PDF:检查 PDF 是否包含任何注释
Document.has_links() 仅限 PDF:检查 PDF 是否包含任何链接
Document.insert_page() 仅限 PDF:插入新页面
Document.insert_pdf() 仅限 PDF:从另一个 PDF 插入页面
Document.insert_file() 仅限 PDF:从任意文档插入页面
Document.journal_can_do() 仅限 PDF:哪些日志记录操作是可能的
Document.journal_enable() 仅限 PDF:启用文档的日志记录
Document.journal_load() 仅限 PDF:从文件加载日志记录
Document.journal_op_name() 仅限 PDF:返回日志记录步骤的名称
Document.journal_position() 仅限 PDF:返回日志记录状态
Document.journal_redo() 仅限 PDF:重做当前操作
Document.journal_save() 仅限 PDF:将日志记录保存到文件
Document.journal_start_op() 仅限 PDF:启动一个“操作”,并为其命名
Document.journal_stop_op() 仅限 PDF:结束当前操作
Document.journal_undo() 仅限 PDF:撤消当前操作
Document.layer_ui_configs() 仅限 PDF:可选内容意图列表
Document.layout() 重新对文档进行分页(如果支持的话)
Document.load_page() 读取一页
Document.make_bookmark() 在可重排文档中创建页面指针
Document.move_page() 仅适用于 PDF:将页面移动到文档中的不同位置
Document.need_appearances() 仅适用于 PDF:获取/设置/NeedAppearances属性
Document.new_page() 仅适用于 PDF:插入一个新的空白页
Document.next_location() 返回下一页的章节和页码
Document.outline_xref() 仅适用于 PDF:将 TOC 项 xref 化
Document.page_cropbox() 仅适用于 PDF:未旋转的页面矩形
Document.page_xref() 仅适用于 PDF:页面号 xref
Document.pages() 迭代器,遍历页面范围
Document.pdf_catalog() 仅适用于 PDF:目录(根)的 xref
Document.pdf_trailer() 仅适用于 PDF:尾部源
Document.prev_location() 返回前一页的章节和页码
Document.reload_page() 仅适用于 PDF:提供页面的新副本
Document.resolve_names() 仅适用于 PDF:将目标名称转换为 Python 字典
Document.save() 仅适用于 PDF:保存文档
Document.saveIncr() 仅适用于 PDF:增量保存文档
Document.scrub() 仅适用于 PDF:删除敏感数据
Document.search_page_for() 在页面上搜索字符串
Document.select() 仅适用于 PDF:选择页面的子集
Document.set_layer_ui_config() 仅适用于 PDF:临时设置 OCG 可见性
Document.set_layer() 仅适用于 PDF:批量更改 OCG 状态
Document.set_markinfo() 仅适用于 PDF:设置 MarkInfo 值
Document.set_metadata() 仅适用于 PDF:设置元数据
Document.set_oc() 仅适用于 PDF:将 OCG/OCMD 附加到图像/表单 XObject
Document.set_ocmd() 仅适用于 PDF:创建或更新 OCMD
Document.set_page_labels() 仅适用于 PDF:添加/更新页面标签定义
Document.set_pagemode() 仅适用于 PDF:设置页面模式
Document.set_pagelayout() 仅适用于 PDF:设置页面布局
Document.set_toc_item() 仅适用于 PDF:更改单个 TOC 项
Document.set_toc() 仅适用于 PDF:设置目录(TOC)
Document.set_xml_metadata() 仅适用于 PDF:创建或更新文档的 XML 元数据
Document.subset_fonts() 仅适用于 PDF:创建字体子集
Document.switch_layer() 仅适用于 PDF:激活 OC 配置
Document.tobytes() 仅适用于 PDF:将文档写入内存
Document.xref_copy() 仅适用于 PDF:将 PDF 字典复制到另一个xref
Document.xref_get_key() 仅适用于 PDF:获取字典键的值
Document.xref_get_keys() 仅适用于 PDF:列出xref对象的键
Document.xref_object() 仅适用于 PDF:获取xref的定义源
Document.xref_set_key() 仅适用于 PDF:设置字典键的值
Document.xref_stream_raw() 仅适用于 PDF:xref的原始流源
Document.xref_xml_metadata() 仅适用于 PDF:XML 元数据的xref
Document.chapter_count 章节数量
Document.FormFonts 仅适用于 PDF:全局小部件字体列表
Document.is_closed 文档是否已关闭?
Document.is_dirty 仅适用于 PDF:文档是否已更改?
Document.is_encrypted 文档是否(仍然)加密?
Document.is_fast_webaccess PDF 是否线性化?
Document.is_form_pdf 这是表单 PDF 吗?
Document.is_pdf 这是 PDF 吗?
Document.is_reflowable 这是可重排文档吗?
Document.is_repaired 仅限 PDF:此 PDF 在打开时是否已修复?
Document.last_location 最后一页的(章节,页号)位置
Document.metadata 元数据
Document.markinfo PDF 标记信息值
Document.name 文档的文件名
Document.needs_pass 需要密码访问数据吗?
Document.outline 第一个大纲条目
Document.page_count 页数
Document.permissions 访问文档的权限
Document.pagemode PDF 页面模式值
Document.pagelayout PDF 页面布局值
Document.version_count PDF 版本计数

类 API

class Document
__init__(self, filename=None, stream=None, *, filetype=None, rect=None, width=0, height=0, fontsize=11)
  • 自 v1.14.13 更改:支持io.BytesIO用于内存文档。

  • 自 v1.19.6 更改:更清晰、更简短和更一致的异常消息。如果未指定,文件类型将始终假定为“pdf”。空文件和内存区域将始终导致异常。

创建一个Document对象。

  • 默认参数下,将创建一个新的空白 PDF文档。

  • 如果提供了stream,则文档将从内存中创建,如果不是 PDF,则filenamefiletype必须指示其类型。

  • 如果streamNone,则文档将从filename指定的文件创建。其类型将根据扩展名推断。可以通过filetype覆盖此行为。

参数:

  • filename (str,pathlib) – 包含文件路径的 UTF-8 字符串或pathlib对象。文档类型将根据文件名扩展名推断。如果不存在或不匹配支持的类型,则假定为 PDF 文档。对于内存文档,可以使用此参数代替filetype,请参见下文。

  • stream (bytes,bytearray,BytesIO) – 包含支持的文档的内存区域。如果不是 PDF,必须通过filenamefiletype指定其类型。

  • filetype (str) – 指定文档类型的字符串。这可以是类似文件名的任何内容(例如“x.pdf”),在这种情况下,MuPDF 使用扩展名确定类型,或者像application/pdf这样的 MIME 类型。只需使用像“pdf”或“.pdf”这样的字符串也可以。对于 PDF 文档,可以省略,否则必须匹配支持的文档类型。

  • rect (rect_like) – 指定所需页面大小的矩形。此参数仅适用于具有可变页面布局(“可重排”文档),如电子书或 HTML,并且在其他情况下将被忽略。如果指定,它必须是一个非空的有限矩形,其左上坐标为 (0, 0)。与参数 fontsize 一起,每个页面将相应地布局,并因此确定页数。

  • width (float) – 可与 height 一起用作 rect 的替代,以指定布局信息。

  • height (float) – 可与 width 一起用作 rect 的替代,以指定布局信息。

  • fontsize (float) – 可重排文档类型的默认字体大小。如果未指定 rectwidthheight 中的任何一个参数,则此参数将被忽略。将用于计算页面布局。

引发:

  • TypeError – 如果任何参数的类型不符合规范。

  • FileNotFoundError – 如果找不到文件/路径。重新实现为RuntimeError的子类。

  • EmptyFileError – 如果文件/路径为空或内存中的bytes对象长度为零。是FileDataErrorRuntimeError的子类。

  • ValueError – 如果显式指定未知文件类型。

  • FileDataError – 如果文档对于给定类型具有无效结构 – 或根本不是文件(而是例如文件夹)。是RuntimeError的子类。

返回:

文档对象。如果无法创建文档,则会按上述顺序引发异常。请注意,如果检查RuntimeError,PyMuPDF 特定的异常,FileNotFoundErrorEmptyFileErrorFileDataError会被拦截。

如果有问题,您可以在内部消息存储中查看更多详细信息:print(pymupdf.TOOLS.mupdf_warnings())(此调用将清空,但您也可以防止此操作 – 参考Tools.mupdf_warnings())。

注意

并非所有文档类型在打开时都会检查有效格式。例如,栅格图像只有在尝试访问内容时才会稍后引发异常。其他类型(特别是具有非二进制内容的类型)有时也会成功地打开(有时甚至访问),即使格式无效:

  • HTM,HTML,XHTML:始终打开,metadata["format"] 为“HTML5”,或“XHTML”。

  • XML,FB2:始终打开,metadata["format"] 为“FictionBook2”。

可能的形式概述,注意:open 是 文档 的同义词:

>>> # from a file
>>> doc = pymupdf.open("some.xps")
>>> # handle wrong extension
>>> doc = pymupdf.open("some.file", filetype="xps")
>>>
>>> # from memory, filetype is required if not a PDF
>>> doc = pymupdf.open("xps", mem_area)
>>> doc = pymupdf.open(None, mem_area, "xps")
>>> doc = pymupdf.open(stream=mem_area, filetype="xps")
>>>
>>> # new empty PDF
>>> doc = pymupdf.open()
>>> doc = pymupdf.open(None)
>>> doc = pymupdf.open("") 

注意

具有错误(但支持的)文件扩展名的栅格图像不成问题。当实际访问文件内容并且没有投诉时,MuPDF 将确定正确的图像类型。因此,即使对于 PNG 图像,pymupdf.open("file.jpg")也能正常工作。

Document 类也可以作为上下文管理器使用。退出时,文档将自动关闭。

>>> import pymupdf
>>> with pymupdf.open(...) as doc:
 for page in doc: print("page %i" % page.number)
page 0
page 1
page 2
page 3
>>> doc.is_closed
True
>>> 
get_oc(xref)
  • v1.18.4 中的新内容

返回图像或表单 X 对象附加的OCGOCMD的交叉引用号。

参数:

xref (int) – 图像或表单 X 对象的xref号。有效的交叉引用号由Document.get_page_images()Document.get_page_xobjects()返回。对于无效的号码,会引发异常。

返回类型:

int

返回:

可选内容对象的交叉引用号,如果没有则为零。

set_oc(xref, ocxref)
  • v1.18.4 版新功能

如果xref代表图像或表单 X 对象,则设置或删除可选内容对象的交叉引用号ocxref

参数:

  • xref (int) – 图像或表单 X 对象的xref [5]。有效的交叉引用号由Document.get_page_images()Document.get_page_xobjects()返回。对于无效的号码,会引发异常。

  • ocxref (int) – OCG / OCMDxref号。如果不为零,则无效引用会引发异常。如果为零,则删除任何 OC 引用。

get_layers()
  • v1.18.3 版新功能

显示可选层配置。总是有一个标准配置,不包含在响应中。

>>> for item in doc.get_layers(): print(item)
{'number': 0, 'name': 'my-config', 'creator': ''}
>>> # use 'number' as config identifier in add_ocg 
add_layer(name, creator=None, on=None)
  • v1.18.3 版新功能

添加一个可选内容配置。层用作可选内容组的 ON / OFF 状态集合,并允许在同一文档上快速切换不同视图的可见性。

参数:

  • name (str) – 任意名称。

  • creator (str) – (可选)创建软件。

  • on (sequ) – 应在激活此层时设置为 ON 的 OCG xref号序列。未列出的所有 OCG 将被设置为 OFF。

switch_layer(number, as_default=False)
  • v1.18.3 版新功能

切换到由可选层配置号定义的文档视图。这是临时的,除非设为默认。

参数:

  • number (int) – 由Document.layer_configs()返回的配置号。

  • as_default (bool) – 将此配置设置为默认配置。

激活在识别的层中定义的 OCG 的 ON / OFF 状态。如果as_default=True,则还会合并所有层,包括标准层,并将结果写回标准层,并删除所有可选层

add_ocg(name, config=-1, on=True, intent='View', usage='Artwork')
  • v1.18.3 版新功能

添加一个可选内容组。OCG 是确定对象可见性的最重要信息单元。对于 PDF 文档,至少必须存在一个 OCG 才能被视为具有可选内容。

参数:

  • name (str) – 任意名称。将在支持 PDF 查看器中显示。

  • config (int) – 层配置号。默认为-1 是标准配置。

  • on (bool) – 指向此 OCG 的对象的标准可见性状态。

  • intent (str,list) – 声明可见性意图的字符串或字符串列表。可以选择两个 PDF 标准值:“View”和“Design”。默认为“View”。拼写非常重要

  • usage (str) – OCG 可见性的另一个影响因素。这将成为 OCG 的/Usage键的一部分。可以选择两个 PDF 标准值:“Artwork”和“Technical”。默认为“Artwork”。请仅在必要时更改。

返回:

创建的 OCG 的xref。用作支持对象中oc参数的条目。

注意

可能会创建具有相同参数的多个 OCG。这不会引起问题。Document.save()的垃圾选项 3 将清除任何重复项。

set_ocmd(xref=0, ocgs=None, policy='AnyOn', ve=None)
  • v1.18.4 中的新功能

创建或更新一个OCMDOptional Content Membership Dictionary(可选内容成员字典)。

参数:

  • xref (int) – 要更新的 OCMD 的xref,或者为新的 OCMD 为 0。

  • ocgs (list) – 一系列现有xref PDF 对象的编号。

  • policy (str) – “AnyOn”(默认),“AnyOff”,“AllOn”,“AllOff”(混合或小写)之一。

  • ve (list) – “可见性表达式”。这是一个任意嵌套其他列表的列表 – 详见下面的解释。如果需要制定更复杂的条件,可用作ocgs / policy的替代。

返回类型:

int

返回:

创建 OCMD 的xref。用作支持对象中oc=xref参数,以及分别在Document.set_oc()Annot.set_oc()中使用。

注意

类似于 OCG,OCMD 具有开启或关闭的可见性状态,并且可以像 OCG 一样使用。与 OCG 不同的是,通过评估一个或多个 OCG 的状态来确定 OCMD 的状态,通过特殊形式的布尔表达式。如果表达式评估为 true,则 OCMD 状态为 ON,false 为 OFF。

有两种方式可以制定 OCMD 的可见性:

  1. 使用ocgspolicy的组合:policy的值解释如下:
  • AnyOn – (默认)如果至少有一个 OCG 打开,则为 true。
  • AnyOff – 如果至少有一个 OCG 关闭,则为 true。
  • AllOn – 如果所有 OCG 都打开,则为 true。
  • AllOff – 如果所有 OCG 都关闭,则为 true。

假设您希望两个 PDF 对象一次只显示一个(如果一个打开,则另一个必须关闭):

解决方案:使用一个OCG作为对象 1 的对象,使用一个OCMD作为对象 2 的对象。通过set_ocmd(ocgs=[xref], policy="AllOff")创建 OCMD,其中xref为 OCG 的编号。

  1. 使用可见性表达式 ve:这是一个包含两个或更多项的列表。第一个项是一个逻辑关键词:字符串“and”“or”“not”之一。第二个及其后的项必须是整数或另一个列表。整数必须是xref的编号。列表必须再次至少有两个以布尔关键词开头的项。这种语法有些笨拙,但非常强大:
  • 每个列表必须以逻辑关键词开头。
  • 如果关键词是“not”,那么列表必须正好有两个项。如果是“and”“or”,则可以跟随任意数量的其他项。
  • 逻辑关键词后面的项目可以是整数或者再次是一个列表。整数必须是 OCG 的 xref。列表必须符合前述规则。

示例:

  • set_ocmd(ve=["or", 4, ["not", 5], ["and", 6, 7]])。如果以下条件为真,则返回 ON:“4 为 ON,或者 5 为 OFF,或者 6 和 7 同时为 ON”
  • set_ocmd(ve=["not", xref])。这与第 1 创建的 OCMD 示例具有相同的效果。

更多详细信息和示例请参见 Adobe PDF References 第 224 页。还请查看示例脚本这里

可见性表达式/VE是 PDF 规范 1.6 版的一部分。因此,并非所有 PDF 查看器/阅读器可能已支持此功能,因此对于这些情况会以某种标准方式进行响应。

get_ocmd(xref)
  • 自 v1.18.4 起新增功能

检索OCMD的定义。

参数:

xref (int) – OCMD 的xref

返回类型:

字典

返回:

带有键xrefocgspolicyve的字典。

get_layer(config=-1)
  • 自 v1.18.3 起新增功能

特定配置中可选内容组的状态列表。这是一个包含数组/ON/OFF或某些单选按钮组(/RBGroups)中的 OCG 交叉引用号列表的字典。

参数:

config (int) – 配置层(默认为标准配置层)。

>>> pprint(doc.get_layer())
{'off': [8, 9, 10], 'on': [5, 6, 7], 'rbgroups': [[7, 10]]}
>>> 
set_layer(config, *, on=None, off=None, basestate=None, rbgroups=None, locked=None)
  • 自 v1.18.3 起新增功能

  • 自 v1.22.5 起更改:支持锁定OCG 的列表。

大量可选内容组的状态更改。永久设置 OCG 的状态。

参数:

  • config (int) – 所需的配置层,选择-1 表示默认配置层。

  • on (list) – 设置为 ON 的 OCG 的xref列表。替换以前的值。如果使用basestate="ON",应指定为空列表将不再设置任何 OCG 为 ON。

  • off (list) – 设置为 OFF 的 OCG 的xref列表。替换以前的值。如果使用basestate="OFF",应指定为空列表将不再设置任何 OCG 为 OFF。

  • basestate (str) – 未在onoff中提到的 OCG 的状态。可能的值为“ON”、“OFF”或“Unchanged”。大小写皆可。

  • rbgroups (list) – 一个列表的列表。替换以前的值。每个子列表应包含两个或更多个 OCG xrefs。同一子列表中的 OCG 就像单选按钮组中的按钮:设置一个为 ON 将自动将所有其他组成员设置为 OFF。

  • locked (list) – 无法通过用户界面更改的 OCG xref 号列表。

None 将不更改相应的 PDF 数组。

>>> doc.set_layer(-1, basestate="OFF")  # only changes the base state
>>> pprint(doc.get_layer())
{'basestate': 'OFF', 'off': [8, 9, 10], 'on': [5, 6, 7], 'rbgroups': [[7, 10]]} 
get_ocgs()
  • v1.18.3 中的新功能

所有可选内容组的详细信息。这是一个字典,形如(键是 OCG 的 xref):

>>> pprint(doc.get_ocgs())
{13: {'on': True,
 'intent': ['View', 'Design'],
 'name': 'Circle',
 'usage': 'Artwork'},
14: {'on': True,
 'intent': ['View', 'Design'],
 'name': 'Square',
 'usage': 'Artwork'},
15: {'on': False, 'intent': ['View'], 'name': 'Square', 'usage': 'Artwork'}}
>>> 
layer_ui_configs()
  • v1.18.3 中的新功能

显示可由支持 PDF 查看器的用户界面修改的可选内容的可见性状态。

  • 仅报告当前选择的层配置中包含的项目。
  • 字典键的含义如下:
    • depth:/Order 数组中的项目嵌套级别
    • locked: 如果无法通过用户界面更改,则为 true
    • number: 运行的顺序号
    • on: 项目状态
    • text: 源 OCG 的文本字符串或名称字段
    • type: “label”(由文本字符串设置),“checkbox”(由单个 OCG 设置)或 “radiobox”(由一组连接的 OCG 设置之一)
set_layer_ui_config(number, action=0)
  • v1.18.3 中的新功能

修改内容组的 OC 可见性状态。这类似于支持 PDF 查看器提供的功能。

请注意,可见性不是与 OCG 存储的属性。它甚至可能根本不在 PDF 文档中存在。相反,当前的可见性是使用某些支持 PDF 消费软件的用户界面临时设置的。此方法提供了相同类型的功能。

要进行永久更改,请使用 Document.set_layer()

参数:

  • number (int,str) – 列表 Document.layer_configs() 中项目的顺序号或其中一个项目的“text”。

  • action (int) – PDF_OC_ON = 设置为开启(默认),PDF_OC_TOGGLE = 切换开/关,PDF_OC_OFF = 设置为关闭。

authenticate(password)

使用字符串 password 解密文档。如果成功,可以访问文档数据。对于 PDF 文档,“所有者”和“用户”具有不同的特权,因此可能存在这些授权级别的不同密码。该方法将自动为提供的密码建立适当的(所有者或用户)访问权限。

参数:

password (str) – 所有者或用户密码。

返回类型:

int

返回:

如果成功,则返回正值,否则返回零(字符串不匹配任何密码)。如果返回正值,则指示器 Document.is_encrypted 将设置为 False返回代码携带以下详细信息:

  • 1 => 已验证,但 PDF 既没有所有者密码也没有用户密码。

  • 2 => 使用 用户 密码进行身份验证。

  • 4 => 使用 所有者 密码进行身份验证。

  • 6 => 已验证,且两个密码相等 – 可能是一种罕见的情况。

注意

文档可能由所有者保护,但不是由用户密码保护。通过 doc.authenticate("") == 2 可检测此情况。这允许无需验证即可打开和阅读文档,但依赖于Document.permissions值,其他操作可能会受限制。在这种情况下,PyMuPDF(如 MuPDF)忽略这些限制。因此,与任何 PDF 查看器相反,例如即使相应的权限标志PDF_PERM_COPYPDF_PERM_MODIFYPDF_PERM_ANNOTATE等被关闭,您也可以提取文本并添加或修改内容!在适用的情况下,您有责任构建合法合规的应用程序。

get_page_numbers(label, only_one=False)
  • 新功能在 v 1.18.6 中引入

仅限 PDF:返回具有指定标签的页面号列表 – 请注意,PDF 中的标签可能不唯一。这意味着需要对所有页面号进行顺序搜索以比较它们的标签。

注意

实施细节 – 用于此目的,页面不会被加载

参数:

  • 标签 (str) – 要查找的标签,例如“vii”(罗马数字 7)。

  • only_one (bool) – 在第一次命中后停止。如果标签是唯一的已知值或者页面很多等情况下非常有用。默认会检查每个页面号。

返回类型:

列表

返回:

具有此标签的页面号列表。如果找不到、未定义标签等,则为空。

get_page_labels()
  • 新功能在 v1.18.7 中引入

仅限 PDF:提取页面标签定义列表。通常用于在输入Document.set_page_labels()之前进行修改。

返回:

一个字典列表,如Document.set_page_labels()中所定义。

set_page_labels(labels)
  • 新功能在 v1.18.6 中引入

仅限 PDF:添加或更新 PDF 的页面标签定义。

参数:

标签 (列表) –

一个字典列表。每个字典定义一个标签构建规则和基于 0 的“起始”页码。该起始页是首个适用于该标签定义的页面。每个字典最多有 4 个条目,类似于 {'startpage': int, 'prefix': str, 'style': str, 'firstpagenum': int},具有以下条目。

  • startpage: (int) 应用标签规则的第一页号(基于 0)。此键必须存在。规则适用于文档的所有后续页面,直到超过下一个较大页码的规则为止。

  • prefix: (str) 一个任意字符串,用于开始标签,例如“A-”。默认为“”。

  • style: (str) 编号样式。可选的有“D”(十进制)、“r”/“R”(罗马数字,小写 / 大写)、“a”/“A”(字母编号,小写 / 大写:“a”到“z”,然后“aa”到“zz”等)。默认为“”。如果为空,则范围内的页面将获得相同的由 prefix 值组成的标签。如果 prefix 也省略,则标签将是“”。

  • firstpagenum: (int) 从该值开始编号。默认为 1,较小的值将被忽略。

例如:

[{'startpage': 6, 'prefix': 'A-', 'style': 'D', 'firstpagenum': 10},
 {'startpage': 10, 'prefix': '', 'style': 'D', 'firstpagenum': 1}] 

将为页面 6、7 等生成标签“A-10”、“A-11”、“A-12”、“A-13”、“1”、“2”、“3”等,直到文档末尾。页面 0 到 5 将标签为“”。

make_bookmark(loc)
  • 新功能 v.1.17.3

返回可重新流动文档中的页面指针。在重新布局文档后,此方法的结果可用于查找页面的新位置。

注意

不要与目录项 TOC 混淆。

参数:

loc列表,元组) – 页面位置。必须是有效的 (章节, 页数)

返回类型:

指针

返回:

以指针格式的长整数。用于找到文档重新布局后页面的新位置。不要触摸或重新分配。

find_bookmark(bookmark)
  • 新功能 v.1.17.3

在重新布局文档后返回新的页面位置。

参数:

bookmark指针) – 由 Document.make_bookmark() 创建。

返回类型:

元组

返回:

页面的新位置(章节, 页数)。

chapter_page_count(chapter)
  • 新功能 v.1.17.0

返回章节的页数。

参数:

chapter整数) – 基于 0 的章节编号。

返回类型:

整数

返回:

章节中的页数。仅适用于支持章节的文档类型(目前为 EPUB)。

next_location(page_id)
  • 新功能 v.1.17.0

返回下一页的位置。

参数:

page_id元组) – 当前页面 id。这必须是标识现有页面的元组 (章节, 页数)

返回:

下一页的元组,即 (章节, 页数 + 1)(章节 + 1, 0) 如果参数是最后一页,则为空元组 ()。仅适用于支持章节的文档类型(目前为 EPUB)。

prev_location(page_id)
  • 新功能 v.1.17.0

返回前一页的定位器。

参数:

page_id元组) – 当前页面 id。这必须是标识现有页面的元组 (章节, 页数)

返回:

前一页的元组,即 (章节, 页数 - 1) 或前一章节的最后一页, 如果参数是第一页,则为空元组 ()。仅适用于支持章节的文档类型(目前为 EPUB)。

load_page(page_id=0)
  • 在 v1.17.0 中更改:对于支持所谓的“章节结构”(如 EPUB)的文档类型,页面也可以通过章节编号和相对页数的组合加载,而不是绝对页数。这应该 显著加快 对大型文档的访问速度。

为进一步处理(如渲染、文本搜索等)创建一个 Page 对象。

参数:

page_id整数,元组) –

(v1.17.0 中更改)

可以是基于 0 的页码,或元组 (章节, 页数)。对于 整数,任何 -∞ < page_id < page_count 都可以接受。当 page_id 为负数时,将会添加 page_count。例如:要加载最后一页,你可以使用 doc.load_page(-1)。之后,你将拥有 page.number = doc.page_count - 1。

对于元组,chapter 必须在 Document.chapter_count 范围内,并且 pno 必须在该章节的 Document.chapter_page_count() 范围内。这两个值都是从 0 开始计数的。使用这种表示法,Page.number 将等于给定的元组。仅适用于支持章节结构的文档类型(目前仅限 EPUB)。

返回类型:

Page

注意

文档还遵循带有页码索引的 Python 序列协议:doc.load_page(n) == doc[n]

仅限绝对页码,如“for page in doc: …”“for page in reversed(doc): …” 将按顺序产生文档的页面。请参考 Document.pages(),允许像切片一样处理页面。

您还可以使用基于章节的新页面标识的索引表示法:使用 page = doc[(5, 2)] 加载第六章的第三页。

为了保持一致的 API,在不支持章节结构(如 PDF)的文档类型中,Document.chapter_count 为 1,也可以通过元组(0, pno)加载页面。参见 [3] 注释以获取性能改进的评论。

reload_page(page)
  • v1.16.10 版中的新功能

仅适用于 PDF:在完成并更新所有待定更改后,提供页面的新副本。

参数:

page (Page) – 页面对象。

返回类型:

Page

返回:

相同页面的新副本。将会完成所有待定更新(如注释或小部件),并加载页面的新副本。

注意

在典型用例中,在添加或更改注释/小部件后应获取页面 Pixmap。为了强制所有这些更改在页面结构中反映出来,该方法将重新加载一个新副本,同时保持对象层次结构“文档 -> 页面 -> 注释/小部件”不变。

resolve_names()

仅适用于 PDF:将目标名称转换为 Python 字典。

返回:

具有以下布局的字典:

  • key: (str) 名称。

  • value: (dict) 具有以下布局:

    • ”page”: 目标页码(从 0 开始)。如果找不到页码,则返回-1。

    • ”to”: (x, y) 页面上的目标点。目前在 PDF 坐标中,即点(0,0)是页面的左下角。

    • ”zoom”: (float) 缩放因子。

    • ”dest”: (str) 仅在页面上的目标位置未提供为“/XYZ”或未找到页码时才存在。

示例:

{
    '__bookmark_1': {'page': 0, 'to': (0.0, 541.0), 'zoom': 0.0},
    '__bookmark_2': {'page': 0, 'to': (0.0, 481.45), 'zoom': 0.0},
} 

或:

{
    '21154a7c20684ceb91f9c9adc3b677c40': {'page': -1, 'dest': '/XYZ 15.75 1486 0'},
    ...
} 

目录中所有在“/Dests”和“/Names/Dests”键下找到的名称都包含在内。

  • v1.23.6 版中的新功能
page_cropbox(pno)
  • v1.17.7 版中的新功能

仅适用于 PDF:返回未旋转的页面矩形 – 无需加载页面(通过 Document.load_page())。这适用于需要最佳性能的内部目的。

参数:

pno (int) – 从 0 开始的页面编号。

返回:

页面的 Rect 与 Page.rect() 类似,但忽略任何旋转。

page_xref(pno)
  • 新增于 v1.17.7

仅限 PDF:返回页面的 xref不加载页面(通过 Document.load_page())。这是为内部需要而设计,要求尽可能最佳性能。

参数:

pno (int) – 基于 0 的页码数。

返回:

页面的 xrefPage.xref 类似。

pages(start=None[, stop=None[, step=None]])
  • 新增于 v1.16.4

一个页面范围的生成器。参数的含义与内置函数 range() 相同。用于形如 “for page in doc.pages(start, stop, step): …” 的表达式。

参数:

  • start (int) – 从此页码开始迭代。默认为零,允许的值为 -∞ < start < page_count。如果为负数,将在开始迭代之前加上 page_count

  • stop (int) – 在此页码数停止迭代。默认为 page_count,可选范围为 -∞ < stop <= page_count。大于此值的将被 静默替换 为默认值。负值将循环发出倒序页面。与内置的 range() 相同,这不是第一个不返回的页面。

  • step (int) – 步进值。如果起始页小于结束页,默认为 1;如果起始页大于结束页,默认为 -1。不允许为零。

返回:

文档页面的生成器迭代器。以下是一些示例:

  • ”doc.pages()” 发出所有页面。

  • ”doc.pages(4, 9, 2)” 发出页面 4, 6, 8。

  • ”doc.pages(0, None, 2)” 发出所有偶数编号的页面。

  • ”doc.pages(-2)” 发出最后两页。

  • ”doc.pages(-1, -1)” 以倒序方式发出所有页面。

  • ”doc.pages(-1, -10)” 总是以倒序方式发出 10 页,从最后一页开始,重复,如果文档少于 10 页。因此,对于一个有 4 页的文档,将发出以下页码:3, 2, 1, 0, 3, 2, 1, 0, 3, 2, 1, 0, 3。

convert_to_pdf(from_page=-1, to_page=-1, rotate=0)

创建当前文档的 PDF 版本并将其写入内存。支持所有文档类型。参数的含义与 insert_pdf() 相同。实质上,您可以限制转换到页面子集,指定页面旋转并恢复页面顺序。

参数:

  • from_page (int) – 要复制的第一页(基于 0)。默认为第一页。

  • to_page (int) – 要复制的最后一页(基于 0)。默认为最后一页。

  • rotate (int) – 旋转角度。默认为 0(无旋转)。应为整数 n 的 n * 90,未经检查。

返回类型:

bytes

返回:

一个 Python bytes 对象,包含一个 PDF 文件图像。内部使用 tobytes(garbage=4, deflate=True) 创建。参见 tobytes()。您可以直接将其输出到磁盘或打开为 PDF。以下是一些示例:

>>> # convert an XPS file to PDF
>>> xps = pymupdf.open("some.xps")
>>> pdfbytes = xps.convert_to_pdf()
>>>
>>> # either do this -->
>>> pdf = pymupdf.open("pdf", pdfbytes)
>>> pdf.save("some.pdf")
>>>
>>> # or this -->
>>> pdfout = open("some.pdf", "wb")
>>> pdfout.tobytes(pdfbytes)
>>> pdfout.close() 
>>> # copy image files to PDF pages
>>> # each page will have image dimensions
>>> doc = pymupdf.open()                     # new PDF
>>> imglist = [ ... image file names ...] # e.g. a directory listing
>>> for img in imglist:
 imgdoc=pymupdf.open(img)           # open image as a document
 pdfbytes=imgdoc.convert_to_pdf()  # make a 1-page PDF of it
 imgpdf=pymupdf.open("pdf", pdfbytes)
 doc.insert_pdf(imgpdf)             # insert the image PDF
>>> doc.save("allmyimages.pdf") 

注意

该方法与mutool convert CLI 使用相同的逻辑。在大多数情况下运行良好——但请注意以下限制。

  • 图像文件:完美,未检测到问题。但是,图像透明度被忽略。如果需要(例如水印),请改用Page.insert_image()。否则,由于其更佳性能,建议使用此方法。

  • XPS:外观非常好。链接工作正常,大纲(书签)丢失,但可以轻松恢复[2]

  • EPUB、CBZ、FB2:类似于 XPS。

  • SVG:中等。与svglib大致相当。

get_toc(simple=True)

创建目录(TOC),以文档的大纲链为基础。

参数:

simplebool)– 指示是否需要简单或详细的 TOC。如果为False,则列表的每个项目还包含用于每个大纲条目的 linkDest 详细信息的字典。

返回类型:

list

返回:

一个列表的列表。每个条目的形式为[lvl, title, page, dest]。其条目具有以下含义:

  • lvl – 层次级别(正整数)。第一个条目始终为 1。连续条目要么相等,要么递增 1,要么以任何数字递减。

  • title – 标题(str

  • page – 基于 1 的源页面编号(int)。如果没有目标或在文档外部,则为-1

  • dest – (dict)仅在simple=False时包含。包含如下 TOC 条目的详细信息:

    • kind:目标类型,参见链接目标类型。

    • 文件:如果 kind 为LINK_GOTORLINK_LAUNCH,则为文件名。

    • page:目标页面,基于 0,LINK_GOTORLINK_GOTO

    • to:目标页面上的位置(Point)。

    • 缩放:目标页面上的缩放因子(float)。

    • xref:项目的xref(如果无 PDF,则为 0)。

    • 颜色:PDF RGB 格式中的项目颜色(red, green, blue),或省略(如果没有 PDF 则始终省略)。

    • 粗体:如果为粗体项目文本或省略,则为 true。仅适用于 PDF。

    • 斜体:如果为斜体项目文本,则为 true,或省略。仅适用于 PDF。

    • collapse:如果子项目折叠,则为 true,或省略。仅适用于 PDF。

    • nameddest:如果 kind=4,则为目标名称。仅适用于 PDF。(1.23.7 新增。)

xref_get_keys(xref)
  • v1.18.7 新增内容

仅适用于 PDF:返回xref所提供的dictionary对象的 PDF 字典键。

参数:

xrefint)– 项目的xref(v1.18.10 中更改) 使用-1访问特殊字典“PDF 尾部”。

返回:

dictionary对象的 PDF 字典键的返回类型和值。

>>> from pprint import pprint
>>> import pymupdf
>>> doc=pymupdf.open("pymupdf.pdf")
>>> xref = doc.page_xref(0)  # xref of page 0
>>> pprint(doc.xref_get_keys(xref))  # primary level keys of a page
('Type', 'Contents', 'Resources', 'MediaBox', 'Parent')
>>> pprint(doc.xref_get_keys(-1))  # primary level keys of the trailer
('Type', 'Index', 'Size', 'W', 'Root', 'Info', 'ID', 'Length', 'Filter')
>>> 
xref_get_key(xref, key)
  • v1.18.7 新增内容

仅适用于 PDF:给定其 xref 的dictionary对象的 PDF 字典键的返回类型和值。

参数:

  • xref (int) – xref在 v1.18.10 中更改: 使用 -1 来访问特殊字典 “PDF 尾页”。

  • key (str) – 所需的 PDF 键。必须 完全 匹配(区分大小写),其中之一包含在 Document.xref_get_keys() 中。

返回类型:

元组

返回:

一个字符串元组 (type, value),其中 type 是以下之一的字符串:“xref”, “array”, “dict”, “int”, “float”, “null”, “bool”, “name”, “string” 或 “unknown”(不应该出现)。无论 “type” 如何,键的值 总是 格式化为字符串 – 见下面的示例 – 并且(几乎总是)忠实地反映了存储在 PDF 中的内容。在大多数情况下,值字符串的格式也提供了有关键类型的线索:

  • “name” 总是以 “/” 斜杠开头。

  • “xref” 总是以 “ 0 R” 结尾。

  • “array” 总是用 “[…]” 括起来。

  • “dict” 总是用 “<<…>>” 括起来。

  • “bool”,“null” 始终等于 “true”,“false”,“null”。

  • “float” 和 “int” 用它们的字符串格式表示 – 因此不总是可以区分。

  • “string” 被转换为 UTF-8,因此可能与存储在 PDF 中的内容不同。例如,PDF 键 “Author” 可能在文件中具有值 “”,但该方法将返回 ('string', 'Jorj X. McKie')

    >>> for key in doc.xref_get_keys(xref):
     print(key, "=" , doc.xref_get_key(xref, key))
    Type = ('name', '/Page')
    Contents = ('xref', '1297 0 R')
    Resources = ('xref', '1296 0 R')
    MediaBox = ('array', '[0 0 612 792]')
    Parent = ('xref', '1301 0 R')
    >>> #
    >>> # Now same thing for the PDF trailer.
    >>> # It has no xref, so -1 must be used instead.
    >>> #
    >>> for key in doc.xref_get_keys(-1):
     print(key, "=", doc.xref_get_key(-1, key))
    Type = ('name', '/XRef')
    Index = ('array', '[0 8802]')
    Size = ('int', '8802')
    W = ('array', '[1 3 1]')
    Root = ('xref', '8799 0 R')
    Info = ('xref', '8800 0 R')
    ID = ('array', '[<DC9D56A6277EFFD82084E64F9441E18C><DC9D56A6277EFFD82084E64F9441E18C>]')
    Length = ('int', '21111')
    Filter = ('name', '/FlateDecode')
    >>> 
    
xref_set_key(xref, key, value)
  • 在 v1.18.7 新增,v 1.18.13 中更改

  • 在 v1.19.4 中更改:如果设置为 “null”,则“物理”删除一个键。

仅限于 PDF:为其 xref 指定的 dictionary 对象的键设置(添加,更新,删除)其值。

注意

这是一个专家功能:如果您不知道自己在做什么,可能会导致(部分)PDF 无法使用。请参阅 Adobe PDF References,了解对象规范格式(第 18 页)和特殊字典类型(如页面对象)的结构。

参数:

  • xref (int) – xref在 v1.18.13 中更改: 要更新 PDF 尾页,指定 -1。

  • key (str) – 所需的 PDF 键(无前导 “/”)。必须不为空。任何有效的 PDF 键 – 无论已存在于对象中(将被覆盖) – 或新键。可以使用类似 "Resources/ExtGState" 的 PDF 路径表示法,这会将键 "/ExtGState" 的值设置为 "/Resources" 的子对象。

  • value (str) – 键的值。必须是非空字符串,并且根据所需的 PDF 对象类型必须遵守以下规则。有一些语法检查,但 没有类型检查 和 PDF 方面的 语义检查。大小写很重要!

  • xref – 必须提供为 "nnn 0 R",带有 PDF 的有效 xref 编号 nnn。后缀 “0 R” 是 PDF 应用程序能够识别 xref 的必要标识符。

  • array – 像"[a b c d e f]"这样的字符串。括号是必需的。数组项必须至少用一个空格分隔(不像 Python 中的逗号)。空数组"[]"是可能的,并且等效于移除该键。数组项可以是任何 PDF 对象,如字典、xrefs、其他数组等。与 Python 类似,数组项可以是不同类型的。

  • dict – 像"<< ... >>"这样的字符串。括号是必需的,必须包含有效的 PDF 字典定义。空字典"<<>>"是可能的,并且等效于移除该键。

  • int – 作为字符串格式化的整数。

  • float – 作为字符串格式化的浮点数。PDF 不允许使用科学计数法(带有指数)。

  • null – 字符串"null"。这是 PDF 中类似于 Python 的None,会导致键被忽略 – 不过不一定在保存时移除,或在垃圾收集时移除。在 v1.19.4 中更改:如果键不是路径层次结构(即不包含斜杠“/”),则将完全删除该键。

  • bool – 字符串之一"true""false"

  • name – 带有前导斜杠的有效 PDF 名称,例如"/PageLayout"。参见 Adobe PDF 参考手册第 16 页。

  • string – 有效的 PDF 字符串。所有 PDF 字符串必须用括号括起来。空字符串表示为"()"。根据其内容,可能的括号是

    • “(…)”用于仅 ASCII 文本。保留的 PDF 字符必须反斜杠转义,非 ASCII 字符必须作为 3 位数字反斜杠转义的八进制提供 – 包括前导零。例如:12 = 0x0C 必须编码为014

    • “<…>”用于十六进制编码的文本。每个字符必须由两个十六进制数字(大小写不限)表示。

    • 如果有疑问,我们强烈建议使用get_pdf_str()!该函数会自动生成正确的括号、转义和整体格式。例如,它将执行如下转换:

      >>> # because of the € symbol, the following yields UTF-16BE BOM
      >>> pymupdf.get_pdf_str("Pay in $ or €.")
      '<feff00500061007900200069006e002000240020006f0072002020ac002e>'
      >>> # escapes for brackets and non-ASCII
      >>> pymupdf.get_pdf_str("Prices in EUR (USD also accepted). Areas are in m².")
      '(Prices in EUR \\(USD also accepted\\). Areas are in m\\262.)' 
      
get_page_pixmap(pno: int, *, matrix: matrix_like = Identity, dpi=None, colorspace: Colorspace = csRGB, clip: rect_like = None, alpha: bool = False, annots: bool = True)

从第pno页(从零开始)创建一个位图。调用Page.get_pixmap()

除了pno之外的所有参数都是仅限关键字的。

参数:

pno (int) – 页面编号,在-∞ < pno < page_count中为基于零的。

返回类型:

Pixmap

get_page_xobjects(pno)
  • v1.16.13 中的新功能

  • 在 v1.18.11 中更改

仅限 PDF:返回页面引用的所有 XObject 的列表。

参数:

pno (int) – 页面编号,从 0 开始,-∞ < pno < page_count

返回类型:

列表

返回:

一个(非图像)XObject 列表。这些对象通常代表从其他 PDF 文件嵌入(而不是复制)的页面。例如,Page.show_pdf_page()将创建这种类型的对象。列表中的每一项具有以下布局:(xref, name, invoker, bbox),其中

  • xref (int) 是 XObject 的xref

  • name (str) 是用于引用 XObject 的符号名称。

  • invokerint)调用 XObject 的xref或如果页面直接调用它,则为零。

  • bbox(Rect)XObject 在页面上未转换坐标中的边界框。要获取实际的非旋转页面坐标,请与页面的变换矩阵Page.transformation_matrix相乘。在 v.18.11 中更改:bbox 现在格式为 Rect。

get_page_images(pno, full=False)

仅限 PDF:返回页面直接或间接引用的所有图像列表。

参数:

  • pnoint) - 页面编号,从 0 开始,-∞ < pno < page_count

  • fullbool) - 是否还包括引用者的xref(如果这是页面,则为零)。

返回类型:

列表

返回:

由此页面引用的图像列表。每个项看起来像

(xref, smask, width, height, bpc, colorspace, alt. colorspace, name, filter, referencer)

在哪里

  • xrefint)是图像对象编号。
  • smaskint)是其软蒙版图像的对象编号。
  • widthheightints)是图像的尺寸。
  • bpcint)表示每个组件的位数(通常为 8)。
  • colorspacestr)是命名颜色空间的字符串(例如DeviceRGB)。
  • alt. colorspacestr)是依赖于colorspace值的任何备选颜色空间。
  • namestr)是引用图像的符号名称。
  • filterstr)是图像的解码滤波器(Adobe PDF References,第 22 页)。
  • referencerint)引用者的xref。如果直接由页面引用,则为零。仅在full=True时存在。

注意

一般而言,这不是实际显示的图像列表。此方法仅解析几个 PDF 对象以收集对嵌入图像的引用。它不分析页面的contents,其中定义了所有实际图像显示命令。要获取此信息,请使用Page.get_image_info()。还请参阅 textpage.html#textpagedict 部分中的字典输出结构讨论。

get_page_fonts(pno, full=False)

仅限 PDF:返回页面直接或间接引用的所有字体列表。

参数:

  • pnoint) - 页面编号,从 0 开始,-∞ < pno < page_count

  • fullbool) - 是否还包括引用者的xref。如果True,返回的条目将再多一个条目。如果需要知道页面是否直接引用字体,请使用此选项。在这种情况下,最后一个条目为 0。如果字体由页面的/XObject 引用,则在这里找到其xref

返回类型:

列表

返回:

由此页面引用的字体列表。每个条目看起来像

(xref, ext, type, basefont, name, encoding, referencer)

在哪里

  • xref (int) 是字体对象号码(如果 PDF 直接使用内置字体,则可能为零)
  • ext (str) 字体文件扩展名(例如“ttf”,参见 Font File Extensions)
  • type (str) 是字体类型(如“Type1”或“TrueType”等)
  • basefont (str) 是基础字体名称,
  • name (str) 是字体的符号名称,用于引用
  • encoding (str) - 如果与内置编码不同,字体的字符编码(Adobe PDF References,第 254 页):
  • referencer (int 可选) 引用者的 xref。如果页面直接引用,则为零;否则为 XObject 的 xref。仅在full=True时出现。

示例:

>>> pprint(doc.get_page_fonts(0, full=False))
[(12, 'ttf', 'TrueType', 'FNUUTH+Calibri-Bold', 'R8', ''),
 (13, 'ttf', 'TrueType', 'DOKBTG+Calibri', 'R10', ''),
 (14, 'ttf', 'TrueType', 'NOHSJV+Calibri-Light', 'R12', ''),
 (15, 'ttf', 'TrueType', 'NZNDCL+CourierNewPSMT', 'R14', ''),
 (16, 'ttf', 'Type0', 'MNCSJY+SymbolMT', 'R17', 'Identity-H'),
 (17, 'cff', 'Type1', 'UAEUYH+Helvetica', 'R20', 'WinAnsiEncoding'),
 (18, 'ttf', 'Type0', 'ECPLRU+Calibri', 'R23', 'Identity-H'),
 (19, 'ttf', 'Type0', 'TONAYT+CourierNewPSMT', 'R27', 'Identity-H')] 

注意

  • 此列表没有重复条目:xrefnamereferencer 的组合是唯一的。

  • 一般来说,这是实际页面使用的字体的超集。例如,PDF 创建者可能已指定一些全局列表,每个页面只使用部分内容。

get_page_text(pno, output='text', flags=3, textpage=None, sort=False)

提取给定页码(从零开始)pno 的页面文本。调用 Page.get_text()

参数:

pno (int) – 页面号码,从零开始,任何值 -∞ < pno < page_count

对于其他参数,请参阅页面方法。

返回类型:

str

layout(rect=None, width=0, height=0, fontsize=11)

根据给定的页面尺寸和字体大小重新分页(“重排”)文档。这仅影响某些文档类型,如电子书和 HTML。如果不支持,则忽略。支持的文档在属性is_reflowable中有True

参数:

  • rect (rect_like) – 所需的页面尺寸。必须是有限的,不为空,并从点 (0, 0) 开始。

  • width (float) – 与 height 一起使用,作为 rect 的替代。

  • height (float) – 与 width 一起使用,作为 rect 的替代。

  • fontsize (float) – 所需的默认字体大小。

select(s)

仅适用于 PDF:保留文档中指定页码的页面。空序列或超出 range(doc.page_count) 范围的元素将引发 ValueError。更多详细信息请参见本章末尾或本章说明。

参数:

s (sequence) – 页面号码序列(从零开始),要包含的页面。不在序列中的页面将被删除(从内存中),并在文档重新打开之前不可用。页面号码可以多次出现且顺序任意:生成的文档将完全按指定的序列排列。

注意

  • 序列中的页面号码不需要唯一,也不需要特定顺序。这使得该方法成为一个多功能实用工具,例如仅选择偶数页或奇数页,或满足其他某些条件等。

  • 在技术层面上,该方法始终会创建一个新的 pagetree

  • 当处理少量页面时,方法 copy_page()move_page()delete_page() 更易于使用。事实上,它们也快得多-当文档有许多页面时,至少快一个数量级。

set_metadata(m)

仅限 PDF:根据 m 中指定的内容设置或更新文档的元数据,一个 Python 字典。

参数:

m (dict) – 与 metadata(见下文)具有相同键的字典。所有键都是可选的。PDF 的格式和加密方法无法设置或更改,将被忽略。如果任何值不应包含数据,请不要指定其键或将值设置为 None。如果您使用 {},所有元数据信息将被清除为字符串 “none”。如果您只想选择性地更改一些值,请修改 doc.metadata 的副本并将其用作参数。如果指定为 UTF-8 编码,可能会出现任意的 Unicode 值。

(在 v1.18.4 中更改) 空值或“none”不再被写入,而是完全被省略。

get_xml_metadata()

仅限 PDF:获取文档的 XML 元数据。

返回类型:

str

返回:

文档的 XML 元数据。如果不存在或不是 PDF,则为空字符串。

set_xml_metadata(xml)

仅限 PDF:设置或更新文档的 XML 元数据。

参数:

xml (str) – 新的 XML 元数据。应该是 XML 语法,但此方法不进行任何检查,接受任何字符串。

set_pagelayout(value)
  • v1.22.2 中的新功能

仅限 PDF:设置 /PageLayout

参数:

value (str) – 字符串之一“SinglePage”,“OneColumn”,“TwoColumnLeft”,“TwoColumnRight”,“TwoPageLeft”,“TwoPageRight”。支持小写。

set_pagemode(value)
  • v1.22.2 中的新功能

仅限 PDF:设置 /PageMode

参数:

value (str) – 字符串之一“UseNone”,“UseOutlines”,“UseThumbs”,“FullScreen”,“UseOC”,“UseAttachments”。支持小写。

set_markinfo(value)
  • v1.22.2 中的新功能

仅限 PDF:设置 /MarkInfo 值。

参数:

value (dict) – 一个像这样的字典:{"Marked": False, "UserProperties": False, "Suspects": False}。该字典包含有关标记 PDF 约定使用情况的信息。详情请参阅 PDF 规范

set_toc(toc, collapse=1)

仅限 PDF:用提供的参数替换完整的当前大纲树(目录)。执行成功后,可以像往常一样通过 Document.get_toc() 或通过 Document.outline 访问新的大纲树。与其他面向输出的方法一样,只有通过 save()(支持增量保存)更改才会变得永久。在内部,该方法由以下两个步骤组成。有关演示,请参见下面的示例。

  • 第一步删除所有现有的书签。

  • 第二步从 toc 中包含的条目创建新的目录。

参数:

  • toc (sequence) –

    包含所有书签条目的列表/元组,这些条目应形成新的目录。get_toc()的输出变体是可接受的。要完全删除目录,请指定一个空序列或 None。每个项目必须是具有以下格式的列表。

    • [lvl, title, page [, dest]],其中

      • lvl是项目的层次级别(int > 0),第一个项目必须为 1,且最多比前一个项目大 1。

      • title(str)是要显示的标题。假定其为 UTF-8 编码(仅适用于多字节代码点)。

      • page(int)是目标页码 (注意:基于 1)。如果为正数,必须在有效范围内。如果没有目标或目标是外部的,请将其设置为-1。

      • dest(可选)是一个字典或一个数字。如果是数字,它将被解释为页面上此条目应指向的期望高度(以点为单位)。使用字典(例如由get_toc(False)输出的字典)可以详细控制书签的属性,请参阅Document.get_toc()进行描述。

  • collapseint) - (新于 v1.16.9)控制超出哪个层次级别的大纲条目应最初显示折叠。默认为 1,因此仅显示级别 1,必须使用 PDF 查看器展开更高级别。要展开所有内容,请指定较大的整数,0 或 None。

返回类型:

int

返回:

插入或删除的项目数。

从 v1.23.8 开始更改:目标“to”坐标现在应与get_toc()返回的坐标系相同(内部它们现在使用page.cropboxpage.rotation_matrix进行转换)。例如,set_toc(get_toc())现在给出未更改的目标“to”坐标。

outline_xref(idx)
  • 从 v1.17.7 开始新增

仅 PDF:返回大纲项的xref。这主要用于内部目的。

参数 int idx:列表Document.get_toc()中项目的索引。

返回:

xref

del_toc_item(idx)
  • 从 v1.17.7 开始新增

  • 从 v1.18.14 开始更改:不再删除项目的文本,而是显示为灰色。

仅 PDF:删除此 TOC 项。这是一种高速方法,禁用了相应的项目,但保留了整体的 TOC 结构。在物理上,项目仍然存在于 TOC 树中,但以灰色显示,并且不再指向任何目标。

这也意味着,当需要时,您可以使用Document.set_toc_item()重新分配项目到新的目标。

参数:

idxint) - 列表Document.get_toc()中项目的索引。

set_toc_item(idx, dest_dict=None, kind=None, pno=None, uri=None, title=None, to=None, filename=None, zoom=0)
  • 从 v1.17.7 开始新增

  • 从 v1.18.6 开始更改

仅适用于 PDF:更改由其索引标识的 TOC 条目。更改条目的标题目标外观(颜色、粗体、斜体)或折叠子项,或者完全删除该项。

如果仅需要对选定条目进行特定更改并且想避免替换完整的 TOC,则使用此方法。在处理大型目录时尤其有益。

参数:

  • idx (int) – 由Document.get_toc()创建的列表中条目的索引。

  • dest_dict (dict) – 新的目标。类似于doc.get_toc(False)中条目的最后一个条目的字典。建议使用此作为模板。如果给出,则忽略所有其他参数 – 除了标题。

  • kind (int) – 链接种类,参见链接目的地种类。如果是LINK_NONE,则所有剩余参数将被忽略,TOC 条目将被删除,与Document.del_toc_item()相同。如果为 None,则仅修改标题,忽略其余参数。其他所有值都将使用后续参数创建新的目的地字典。

  • pno (int) – 基于 1 的页码,即 1 <= pno <= doc.page_count。LINK_GOTO 操作必需的参数。

  • uri (str) – URL 文本。LINK_URI 操作必需的参数。

  • title (str) – 所需的新标题。如果不更改,则为 None。

  • to (point_like) – (可选)指向目标页面上的坐标。对 LINK_GOTO 操作相关。如果省略,则选择靠近页面顶部的点。

  • filename (str) – LINK_GOTOR 和 LINK_LAUNCH 操作所需的文件名。

  • zoom (float) – 在显示目标页面时使用的缩放因子。

示例用法: 更改 SWIG 手册的 TOC 以实现以下效果:

折叠所有低于顶级的内容,并以红色、粗体和斜体显示 Python 支持章节:

>>> import pymupdf
>>> doc=pymupdf.open("SWIGDocumentation.pdf")
>>> toc = doc.get_toc(False)  # we need the detailed TOC
>>> # list of level 1 indices and their titles
>>> lvl1 = [(i, item[1]) for i, item in enumerate(toc) if item[0] == 1]
>>> for i, title in lvl1:
 d = toc[i][3]  # get the destination dict
 d["collapse"] = True  # collapse items underneath
 if "Python" in title:  # show the 'Python' chapter
 d["color"] = (1, 0, 0)  # in red,
 d["bold"] = True  # bold and
 d["italic"] = True  # italic
 doc.set_toc_item(i, dest_dict=d)  # update this toc item
>>> doc.save("NEWSWIG.pdf",garbage=3,deflate=True) 

在前面的例子中,我们仅更改了文件中 1240 个 TOC 条目中的 42 个。

bake(*, annots=True, widgets=True)

仅适用于 PDF:将注释和/或小部件转换为页面的永久部分。通过这种方法,PDF 将被更改。如果widgetsTrue,文档也将不再是“表单 PDF”。

所有页面看起来都一样,但将不再有注释或字段。可见部分将根据需要转换为标准文本、矢量图形或图像。

因此,通过使用Document.convert_to_pdf(),这种方法可能是 PDF 到 PDF 转换的一个可行替代方法

请考虑注释是复杂对象,可能由更多“底层”数据组成。例如,“Text”和“FileAttachment”注释。使用此方法“烘烤”注释/小部件时,所有这些底层信息(附加文件、评论、相关弹出式注释等)将在下次垃圾收集时丢失并被删除。

比如,用于 Document.insert_pdf() 方法(不支持复制小部件)或 Page.show_pdf_page() 方法(不支持注释和小部件),源页面在目标页面中应该完全一样时使用此功能。

参数:

  • annots (bool) – 转换注释。

  • widgets (bool) – 转换字段 / 小部件。执行后,文档将不再是“表单 PDF”。

can_save_incrementally()
  • 自 v1.16.0 新增

检查文档是否可以增量保存。在选择正确选项时使用,避免遇到异常。

scrub(attached_files=True, clean_pages=True, embedded_files=True, hidden_text=True, javascript=True, metadata=True, redactions=True, redact_images=0, remove_links=True, reset_fields=True, reset_responses=True, thumbnails=True, xml_metadata=True)
  • 自 v1.16.14 新增

仅适用于 PDF:从 PDF 中删除潜在敏感数据。此功能受 Adobe Acrobat 产品中类似“Sanitize”功能的启发。该过程可通过多个选项进行配置。

参数:

  • attached_files (bool) – 查找“FileAttachment”注释并删除文件内容。

  • clean_pages (bool) – 从页面绘画源中删除任何注释。如果此选项设置为 False,那么对于 hidden_textredactions 也会执行相同操作。

  • embedded_files (bool) – 删除嵌入文件。

  • hidden_text (bool) – 删除 OCR 文本和不可见文本[7]

  • javascript (bool) – 删除 JavaScript 源代码。

  • metadata (bool) – 删除 PDF 标准元数据。

  • redactions (bool) – 应用删除注释。

  • redact_images (int) – 如果应用删除操作,处理图像的方法。可选值为 0(忽略)、1(覆盖重叠区域)或 2(删除)。

  • remove_links (bool) – 删除所有链接。

  • reset_fields (bool) – 将所有表单字段重置为默认值。

  • reset_responses (bool) – 从所有注释中删除所有响应。

  • thumbnails (bool) – 从页面中删除缩略图图像。

  • xml_metadata (bool) – 删除 XML 元数据。

save(outfile, garbage=0, clean=False, deflate=False, deflate_images=False, deflate_fonts=False, incremental=False, ascii=False, expand=0, linear=False, pretty=False, no_new_id=False, encryption=PDF_ENCRYPT_NONE, permissions=-1, owner_pw=None, user_pw=None, use_objstms=0)
  • 自 v1.18.7 更改

  • 自 v1.19.0 起更改

  • 自 v1.24.1 更改

仅适用于 PDF:以当前状态保存文档。

参数:

  • outfile (str,Path,fp) – 要保存到的文件路径、pathlib.Path 或文件对象。文件对象必须在之前通过 open(...)io.BytesIO() 创建。选择 io.BytesIO() 相当于 Document.tobytes() 下的 getvalue() 输出,这相当于内部创建的 io.BytesIO()getvalue()

  • garbage (int) –

    进行垃圾回收。正值排除“增量”。

    • 0 = 无

    • 1 = 删除未使用(未引用)的对象。

    • 2 = 除了 1 之外,压缩 xref 表。

    • 3 = 除了 2 之外,合并重复的对象。

    • 4 = 除了 3 之外,检查 stream 对象是否重复。这可能很慢,因为这类数据通常很大。

  • clean (bool) – 清理和消毒内容流[1]。对应于“mutool clean -sc”。

  • deflate (bool) – 压缩未压缩的流。

  • deflate_images (bool) – (自 v1.18.3 新增) 压缩未压缩的图像流。

  • deflate_fonts (bool) – (自 v1.18.3 新增) 压缩未压缩的字体文件流。

  • incremental (bool) – 仅保存 PDF 的更改。排除“垃圾”和“线性”。只能在outfile是字符串或pathlib.Path且等于Document.name时使用。不能用于已解密或修复的文件以及其他一些情况。请确认 Document.can_save_incrementally() 如果为假,则需要保存到新文件。

  • ascii (bool) – 将二进制数据转换为 ASCII。

  • expand (int) –

    解压对象。生成可以被其他程序更好读取的版本,从而导致更大的文件。

    • 0 = 无

    • 1 = 图像

    • 2 = 字体

    • 255 = 全部

  • linear (bool) – 保存文档的线性化版本。此选项创建了一个针对 Internet 访问性能改进的文件格式。排除“增量”选项。

  • pretty (bool) – 美化文档源以提高可读性。PDF 对象将重新格式化,看起来像Document.xref_object()的默认输出。

  • no_new_id (bool) – 抑制文件的/ID字段更新。如果文件根本没有此类字段,则还抑制创建新的字段。默认为False,因此每次保存都会导致文件标识的更新。

  • permissions (int) – (自 v1.16.0 新增) 设置所需的权限级别。参见 文档权限 获取可能的值。默认为授予全部权限。

  • encryption (int) – (自 v1.16.0 新增) 设置所需的加密方法。参见 PDF 加密方法代码 获取可能的值。

  • owner_pw (str) – (自 v1.16.0 新增) 设置文档的所有者密码。(自 v1.18.3 更改) 如果未提供,则使用用户密码(如果提供)。字符串长度不能超过 40 个字符。

  • user_pw (str) – (自 v1.16.0 新增) 设置文档的用户密码。字符串长度不能超过 40 个字符。

  • use_objstms (int) – (自 v1.24.0 新增) 压缩选项,将符合条件的 PDF 对象定义转换为存储在其他对象的stream数据中的信息。根据deflate参数值,转换后的对象定义将被压缩,这可能导致文件大小显著减小。

警告

该方法不检查是否已存在同名文件,因此不会请求确认并覆盖文件。这是程序员处理的责任。

注意

文件大小减小

1. 使用保存选项,如 garbage=3|4, deflate=True, use_objstms=True|1。不要触碰默认值 expand=False|0, clean=False|0, incremental=False|0。这是一种“无损”文件大小减小方法。有一个方便的版本,这些值默认设置为Document.ez_save(),请参见下文。

  1. 实质上的“有损”文件大小减小必须放弃某些与图像相关的东西,比如(a)删除所有图像(b)将图像替换为其灰度版本(c)减少图像分辨率。在PyMuPDF Utilities “replace-image”文件夹中找到示例。
ez_save(*args, **kwargs)
  • 在 v1.18.11 中新增

仅限 PDF:与Document.save()相同,但默认值已更改为 deflate=True, garbage=3, use_objstms=1

saveIncr()

仅限 PDF:增量保存文档。这是一个方便的缩写,等同于 doc.save(doc.name, incremental=True, encryption=PDF_ENCRYPT_KEEP)

注意

如果文档包含经过验证的签名,保存到新文件可能会使签名失效,则可能需要进行增量保存。

tobytes(garbage=0, clean=False, deflate=False, deflate_images=False, deflate_fonts=False, ascii=False, expand=0, linear=False, pretty=False, no_new_id=False, encryption=PDF_ENCRYPT_NONE, permissions=-1, owner_pw=None, user_pw=None, use_objstms=0)
  • 在 v1.18.7 中更改

  • 在 v1.19.0 中更改

  • 在 v1.24.1 中更改

仅限 PDF:将当前文档的内容写入字节对象,而不是写入文件。显然,您应该对内存需求保持警惕。参数的含义与save()中的参数完全相同。章节 FAQ 中包含了一个使用此方法作为pdfrw的预处理器的示例。

(在 v1.16.0 中更改) 以支持扩展的加密支持。

返回类型:

字节

返回:

一个包含完整文档的字节对象。

search_page_for(pno, text, quads=False)

在“pno”页上搜索“text”。与相应的Page.search_for()完全相同。任何整数 -∞ < pno < page_count 都可以接受。

insert_pdf(docsrc, from_page=-1, to_page=-1, start_at=-1, rotate=-1, links=True, annots=True, show_progress=0, final=1)
  • 在 v1.19.3 中更改 - 作为对问题#537的修复,表单字段始终被排除。

仅限 PDF:将 PDF 文档docsrc中的页面范围 [from_page, to_page](两者都包括)复制到当前文档中。插入将从页码 start_at 开始。值 -1 表示默认值。因此复制的所有页面都将按指定的方式旋转。链接和注释可以在目标中排除,详见下文。所有页码都是基于 0 的。

参数:

  • docsrc (Document) – 一个已打开的 PDF Document,不能是当前文档。但是,它可以引用相同的底层文件。

  • from_page (int) – docsrc 中的第一页页码。默认为零。

  • to_page (int) – 复制的docsrc中的最后一页页码。默认为最后一页。

  • start_at (int) – 复制的第一页,将成为目标中的页码 start_at。默认值 -1 将页面范围追加到末尾。如果为零,则页面范围将插入到当前第一页之前。

  • rotate (int) – 所有复制的页面将以提供的值旋转(度,90 的整数倍)。

  • links (bool) – 选择是否包括链接(内部和外部)在复制中。默认为True命名链接(LINK_NAMED)和指向超出复制页面范围的内部链接总是被排除在外

  • annots (bool) – (v1.16.1 新增) 选择是否在复制中包括注释。表单字段永远不会被复制 – 请参见下文。

  • show_progress (int) – (v1.17.7 新增) 指定大于零的间隔大小以在sys.stdout上看到进度消息。在每个间隔之后,将打印类似Inserted 30 of 47 pages.的消息。

  • final (int) – (v1.18.0 新增) 控制此方法后是否应删除已复制对象的列表,默认True。对于从同一源 PDF 中进行的多次插入中的最后一次,将其设置为 0。这可以节省目标文件大小,并显著加快执行速度。

注意

  1. 这是一种基于页面的方法。因此,源文档的文档级信息将被忽略。示例包括可选内容、嵌入文件、StructureElemAcroForm、目录、页面标签、元数据、命名目标(和其他命名条目)等。因此,具体地说,表单字段(小部件)永远不能被复制 – 尽管它们似乎只出现在页面上。查看Document.bake()以转换源文档,如果您至少需要保留小部件外观

  2. 如果from_page > to_page,页面将以相反的顺序复制。如果0 <= from_page == to_page,那么将复制一页。

  3. docsrc TOC 条目不会被复制。然而,很容易为生成的文档恢复目录。查看下面的示例以及examples目录中的程序join.py:它可以连接 PDF 文档,并同时拼接目录的各个部分。

insert_file(infile, from_page=-1, to_page=-1, start_at=-1, rotate=-1, links=True, annots=True, show_progress=0, final=1)
  • v1.22.0 新增

仅限 PDF:将任意支持的文档添加到当前 PDF 中。打开“infile”作为文档,将其转换为 PDF,然后调用Document.insert_pdf()。参数与该方法相同。除其他外,这还提供了一种将图像附加为输出 PDF 的完整页面的简单方法。

参数:

infile (multiple) – 要插入的输入文档。可以是一个文件名规范,与创建 Document 或 Pixmap 有效的相同。

new_page(pno=-1, width=595, height=842)

仅限 PDF:插入空白页。

参数:

  • pno (int) – 应在其前插入新页面的页码。必须在1 < pno <= page_count。特殊值-1 和doc.page_count在最后一页之后插入之后

  • width (float) – 页面宽度。

  • height (float) – 页面高度。

返回类型:

Page

返回:

创建的页面对象。

insert_page(pno, text=None, fontsize=11, width=595, height=842, fontname='helv', fontfile=None, color=None)

仅适用于 PDF:插入一个新页面并插入一些文本。这是一个方便函数,结合了 Document.new_page() 和(部分)Page.insert_text() 的功能。

参数:

pnoint)–

页面号(基于 0)之前要插入的位置。必须在 range(-1, doc.page_count + 1) 内。特殊值 -1 和 doc.page_count 在文档的最后一页之后插入。

自 v1.14.12 版本更改

此参数现在是位置参数。

对于其他参数,请参阅上述方法。

返回类型:

int

返回:

返回 Page.insert_text() 的结果(成功插入行数)。

delete_page(pno=-1)

仅适用于 PDF:按 0-based 页面号删除页面,范围为 -∞ < pno < page_count - 1

  • 自 v1.18.14 版本更改:支持 Python 的 del 语句。

参数:

pnoint)– 要删除的页面。负数从文档末尾开始计数(类似于索引)。默认为最后一页。

delete_pages(*args, **kwds)
  • 自 v1.18.13 版本更改:删除页面时具有更大的灵活性。

  • 自 v1.18.14 版本更改:支持 Python 的 del 语句。

仅适用于 PDF:按 0-based 页面号删除多个页面。

格式 1: 使用关键字。表示旧格式。删除一段连续的页面。

  • “from_page”: 要删除的第一页。如果省略,为零。

  • “to_page”: 要删除的最后一页。如果省略,将删除文档中的最后一页。必须不小于 “from_page”。

格式 2: 作为位置参数的两个页面号。与格式 1 类似处理。

格式 3: 一个位置整数参数。相当于 Page.delete_page()

格式 4: 一种 listtuplerange() 类型的位置参数,包含要删除的页面号。此序列的项目可以按任何顺序排列,并且可以包含重复项。

格式 5:在 v1.18.14 中新增)现在支持使用 Python 的 del 语句和索引/切片表示法。

注意

在 v1.14.17 中更改,v1.17.7 中优化)为了维护有效的 PDF 结构,此方法和 delete_page() 也会禁用指向已删除页面的目录项。在此处,“禁用”意味着书签将指向空白处,并且支持 PDF 查看器会将标题显示为灰色。总体的目录结构保持不变。

还将删除剩余页面上指向已删除页面的任何链接。对于包含许多页面的文档,此操作可能需要较长的响应时间。

以下示例都将删除从页面 500 到 519 的页面:

  • doc.delete_pages(500, 519)

  • doc.delete_pages(from_page=500, to_page=519)

  • doc.delete_pages((500, 501, 502, ... , 519))

  • doc.delete_pages(range(500, 520))

  • del doc[500:520]

  • del doc[(500, 501, 502, ... , 519)]

  • del doc[range(500, 520)]

对于 Adobe PDF 参考手册,上述操作大约需要 0.6 秒,因为必须清除其余 1290 页中的无效链接。

通常情况下,该方法的性能取决于剩余页面的数量,而不是删除页面的数量:在上述示例中,删除除了那 20 页之外的所有页面,需要的时间要少得多。

copy_page(pno, to=-1)

仅适用于 PDF:在文档内部复制页面引用。

参数:

  • pnoint)- 要复制的页面。必须在0 <= pno < page_count范围内。

  • toint)- 要复制的页面号。默认情况下插入最后一页之后。

注释

只会创建对页面对象的新引用- 不是新的页面对象,所有复制的页面都将具有相同的属性值,包括Page.xref。这意味着对其中一个副本的更改将出现在所有副本上。

fullcopy_page(pno, to=-1)
  • 新版本 v1.14.17 中新增

仅适用于 PDF:制作页面的完整副本(复制)。

参数:

  • pnoint)- 要复制的页面。必须在0 <= pno < page_count范围内。

  • toint)- 要复制的页面号。默认情况下插入最后一页之后。

注释

  • copy_page()相比,此方法创建一个新的页面对象(带有新的xref),可以独立于原始页面进行更改。

  • 任何弹出窗口和“IRT”(“响应于”)注释不会被复制,以避免潜在的不正确情况。

move_page(pno, to=-1)

仅适用于 PDF:在文档内部移动(复制然后删除原始)页面。

参数:

  • pnoint)- 要移动的页面。必须在0 <= pno < page_count范围内。

  • toint)- 要复制的页面前面的页码。默认情况下插入最后一页之后。

need_appearances(value=None)
  • 新版本 v1.17.4 中新增

仅适用于 PDF:获取或设置表单 PDF 的/NeedAppearances属性。引用:“(可选)指定是否为文档中的所有窗口注释构造外观流和外观字典... 默认值:false。”这可能有助于控制某些阅读器/查看器的行为。

参数:

valuebool)- 将属性设置为此值。如果省略或为None,则查询当前值。

返回类型:

布尔值

返回:

  • None:不是表单 PDF,或未定义属性。

  • True / False:属性的值(已设置或现有以进行查询)。如果没有表单 PDF,则没有影响。

get_sigflags()

仅适用于 PDF:返回文档是否包含签名字段。这是一个可选的 PDF 属性:如果不存在(返回值为-1),则无法得出结论- PDF 创建者可能只是没有使用它。

返回类型:

int

返回:

  • -1:不是表单 PDF/未记录签名字段/未找到SigFlags

  • 1:至少存在一个签名字段。

  • 3:包含可能在文件被保存(写入)时使其前一内容发生变化而无效的签名。

embfile_add(name, buffer, filename=None, ufilename=None, desc=None)
  • 从 v1.14.16 版本开始更改:位置参数“name”和“buffer”的顺序已更改,以符合其他函数的调用模式。

仅限 PDF:嵌入新文件。除了名称之外的所有字符串参数均可以是 Unicode(在之前的版本中,只有 ASCII 正常工作)。文件内容将被压缩(如果有利的话)。

参数:

  • name (str) – 条目标识符,不得已经存在

  • buffer (bytes,bytearray,BytesIO) –

    文件内容。

    (在 v1.14.13 中更改) 现在也支持 io.BytesIO

  • filename (str) – 可选的文件名。仅供文档使用,如果为 None,将设置为name

  • ufilename (str) – 可选的 Unicode 文件名。仅供文档使用,如果为 None,将设置为filename

  • desc (str) – 可选的描述。仅供文档使用,如果为 None,将设置为name

返回类型:

int

返回:

(在 v1.18.13 中更改) 现在该方法返回插入文件的xref。此外,基于当前日期时间,文件对象现在将自动获得 PDF 键 /CreationDate/ModDate

embfile_count()
  • 在 v1.14.16 中更改:现在这是一个方法。在以前的版本中,这是一个属性。

仅限 PDF:返回嵌入式文件的数量。

embfile_get(item)

仅限 PDF:通过其条目编号或名称检索嵌入文件的内容。如果文档不是 PDF,或者找不到条目,则会引发异常。

参数:

item (int,str) – 索引或条目的名称。整数必须在 range(embfile_count()) 内。

返回类型:

字节

embfile_del(item)
  • 在 v1.14.16 中更改:现在也可以通过索引删除项目。

仅限 PDF:从/EmbeddedFiles中删除条目。与往常一样,仅当将文档保存到具有适当的垃圾选项的新文件时,才会发生嵌入式文件内容的物理删除(以及文件空间的回收)。

参数:

item (int/str) – 索引或条目的名称。

警告

当指定条目名称时,此函数将仅删除具有该名称的第一项。请注意,未使用 PyMuPDF 创建的 PDF 可能包含重复名称。因此,您可能希望采取适当的预防措施。

embfile_info(item)
  • 在 v1.18.13 中更改

仅限 PDF:通过其编号或名称检索嵌入文件的信息。

参数:

item (int/str) – 索引或条目的名称。整数必须在 range(embfile_count()) 内。

返回类型:

字典

返回:

具有以下键的字典:

  • name – (str) 此条目存储的名称

  • filename – (str) 文件名

  • ufilename – (unicode) 文件名

  • desc – (str) 描述

  • size – (int) 原始文件大小

  • length – (int) 压缩文件长度

  • creationDate(在 v1.18.13 中新增) (str) 以 PDF 格式表示的项目创建日期时间

  • modDate(在 v1.18.13 中新增) (str) 最后一次更改的日期时间,以 PDF 格式表示

  • collection(在 v1.18.13 中新增) (int) 如果有的话,与关联 PDF 组合项的xref,否则为零。

  • checksum(在 v1.18.13 中新增) (str) 存储文件内容的哈希码,以十六进制字符串表示。根据 PDF 规范,应为 MD5,但应准备好看到其他哈希算法。

embfile_names()
  • 在 v1.14.16 中新增

仅限 PDF:返回嵌入文件名列表。名称的顺序与文档中的物理顺序相同。

返回类型:

列表

embfile_upd(item, buffer=None, filename=None, ufilename=None, desc=None)

仅限 PDF:根据其条目编号或名称更改嵌入文件。所有参数均为可选。让它们默认导致无操作。

参数:

  • itemint/str)– 条目的索引或名称。整数必须在 range(embfile_count()) 内。

  • bufferbytes,bytearray,BytesIO)–

    新文件内容。

    (在 v1.14.13 中更改)io.BytesIO 现在也受支持。

  • filenamestr)– 新的文件名。

  • ufilenamestr)– 新的 Unicode 文件名。

  • descstr)– 新描述。

(在 v1.18.13 中更改) 该方法现在返回文件对象的 xref

返回类型:

int

返回:

文件对象的 xref。其 /ModDate PDF 键将自动更新为当前日期时间。

close()

释放与文档相关的对象和空间分配。如果从文件创建,还会关闭 filename(将控制权释放给操作系统)。显式关闭文档等同于删除它,del doc 或将其分配给其他类似 doc = None

xref_object(xref, compressed=False, ascii=False)
  • 新功能在 v1.16.8 中

  • 在 v1.18.10 中更改

仅限 PDF:返回 PDF 对象的定义源。

参数:

  • xrefint)– 对象的 xref在 v1.18.10 中更改: 值为 -1 返回 PDF 尾部源。

  • compressedbool)– 是否生成没有换行或空格的紧凑输出。

  • asciibool)– 是否对二进制数据进行 ASCII 编码。

返回类型:

str

返回:

对象定义源。

pdf_catalog()
  • 新功能在 v1.16.8 中

仅限 PDF:返回 PDF 目录(或根)对象的 xref 编号。使用该编号与 Document.xref_object() 一起查看其源。

pdf_trailer(compressed=False)
  • 新功能在 v1.16.8 中

仅限 PDF:返回 PDF 的尾部源,通常位于 PDF 文件的末尾。这是 Document.xref_object()xref 参数为 -1 的结果。

xref_stream(xref)
  • 新功能在 v1.16.8 中

仅限 PDF:返回 xref 流对象的 解压缩 内容。

参数:

xrefint)– xref 编号。

返回类型:

字节

返回:

(解压后的)对象流。

xref_stream_raw(xref)
  • 新功能在 v1.16.8 中

仅限 PDF:返回 未修改(尤其是 未解压缩)的 xref 流对象的内容。否则等同于 Document.xref_stream()

返回类型:

字节

返回:

(原始的,未修改的)对象流。

update_object(xref, obj_str, page=None)
  • 新功能在 v1.16.8 中

仅限 PDF:用提供的字符串替换 xref 的对象定义。如果 xref 也是新的,则此指令完成对象定义。如果还提供了页面对象,则其链接和注释将在此之后重新加载。

参数:

  • xrefint) – xref 编号。

  • obj_strstr) – 包含有效的 PDF 对象定义的字符串。

  • page(Page) – 页面对象。如果提供,则表示该页面的注释应刷新(重新加载),以反映链接和/或注释所引起的更改。

返回类型:

int

返回:

如果成功则返回零,否则将引发异常。

update_stream(xref, data, new=False, compress=True)
  • 新功能 v.1.16.8

  • v1.19.2 中更改:添加参数 “compress”

  • v1.19.6 中更改:不推荐参数 “new”。现在确认对象是 PDF 字典对象。

替换由 xref 标识的对象的流,该对象必须是 PDF 字典。如果对象不是 stream,它将被转换为流。该函数会在有利时自动执行压缩操作(“deflate”)。

参数:

  • xrefint) – xref 编号。

  • streambytes|bytearray|BytesIO) –

    流的新内容。

    (v1.14.13 中更改:)io.BytesIO 对象现在也得到支持。

  • newbool) – 不推荐 和被忽略。将在 v1.20.0 之后删除。

  • compressbool) – 是否压缩插入的流。如果为 True(默认),则使用 /FlateDecode 压缩插入流(如果有利),否则按原样插入流。

抛出:

ValueError – 如果 xref 不表示 PDF dict。空字典 <<>> 是被接受的。因此,如果刚刚创建了 xref 并希望给它一个流,首先执行 doc.update_object(xref, "<<>>"),然后用此方法插入流数据。

该方法主要(但不仅限于)用于操作包含 PDF 操作符语法的流(参见 Adobe PDF References 的第 643 页),例如页面内容流。

如果更新内容流,请考虑使用保存参数 clean=True 来确保 PDF 操作符源和对象结构之间的一致性。

示例:假设您不再希望某个图片出现在页面上。可以通过删除其内容源的相应引用来实现此目的 - 确实如此:重新加载页面后,该图片将消失。但页面的 resources 对象仍将显示页面引用该图片。此保存选项将清理任何此类不匹配。

xref_copy(source, target, *, keep=None)
  • 新功能 v1.19.5

仅限 PDF:使 target xref 成为 source 的精确副本。如果 sourcestream,那么这些数据也会被复制。

参数:

  • sourceint) – 源 xref。必须是现有的 dictionary 对象。

  • targetint) – 目标 xref。必须是现有的 dictionary 对象。如果刚刚创建了 xref,请确保使用最小规格 <<>> 初始化为 PDF 字典。

  • keep (list) - target 中的顶级键的可选列表,应在复制过程的准备中保留。

注意

  • 该方法与 Python 的 dict 方法 copy() 有很多相似之处。

  • 两个 xref 数字必须代表现有字典。

  • 在从 source 复制数据之前,所有 target 字典键都将被删除。您可以在 keep 列表中指定对此的例外情况。但是,如果 source 有一个同名键,则其值仍将替换目标。

  • 如果 source 是一个 stream 对象,则这些数据也将被复制,并且 target 将被转换为流对象。

  • 典型用例是替换或删除不使用删除注释的现有图像。示例脚本可以在这里看到。

extract_image(xref)

仅适用于 PDF:提取存储在文档中的图像的数据和元信息。输出可以直接用作图像文件存储,作为 PIL 的输入,Pixmap 创建等。该方法尽可能避免使用像素图,以便以其原始格式(例如作为 JPEG)呈现图像。

参数:

xref (int) - xref 图像对象的参考。如果不在 range(1, doc.xref_length()) 内,或者对象不是图像或其他错误发生,则返回None,不会引发异常。

返回类型:

dict

返回:

具有以下键的字典

  • ext (str) 图像类型(例如 ‘jpeg’),可用作图像文件扩展名

  • smask (int) xref 图像的一个蒙版(/SMask)图像或零

  • width (int) 图像宽度

  • height (int) 图像高度

  • colorspace (int) 图像的colorspace.n 数字。

  • cs-name (str) 图像的colorspace.name

  • xres (int) x 方向的分辨率。请参阅resolution

  • yres (int) y 方向的分辨率。请参阅resolution

  • image (bytes) 图像数据,可用作图像文件内容

>>> d = doc.extract_image(1373)
>>> d
{'ext': 'png', 'smask': 2934, 'width': 5, 'height': 629, 'colorspace': 3, 'xres': 96,
'yres': 96, 'cs-name': 'DeviceRGB',
'image': b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x05\ ...'}
>>> imgout = open(f"image.{d['ext']}", "wb")
>>> imgout.write(d["image"])
102
>>> imgout.close() 

注意

pix = pymupdf.Pixmap(doc, xref),然后是 pix.tobytes() 有功能重叠。主要区别在于 extract_image,(1) 不总是提供 PNG 图像格式,(2) 对于非 PNG 图像速度 非常 快,(3) 通常导致提取图像的磁盘存储要少得多,(4) 在错误情况下返回 None(不生成异常)。看看相同 PDF 中的以下示例图像。

  • xref 1268 是 PNG - 执行时间可比较,输出相同:

    In [23]: %timeit pix = pymupdf.Pixmap(doc, 1268);pix.tobytes()
    10.8 ms ± 52.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    In [24]: len(pix.tobytes())
    Out[24]: 21462
    
    In [25]: %timeit img = doc.extract_image(1268)
    10.8 ms ± 86 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
    In [26]: len(img["image"])
    Out[26]: 21462 
    
  • xref 1186 是 JPEG - Document.extract_image()快得多,且产生的输出 要小得多(2.48 MB vs. 0.35 MB):

    In [27]: %timeit pix = pymupdf.Pixmap(doc, 1186);pix.tobytes()
    341 ms ± 2.86 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
    In [28]: len(pix.tobytes())
    Out[28]: 2599433
    
    In [29]: %timeit img = doc.extract_image(1186)
    15.7 µs ± 116 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    In [30]: len(img["image"])
    Out[30]: 371177 
    
extract_font(xref, info_only=False, named=None)
  • 在 v1.19.4 中更改:如果named == True,则返回一个字典。

仅限 PDF:返回嵌入字体文件的数据和适当的文件扩展名。这可用于将字体存储为外部文件。该方法不会抛出异常(除非通过检查 PDF 和有效的xref)。

参数:

  • xref (int) – 要提取的字体的 PDF 对象号。

  • info_only (bool) – 仅返回字体信息,而不返回缓冲区。仅用于信息目的,避免分配大缓冲区。

  • named (bool) – 如果为真,则返回具有以下键的字典:'name'(字体基本名称),'ext'(字体文件扩展名),'type'(字体类型),'content'(字体文件内容)。

返回类型:

tuple,dict

返回值:

一个元组(basename,ext,type,content),其中ext是 3 字节的建议文件扩展名(str),basename是字体的名称(str),type是字体的类型(例如,“Type1”),而content是包含字体文件内容的字节对象(或b””)。有关可能的扩展值及其含义,请参阅字体文件扩展名。返回错误的详细信息:

  • ("", "", "", b"") – 无效的 xref 或 xref 不是(有效的)字体对象。

  • (basename,“n/a”,“Type1”,b“”)basename未嵌入,因此无法提取。例如,这适用于 PDF Base 14 字体和 Type 3 字体。

示例:

>>> # store font as an external file
>>> name, ext, _, content = doc.extract_font(4711)
>>> # assuming content is not None:
>>> ofile = open(name + "." + ext, "wb")
>>> ofile.write(content)
>>> ofile.close() 

警告:

从 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。

Discord logo

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。

Discord logo

标签:24,xref,PyMuPDF,文档,PDF,Document,page,页面
From: https://www.cnblogs.com/apachecn/p/18252557

相关文章

  • PyMuPDF-1-24-4-中文文档-二-
    PyMuPDF1.24.4中文文档(二)原文:https://pymupdf.readthedocs.io/en/latest/教程原文:pymupdf.readthedocs.io/en/latest/tutorial.html本教程将逐步展示您如何在Python中使用PyMuPDF和MuPDF。因为MuPDF不仅支持PDF,还支持XPS、OpenXPS、CBZ、CBR、FB2和EPUB格......
  • git学习笔记——202406171525
    想将本地仓库代码提交到远程仓库,应注意:如果在新建远程仓库时里面还新建了文件,在本地提交代码时会显示两个分支是冲突的,git认为是两个不相关的仓库代码,会拒绝上传。解决方法是gitpullremotemaster拉取远程代码到本地,然后再gitpushremote-umaster相关链接:https://www.cn......
  • 自动驾驶、AI、高端医疗……芯驿电子携 FPGA 创新成果亮相 2024 上海国际嵌入式展
      6月12日至14日,2024上海国际嵌入式展(embeddedworldChina)在上海世博展览馆正式举行。本届展会以“智慧赋能,科技全球”为主题,旨在打造嵌入式系统全产业链交流与合作平台。 作为中国嵌入式技术领域领先的FPGA方案商,芯驿电子科技(上海)有限公司携多款FPGA新品和行业方案......
  • 生成式 AI 服务应用之Langchain 和 DashScope Reranker 彻底改变您的文档检索过程(教程
    介绍在当今信息泛滥的时代,找到所需的确切文档似乎是一件不可能完成的事情。传统搜索引擎经常让您在无关内容中苦苦挣扎,浪费宝贵的时间。但不要担心,因为有一对强大的组合正在等待彻底改变您的搜索体验:Langchain和DashScopeReranker。推荐文章《如何使用CodeLlama......
  • Java速成笔记 2024.6.17版
    变量:可以变化的容器不同变量可以存储不同类型的值变量声明方法:变量类型变量名=初始值;E.G.inta=1;变量类型:整型:intlong浮点数:floatdouble布尔:boolean字符串:String字符:char变量命名注意事项:不能重名不能以数字开头常量:关键字:final语法:finalfl......
  • 国产最好用的EasyRecovery数据恢复软件2024中文电脑版下载
    EasyRecovery数据恢复软件,简直就是数据丢失者的救星!......
  • 软件工程项目开发文档资料(规格说明书、详细设计、测试计划、验收报告)
      前言:在软件开发过程中,文档资料是非常关键的一部分,它们帮助团队成员理解项目需求、设计、实施、测试、验收等各个环节,确保项目的顺利进行。以下是各个阶段的文档资料概述:软件项目管理部分文档清单: 工作安排任务书,可行性分析报告,立项申请审批表,产品需求规格说明书,需求调......
  • 山东大学2023-2024深度学习期末回忆及参考答案
    文章目录名词解释(3*8=24分)分布式表示超参数共现矩阵截断BPTTattention机制梯度确认疑惑度还有一个忘了简答(6题)1、说出训练数据测试数据验证数据的作用,为什么要分训练数据和测试数据?训练数据、测试数据、验证数据的作用为什么要分训练数据和测试数据2、为什么激活函数要......
  • 2024 第六届机器人与计算机视觉国际会议(ICRCV 2024)即将召开!
    2024第六届机器人与计算机视觉国际会议(ICRCV2024)将于2024年9月20日-22日在中国·无锡召开,由IEEE,IEEERAS,南京理工大学联合主办。会议旨在为行业内专家和学者分享技术进步和业务经验,聚焦机器人与计算机视觉的前沿研究,提供一个合作交流的平台。会议官网:ICRCV2024|......
  • 2024.06 别急记录
    1.Ynoi2009-rprsvq首先有方差\(=\dfrac{n-1}{n^2}\suma_i^2-\dfrac2{n^2}\suma_ia_j\)。还有结论:对于大小为\(n\)的集合\(S\),所有\(\dbinomnt\)个大小为\(t\)的子集中,含有给定大小为\(k\)的子集的集合个数为\(\dbinom{n-k}{t-k}\)。那么一个序列\(a_1,...,a......