PyMuPDF 1.24.4 中文文档(二)(1)

简介: PyMuPDF 1.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 格式,所以 PyMuPDF 也支持[1]。然而,为简洁起见,我们只讨论 PDF 文件。确实只支持 PDF 文件的地方会明确说明。

导入绑定

MuPDF 的 Python 绑定通过此导入语句提供。我们还展示了如何检查您的版本:

>>> import pymupdf
>>> print(pymupdf.__doc__)
PyMuPDF 1.16.0: Python bindings for the MuPDF 1.16.0 library.
Version date: 2019-07-28 07:30:14.
Built for Python 3.7 on win32 (64-bit). 

关于名称fitz的说明

旧版本的 PyMuPDF 将其Python导入名称设置为fitz。更新版本改用pymupdf,并提供fitz作为备用选项,以便旧代码仍可使用。

名称fitz的原因是一个历史的奇特现象:

MuPDF 的原始渲染库称为Libart

“在 Artifex Software 收购 MuPDF 项目后,开发重点转向编写名为‘Fitz’的新现代图形库。Fitz 最初是一个旨在取代老旧 Ghostscript 图形库的研发项目,但最终成为 MuPDF 的渲染引擎。”(摘自Wikipedia

注意

仍然可以将 PyMuPDF 导入为fitz,但是 PyMuPDF 不能与 同一 Python 环境中命名为fitz的其他软件包共存。

打开文档

要访问支持的文档,必须使用以下语句打开:

doc = pymupdf.open(filename)  # or pymupdf.Document(filename) 

创建了文档对象docfilename必须是指定现有文件名称的 Python 字符串(或pathlib.Path)。

也可以从内存数据打开文档,或创建一个新的空 PDF。详见文档。还可以将文档用作上下文管理器

文档包含许多属性和函数。其中包括元信息(如“作者”或“主题”)、总页数、大纲和加密信息。

一些文档的方法和属性

方法 / 属性 描述
Document.page_count 页数 (int)
Document.metadata 元数据 (dict)
Document.get_toc() 获取目录 (list)
Document.load_page() 读取一个页面

访问元数据

PyMuPDF 完全支持标准元数据。Document.metadata 是一个 Python 字典,包含以下键。虽然并非所有条目始终包含数据,但它适用于所有文档类型。有关其含义和格式的详细信息,请参阅相应的手册,例如 Adobe PDF 参考手册。还可以在文档章节中找到更多信息。元数据字段是字符串,如果未另行指定,则为None。还要注意,即使它们不是None,并非所有字段始终包含有意义的数据。

Key Value
producer 生产者(制作软件)
format 格式: ‘PDF-1.4’, ‘EPUB’等
encryption 加密使用的加密方法
author 作者
modDate 上次修改日期
keywords 关键词
title 标题
creationDate 创建日期
creator 创建应用程序
subject 主题

注意

除了这些标准元数据外,PDF 文档从 PDF 版本 1.4 开始可能还包含所谓的*“元数据流”*(参见stream)。这些流中的信息以 XML 编码。PyMuPDF 故意不包含 XML 组件用于此目的(PyMuPDF Xml 类是一个帮助类,旨在访问 Story 对象的 DOM 内容),因此我们不直接支持访问其中包含的信息。但是,您可以将整个流提取出来,使用像lxml这样的包进行检查或修改,然后将结果存回 PDF 中。如果您希望,您也可以完全删除这些数据。

注意

存储库中有两个实用脚本,用于从 PDF 导入(仅限 PDF)元数据 和导出元数据,以及从 CSV 文件中导入(仅限 PDF)大纲 和导出大纲。

使用大纲

获取文档所有大纲(也称为“书签”)的最简单方法是加载其目录

toc = doc.get_toc() 

这将返回一个 Python 列表的列表 [[lvl, title, page, …], …],其看起来非常像书籍中常见的传统目录。

lvl是条目的层次级别(从 1 开始),title是条目的标题,page是页面编号(从 1 开始)。其他参数描述书签目标的详细信息。

注意

存储库中有两个实用脚本,用于从 PDF 导入(仅限 PDF)目录 和导出目录,以及从 CSV 文件中导入(仅限 PDF)目录 和导出目录。

使用页面

页面处理是 MuPDF 功能的核心。

  • 可以将页面渲染成位图或矢量(SVG)图像,可选择缩放、旋转、移位或剪切它。
  • 可以以多种格式提取页面的文本和图像,并搜索文本字符串。
  • 对于 PDF 文档,还有许多其他方法可用于向页面添加文本或图像。

首先,必须创建一个页面。这是文档的一个方法:

page = doc.load_page(pno)  # loads page number 'pno' of the document (0-based)
page = doc[pno]  # the short form 

此处可以是任意整数 -∞ < pno < page_count。负数从末尾开始计数,因此*doc[-1]*就像 Python 序列中的最后一页。

一些更高级的方法是使用文档作为其页的迭代器:

for page in doc:
    # do something with 'page'
# ... or read backwards
for page in reversed(doc):
    # do something with 'page'
# ... or even use 'slicing'
for page in doc.pages(start, stop, step):
    # do something with 'page' 

一旦有了页面,这是您通常会对其执行的操作:

检查页面的链接、注释或表单字段

当使用某些查看器软件显示文档时,链接显示为“热区”。如果光标显示手符号,点击时通常会转到编码在该热区中的目标。以下是获取所有链接的方法:

# get all links on a page
links = page.get_links() 

links是一个 Python 字典列表。详情请参见Page.get_links()

你还可以使用一个迭代器,每次发出一个链接:

for link in page.links():
    # do something with 'link' 

如果处理 PDF 文档页面,可能还存在注释(Annot)或表单字段(Widget),它们各自有自己的迭代器:

for annot in page.annots():
    # do something with 'annot'
for field in page.widgets():
    # do something with 'field' 

渲染页面

此示例创建了页面内容的位图图像:

pix = page.get_pixmap() 

pix是一个 Pixmap 对象,它(在本例中)包含页面的RGB图像,可用于多种目的。方法Page.get_pixmap()提供了许多控制图像的变体:分辨率/DPI、色彩空间(例如生成灰度图像或带有减色方案的图像)、透明度、旋转、镜像、移位、剪切等。例如:要创建RGBA图像(即包含 alpha 通道的图像),请指定pix = page.get_pixmap(alpha=True)

一个 Pixmap 包含许多以下引用的方法和属性。其中包括像素的整数宽度高度(每个像素)和stride(一行水平图像的字节数)。属性samples表示表示图像数据的字节的矩形区域(Python 的bytes对象)。

注意

还可以通过使用Page.get_svg_image()创建页面的矢量图像。有关详细信息,请参阅此矢量图像支持页面

将页面图像保存到文件中

我们可以简单地将图像存储在 PNG 文件中:

pix.save("page-%i.png" % page.number) 

在 GUI 中显示图像

我们还可以将其用于 GUI 对话管理器。Pixmap.samples表示所有像素的字节区域,作为 Python 字节对象。以下是一些示例,在examples目录中可以找到更多。

wxPython

请查阅他们的文档以调整 RGB(A)像素图像,并且可能适用于您的 wxPython 版本的具体细节:

if pix.alpha:
    bitmap = wx.Bitmap.FromBufferRGBA(pix.width, pix.height, pix.samples)
else:
    bitmap = wx.Bitmap.FromBuffer(pix.width, pix.height, pix.samples) 
Tkinter

请还要参阅Pillow 文档的第 3.19 节:

from PIL import Image, ImageTk
# set the mode depending on alpha
mode = "RGBA" if pix.alpha else "RGB"
img = Image.frombytes(mode, [pix.width, pix.height], pix.samples)
tkimg = ImageTk.PhotoImage(img) 

以下避免使用 Pillow:

# remove alpha if present
pix1 = pymupdf.Pixmap(pix, 0) if pix.alpha else pix  # PPM does not support transparency
imgdata = pix1.tobytes("ppm")  # extremely fast!
tkimg = tkinter.PhotoImage(data = imgdata) 

如果您正在寻找一个完整的 Tkinter 脚本来浏览任何支持的文档,这里就是!它还可以放大页面,并且可以在 Python 2 或 3 下运行。它需要非常方便的PySimpleGUI纯 Python 包。

PyQt4, PyQt5, PySide

请还要参阅Pillow 文档的第 3.16 节:

from PIL import Image, ImageQt
# set the mode depending on alpha
mode = "RGBA" if pix.alpha else "RGB"
img = Image.frombytes(mode, [pix.width, pix.height], pix.samples)
qtimg = ImageQt.ImageQt(img) 

同样地,您也可以在不使用 Pillow 的情况下搞定。Qt 的QImage幸运地支持本机 Python 指针,因此以下是创建 Qt 图像的推荐方法:

from PyQt5.QtGui import QImage
# set the correct QImage format depending on alpha
fmt = QImage.Format_RGBA8888 if pix.alpha else QImage.Format_RGB888
qtimg = QImage(pix.samples_ptr, pix.width, pix.height, fmt) 

提取文本和图片

我们还可以以多种不同的形式和详细级别提取页面的所有文本、图片和其他信息:

text = page.get_text(opt) 

使用以下字符串之一作为opt以获取不同格式 [2]

  • “text”: (默认)带有换行符的纯文本。无格式化,无文本位置细节,无图片。
  • “blocks”: 生成文本块的列表(=段落)。
  • “words”: 生成单词列表(不包含空格的字符串)。
  • “html”: 创建页面的完整视觉版本,包括所有图片。这可以在您的互联网浏览器中显示。
  • “dict” / “json”: 与 HTML 相同的信息级别,但提供为 Python 字典或 JSON 字符串。详见TextPage.extractDICT()以了解其结构的详细信息。
  • “rawdict” / “rawjson”: 是**“dict”** / **“json”**的超集。此外,它还提供像 XML 一样的字符详细信息。详见TextPage.extractRAWDICT()以了解其结构的详细信息。
  • “xhtml”: 文本信息级别与 TEXT 版本相同,但包含图片。也可以在互联网浏览器中显示。
  • “xml”: 不包含图片,但包含完整的位置和字体信息,直到每个单独的文本字符。使用 XML 模块进行解释。

为了让您对这些替代方案的输出有所了解,我们进行了文本示例提取。请参见附录 2:嵌入文件考虑事项。

搜索文本

可以准确找出某个文本串在页面上的位置:

areas = page.search_for("mupdf") 

这会提供一个矩形列表(参见 Rect),每个矩形围绕一个字符串“mupdf”的出现(不区分大小写)。您可以使用此信息来突出显示这些区域(仅限 PDF)或创建文档的交叉引用。

请同时查看章节 Working together: DisplayList and TextPage 和演示程序 demo.py 以及 demo-lowlevel.py。它们包含有关如何更直接控制 TextPage、Device 和 DisplayList 类的详细信息,例如在性能考虑建议时。

Stories: 从 HTML 源生成 PDF

Story 类是 PyMuPDF 版本 1.21.0 的新功能。它表示对 MuPDF 的 “story” 接口的支持。

以下是来自 “MuPDF Explored” 一书的引用,作者是来自 Artifex 的 Robin Watts:


Stories 提供了一种为文档写入设备等设备易于布局的样式内容的方式。“Story” 的概念来自桌面发布,而桌面发布则是从报纸中得到的。如果您考虑传统报纸的布局,它将包含多个新闻文章(故事),这些文章可能跨多列,可能跨多页。

因此,MuPDF 使用 story 表示带有样式信息的文本流。story 的使用者可以提供一系列矩形,用来布置 story,并且可以将定位文本绘制到输出设备上。这保持了文本本身(story)与应该流入文本的区域(布局)的概念分离。


注意

Story 与互联网浏览器类似:它忠实地解析和呈现 HTML 超文本,还可以使用样式表(CSS)。但它的 输出是 PDF 而不是网页。

创建 Story 时,将考虑来自最多三种不同信息源的输入。所有这些项目都是可选的。

  1. HTML 源代码,可以是 Python 字符串,也可以由脚本使用 Xml 类的方法创建。
  2. CSS(层叠样式表)源代码,提供为 Python 字符串。CSS 可用于提供样式信息(文本字体大小、颜色等),类似于为网页提供样式。显然,这个字符串也可以从文件中读取。
  3. 当 DOM 引用图像或使用文本字体(除了标准的 PDF Base 14 Fonts、CJK 字体和 PyMuPDF 二进制中生成的 NOTO 字体)时,必须使用 Archive。

API 允许完全从头创建 DOM,包括所需的样式信息。它还可以用于修改或扩展提供的 HTML:文本可以被删除或替换,或者其样式可以更改。文本(例如从数据库提取的文本)也可以添加并填充类似模板的 HTML 文档。

不需要提供语法完整的 HTML 文档:像Hello这样的片段是完全被接受的,而且许多/大多数语法错误都会被自动纠正。

HTML 被视为完整后,可以用于创建 PDF 文档。这通过新的 DocumentWriter 类完成。程序员调用其方法创建一个新的空白页,并传递矩形到 Story 来填充它们。

Story 反过来会返回完成代码,指示是否还有更多内容等待写入。内容的哪部分将会在哪个矩形或哪个页面上被自动确定由 Story 自身决定 - 除了提供矩形以外,它不能被影响。

请查看 Stories recipes 以获取一些典型用例。

PDF 维护

PDF 是唯一可以使用 PyMuPDF 进行修改的文档类型。其他文件类型是只读的。

但是,您可以将任何文档(包括图像)转换为 PDF,然后应用所有 PyMuPDF 功能到转换结果。在这里了解更多Document.convert_to_pdf(),也可以查看演示脚本pdf-converter.py,它可以将任何受支持的文档转换为 PDF。

Document.save()总是将 PDF 以其当前(可能已修改)状态存储到磁盘上。

通常可以选择是保存到新文件,还是将修改附加到现有文件上(“增量保存”),这通常会快得多。

以下描述了您可以操纵 PDF 文档的方法。这个描述并不完整:更多内容可以在后续章节中找到。

修改、创建、重新排列和删除页面

有几种方法可以操纵所谓的页面树(描述所有页面的结构):

Document.delete_page()Document.delete_pages()删除页面。

Document.copy_page()Document.fullcopy_page()Document.move_page()复制或移动页面到同一文档中的其他位置。

Document.select()将 PDF 缩小到所选页面。参数是要保留的页面编号序列[3]。这些整数必须都在0 <= i < page_count范围内。执行时,不在列表中的所有页面将被删除。剩余页面将按照您指定的顺序出现,并且出现多次。

因此,您可以轻松地创建新的 PDF 文件。

  • 第一页或最后十页,
  • 仅奇数页或偶数页(用于双面打印),
  • 包含或不包含给定文本的页面,
  • 反转页面顺序,…

…您可以想到的任何内容。

保存的新文档将包含仍然有效的链接、注释和书签(即所选页面或某些外部资源)。

Document.insert_page()Document.new_page()插入新页面。

页面本身还可以通过一系列方法进行修改(例如页面旋转、注释和链接维护、文本和图像插入)。

合并和拆分 PDF 文档

方法Document.insert_pdf()在不同的 PDF 文档之间复制页面。这里是一个简单的连接器示例(doc1doc2是打开的 PDF):

# append complete doc2 to the end of doc1
doc1.insert_pdf(doc2) 

这里有一个分割 doc1 的片段。它创建一个包含其前 10 页和最后 10 页的新文档:

doc2 = pymupdf.open()                 # new empty PDF
doc2.insert_pdf(doc1, to_page = 9)  # first 10 pages
doc2.insert_pdf(doc1, from_page = len(doc1) - 10) # last 10 pages
doc2.save("first-and-last-10.pdf") 

更多信息可以在文档章节中找到。还可以查看PDFjoiner.py

嵌入数据

PDF 可以用作任意数据(可执行文件、其他 PDF、文本或二进制文件等)的容器,类似于 ZIP 档案。

PyMuPDF 完全支持此功能,通过文档 embfile_* 方法和属性。有关详细信息,请参阅附录 3,查阅有关处理嵌入文件的 Wiki(链接:https://github.com/pymupdf/PyMuPDF/wiki/Dealing-with-Embedded-Files),或查看示例脚本embedded-copy.pyembedded-export.pyembedded-import.py,以及embedded-list.py

保存

如上所述,Document.save()将始终以其当前状态保存文档。

您可以通过指定选项incremental=True将更改写回到原始 PDF。这个过程(通常)非常快,因为更改会附加到原始文件而不是完全重写它。

Document.save()选项对应于 MuPDF 命令行实用程序mutool clean的选项,详见以下表格。

保存选项 mutool 效果
garbage=1 g 垃圾回收未使用的对象
garbage=2 gg 除了 1 之外,压缩xref表格
garbage=3 ggg 除了 2 之外,合并重复对象
garbage=4 gggg 除了 3 之外,合并重复的流内容
clean=True cs 清理和消毒内容流
deflate=True z 压缩未压缩的流
deflate_images=True i 压缩图像流
deflate_fonts=True f 压缩字体文件流
ascii=True a 将二进制数据转换为 ASCII 格式
linear=True l 创建线性化版本
expand=True d 解压所有流

注意

如需了解对象、流、xref等术语的解释,请参阅术语表章节。

例如,mutool clean -ggggz file.pdf 可以获得出色的压缩结果。它对应于 doc.save(filename, garbage=4, deflate=True)

结尾

在您的程序继续运行的同时,通常希望“关闭”文档以放弃对底层文件的控制。

可以通过Document.close()方法实现。除了关闭底层文件外,还将释放与文档相关的缓冲区域。

进一步阅读

还请查看 PyMuPDF 的Wiki页面。特别是侧边栏下标题为“Recipes”的页面,覆盖了超过 15 个以“How-To”风格编写的主题。

本文档还包含一个常见问题解答。此章节与上述配方密切相关,将随时间推移增加更多内容。


脚注

对本页面有任何反馈吗?


本软件按原样提供,不附带任何明示或暗示的担保。此软件根据许可证分发,未经明确授权不得复制、修改或分发。有关详细信息,请参阅artifex.com,或联系 Artifex Software Inc., 39 Mesa Street, Suite 108A, San Francisco CA 94129, United States。

本文档涵盖所有版本直至 1.24.4。

导入绑定

通过此导入语句提供了 MuPDF 的 Python 绑定。我们还展示了如何检查您的版本:

>>> import pymupdf
>>> print(pymupdf.__doc__)
PyMuPDF 1.16.0: Python bindings for the MuPDF 1.16.0 library.
Version date: 2019-07-28 07:30:14.
Built for Python 3.7 on win32 (64-bit). 

名称fitz的说明

旧版的 PyMuPDF 将其Python导入名称设为fitz。更新版本使用pymupdf,并提供fitz作为后备,以确保旧代码仍然可以运行。

名称fitz的由来是一个历史的奇闻:

MuPDF 的原始渲染库称为 Libart

“在 Artifex 软件收购 MuPDF 项目后,开发重点转向编写一个名为“Fitz”的新型现代图形库。Fitz 最初旨在成为取代陈旧的 Ghostscript 图形库的研发项目,但最终成为了 MuPDF 的渲染引擎。”(摘自 Wikipedia)。

注意

尽管将 PyMuPDF 导入为 fitz 仍然有效,但 PyMuPDF 不能与 相同 Python 环境中的其他名为fitz的包共存。

关于名称 fitz 的说明

旧版本的 PyMuPDF 将其 Python 导入名称设为 fitz。更新版本改用 pymupdf,并提供 fitz 作为后备,以便旧代码仍然有效。

名称 fitz 的原因是一个历史奇观:

MuPDF 的原始渲染库称为 Libart

“在 Artifex 软件收购 MuPDF 项目后,开发重点转向编写一个名为“Fitz”的新型现代图形库。Fitz 最初旨在成为取代陈旧的 Ghostscript 图形库的研发项目,但最终成为了 MuPDF 的渲染引擎。”(摘自 Wikipedia)。

注意

尽管将 PyMuPDF 导入为 fitz 仍然有效,但 PyMuPDF 不能与 相同 Python 环境中的其他名为fitz的包共存。

打开文档

要访问 支持的文档,必须使用以下语句打开它:

doc = pymupdf.open(filename)  # or pymupdf.Document(filename) 

这会创建 Document 对象 docfilename 必须是指定现有文件名的 Python 字符串(或 pathlib.Path)。

还可以从内存数据打开文档,或创建一个新的空 PDF。详见 Document。您还可以将 Document 用作 上下文管理器

文档包含许多属性和函数。其中包括元信息(如“作者”或“主题”)、总页数、大纲和加密信息。

一些 Document 方法和属性

方法 / 属性 描述
Document.page_count 页数(整数
Document.metadata 元数据(字典
Document.get_toc() 获取目录(列表
Document.load_page() 读取 Page

访问元数据

PyMuPDF 完全支持标准元数据。Document.metadata是一个 Python 字典,具有以下键。它适用于所有文档类型,尽管不是所有条目始终包含数据。有关它们的含义和格式的详细信息,请参阅相应的手册,例如 PDF 的 Adobe PDF 参考。更多信息也可以在章节文档中找到。元数据字段是字符串,如果没有其他指示,则为None。还要注意,即使它们不是None,并非所有字段始终包含有意义的数据。

生成者 生成软件
格式 格式:“PDF-1.4”,“EPUB”等
加密 如果有,则使用的加密方法
作者 作者
修改日期 上次修改日期
关键词 关键词
标题 标题
创建日期 创建日期
创建者 创建应用程序
主题 主题

注意

除了这些标准元数据外,从 PDF 版本 1.4 开始的PDF 文档还可能包含所谓的*“元数据流”*(另请参见stream)。此类流中的信息以 XML 编码。PyMuPDF 故意不包含用于此目的的 XML 组件(PyMuPDF Xml 类是一个辅助类,用于访问 Story 对象的 DOM 内容),因此我们不直接支持访问其中包含的信息。但您可以将整个流提取出来,使用类似lxml的软件包检查或修改它,然后将结果存回 PDF。如果您愿意,还可以完全删除这些数据。

注意

存储库中有两个实用程序脚本,用于从元数据导入(仅限 PDF)或从 CSV 文件中导出元数据

处理大纲

获取文档的所有大纲(也称为“书签”)的最简单方法是加载其目录

toc = doc.get_toc() 

这将返回一个 Python 列表的列表*[[lvl, title, page, …], …]*,看起来很像书籍中的传统目录。

lvl是条目的层次级别(从 1 开始),title是条目的标题,page是页码(从 1 开始!)。其他参数描述了书签目标的详细信息。

注意

存储库中有两个实用程序脚本,用于从目录导入(仅限 PDF)或从 CSV 文件中导出目录

处理页面

页面处理是 MuPDF 功能的核心。

  • 您可以将页面呈现为光栅或矢量(SVG)图像,可选择缩放、旋转、移位或剪切它。
  • 您可以以许多格式提取页面的文本和图像并搜索文本字符串。
  • 对于 PDF 文档,有更多的方法可用于向页面添加文本或图像。

首先,必须创建一个页面。这是文档的一种方法:

page = doc.load_page(pno)  # loads page number 'pno' of the document (0-based)
page = doc[pno]  # the short form 

在此处可能存在任何整数-∞ < pno < page_count。负数从末尾开始计数,因此*doc[-1]*是最后一页,就像 Python 序列一样。

更高级的方式之一是使用文档作为其页面的迭代器:

for page in doc:
    # do something with 'page'
# ... or read backwards
for page in reversed(doc):
    # do something with 'page'
# ... or even use 'slicing'
for page in doc.pages(start, stop, step):
    # do something with 'page' 

一旦您有了页面,以下是您通常会执行的操作:

检查页面的链接、注释或表单字段

当使用某些查看器软件显示文档时,链接显示为“热区”。如果光标显示手型符号时单击,通常会跳转到该热区编码的目标。以下是获取所有链接的方法:

# get all links on a page
links = page.get_links() 

links是一个字典的 Python 列表。有关详细信息,请参阅Page.get_links()

您还可以使用逐个链接发出一个链接的迭代器:

for link in page.links():
    # do something with 'link' 

如果处理 PDF 文档页面,还可能存在注释(Annot)或表单字段(Widget),它们各自有自己的迭代器:

for annot in page.annots():
    # do something with 'annot'
for field in page.widgets():
    # do something with 'field' 

渲染页面

此示例创建了一个页面内容的光栅图像:

pix = page.get_pixmap() 

pix是一个 PixMap 对象,其中(在本例中)包含页面的RGB图像,可用于许多目的。方法Page.get_pixmap()提供了许多变体来控制图像:分辨率 / DPI、颜色空间(例如生成灰度图像或带有减法色彩方案的图像)、透明度、旋转、镜像、移位、剪切等。例如:要创建一个RGBA图像(即包含 alpha 通道的图像),请指定pix = page.get_pixmap(alpha=True)

位图包含下面引用的许多方法和属性。其中包括整数宽度高度(每个像素)和步幅(一行的字节数)。属性样本表示表示图像数据的字节的矩形区域(Python bytes对象)。

注意

您还可以通过使用Page.get_svg_image()创建一个页面的矢量图像。有关详细信息,请参阅此矢量图像支持页面

保存页面图像到文件

我们可以简单地将图像存储在 PNG 文件中:

pix.save("page-%i.png" % page.number) 

在 GUI 中显示图像

我们还可以在 GUI 对话管理器中使用它。Pixmap.samples 表示所有像素的字节区域,作为 Python 字节对象。这里有一些例子,在 examples 目录中找到更多。

wxPython

请查阅他们的文档,以调整 RGB(A) 图像和,可能,适用于你的 wxPython 版本的特定事项:

if pix.alpha:
    bitmap = wx.Bitmap.FromBufferRGBA(pix.width, pix.height, pix.samples)
else:
    bitmap = wx.Bitmap.FromBuffer(pix.width, pix.height, pix.samples)
Tkinter

也请查看 Pillow 文档 的第 3.19 节:

from PIL import Image, ImageTk
# set the mode depending on alpha
mode = "RGBA" if pix.alpha else "RGB"
img = Image.frombytes(mode, [pix.width, pix.height], pix.samples)
tkimg = ImageTk.PhotoImage(img) 

以下避免使用 Pillow:

# remove alpha if present
pix1 = pymupdf.Pixmap(pix, 0) if pix.alpha else pix  # PPM does not support transparency
imgdata = pix1.tobytes("ppm")  # extremely fast!
tkimg = tkinter.PhotoImage(data = imgdata) 

如果你正在寻找一个完整的 Tkinter 脚本来翻页浏览任何支持的文档,这里有!它还可以缩放页面,并且在 Python 2 或 3 下运行。它需要极其方便的 PySimpleGUI 纯 Python 包。

PyQt4、PyQt5、PySide

也请查看 Pillow 文档 的第 3.16 节:

from PIL import Image, ImageQt
# set the mode depending on alpha
mode = "RGBA" if pix.alpha else "RGB"
img = Image.frombytes(mode, [pix.width, pix.height], pix.samples)
qtimg = ImageQt.ImageQt(img) 

同样,你也可以不使用 Pillow。Qt 的 QImage 幸运地支持本机 Python 指针,因此以下是创建 Qt 图像的推荐方式:

from PyQt5.QtGui import QImage
# set the correct QImage format depending on alpha
fmt = QImage.Format_RGBA8888 if pix.alpha else QImage.Format_RGB888
qtimg = QImage(pix.samples_ptr, pix.width, pix.height, fmt) 

提取文本和图像

我们还可以以多种不同形式和详细程度提取页面的所有文本、图像和其他信息:

text = page.get_text(opt) 

使用以下字符串之一作为 opt 可以获取不同的格式 [2]

  • “text”:(默认)带有换行符的纯文本。无格式,无文本位置细节,无图像。
  • “blocks”:生成文本块列表(= 段落)。
  • “words”:生成一个单词列表(不包含空格的字符串)。
  • “html”:创建包括任何图像在内的页面的完整视觉版本。这可以在你的互联网浏览器中显示。
  • “dict” / “json”:与 HTML 相同的信息级别,但提供为 Python 字典或 JSON 字符串。请查看 TextPage.extractDICT() 以了解其结构的详细信息。
  • “rawdict” / “rawjson”:“dict” / “json” 的超集。它还提供了像 XML 那样的字符详细信息。请查看 TextPage.extractRAWDICT() 以了解其结构的详细信息。
  • “xhtml”:文本信息级别与 TEXT 版本相同,但包括图像。也可以通过互联网浏览器显示。
  • “xml”:不包含图像,但包含完整的位置和字体信息,直到每个单个文本字符。使用 XML 模块进行解释。

为了让你对这些替代方案的输出有所了解,我们进行了文本示例提取。请查看 Appendix 2: 嵌入式文件的注意事项。

搜索文本

你可以精确地知道页面上某个文本字符串出现的位置:

areas = page.search_for("mupdf") 

这将提供一个矩形列表(参见 Rect),每个矩形围绕字符串“mupdf”的一个出现(不区分大小写)。您可以使用此信息来高亮显示这些区域(仅适用于 PDF)或创建文档的交叉引用。

请查看第 Working together: DisplayList and TextPage 章节和演示程序demo.pydemo-lowlevel.py。它们包含有关 TextPage、Device 和 DisplayList 类如何用于更直接的控制,例如在性能考虑建议时。

检查页面的链接、注释或表单字段

当文档使用某些查看器软件显示时,链接显示为“热区”。如果光标显示手形符号,单击时通常会跳转到编码在该热区中的目标。以下是如何获取所有链接的方法:

# get all links on a page
links = page.get_links() 

links 是一个 Python 字典列表。详情请参阅Page.get_links()

您还可以使用一个迭代器逐个发出一个链接:

for link in page.links():
    # do something with 'link' 

如果处理 PDF 文档页面,则可能还存在注释(Annot)或表单字段(Widget),每个都有自己的迭代器:

for annot in page.annots():
    # do something with 'annot'
for field in page.widgets():
    # do something with 'field' 

渲染页面

此示例创建页面内容的光栅图像:

pix = page.get_pixmap() 

pix 是一个 Pixmap 对象,这里包含了RGB格式的页面图像,可用于多种用途。方法Page.get_pixmap()提供了许多变体,用于控制图像:分辨率/DPI、色彩空间(例如生成灰度图像或使用减法色彩方案的图像)、透明度、旋转、镜像、平移、剪切等等。例如:要创建RGBA图像(即包含 alpha 通道),请指定pix = page.get_pixmap(alpha=True)

一个 Pixmap 包含许多下面引用的方法和属性。其中包括整数widthheight(每个像素)和stride(一条水平图像线的字节数)。属性samples表示代表图像数据的字节的矩形区域(Python 的bytes对象)。

注意

你还可以通过使用Page.get_svg_image()创建页面的矢量图像。请参阅此Vector Image Support page获取详情。

将页面图像保存在文件中

我们可以简单地将图像存储在 PNG 文件中:

pix.save("page-%i.png" % page.number) 

在 GUI 中显示图像

我们还可以在 GUI 对话框管理器中使用它。Pixmap.samples表示所有像素的字节区域作为 Python 字节对象。这里有一些例子,在examples目录中找到更多。

wxPython

请参阅他们的文档,调整 RGB(A)像素图和可能的 wxPython 版本的特定内容:

if pix.alpha:
    bitmap = wx.Bitmap.FromBufferRGBA(pix.width, pix.height, pix.samples)
else:
    bitmap = wx.Bitmap.FromBuffer(pix.width, pix.height, pix.samples) 
Tkinter

请参阅Pillow 文档的第 3.19 节:

from PIL import Image, ImageTk
# set the mode depending on alpha
mode = "RGBA" if pix.alpha else "RGB"
img = Image.frombytes(mode, [pix.width, pix.height], pix.samples)
tkimg = ImageTk.PhotoImage(img) 

以下内容避免使用 Pillow:

# remove alpha if present
pix1 = pymupdf.Pixmap(pix, 0) if pix.alpha else pix  # PPM does not support transparency
imgdata = pix1.tobytes("ppm")  # extremely fast!
tkimg = tkinter.PhotoImage(data = imgdata) 

如果你需要一个完整的 Tkinter 脚本来浏览任何支持的文档,这里有!它还可以缩放页面,并且可以在 Python 2 或 3 下运行。它需要非常方便的PySimpleGUI纯 Python 包。

PyQt4, PyQt5, PySide

请参阅Pillow 文档的第 3.16 节:

from PIL import Image, ImageQt
# set the mode depending on alpha
mode = "RGBA" if pix.alpha else "RGB"
img = Image.frombytes(mode, [pix.width, pix.height], pix.samples)
qtimg = ImageQt.ImageQt(img) 

同样,你也可以不使用 Pillow。Qt 的QImage幸运地支持本地 Python 指针,因此以下是创建 Qt 图像的推荐方式:

from PyQt5.QtGui import QImage
# set the correct QImage format depending on alpha
fmt = QImage.Format_RGBA8888 if pix.alpha else QImage.Format_RGB888
qtimg = QImage(pix.samples_ptr, pix.width, pix.height, fmt) 
wxPython

请参阅他们的文档,调整 RGB(A)像素图和可能的 wxPython 版本的特定内容:

if pix.alpha:
    bitmap = wx.Bitmap.FromBufferRGBA(pix.width, pix.height, pix.samples)
else:
    bitmap = wx.Bitmap.FromBuffer(pix.width, pix.height, pix.samples) 
Tkinter

请参阅Pillow 文档的第 3.19 节:

from PIL import Image, ImageTk
# set the mode depending on alpha
mode = "RGBA" if pix.alpha else "RGB"
img = Image.frombytes(mode, [pix.width, pix.height], pix.samples)
tkimg = ImageTk.PhotoImage(img) 

以下内容避免使用 Pillow:

# remove alpha if present
pix1 = pymupdf.Pixmap(pix, 0) if pix.alpha else pix  # PPM does not support transparency
imgdata = pix1.tobytes("ppm")  # extremely fast!
tkimg = tkinter.PhotoImage(data = imgdata) 

如果你需要一个完整的 Tkinter 脚本来浏览任何支持的文档,这里有!它还可以缩放页面,并且可以在 Python 2 或 3 下运行。它需要非常方便的PySimpleGUI纯 Python 包。

PyMuPDF 1.24.4 中文文档(二)(2)https://developer.aliyun.com/article/1559643

相关文章
|
8天前
|
存储 文字识别 自然语言处理
PyMuPDF 1.24.4 中文文档(五)(2)
PyMuPDF 1.24.4 中文文档(五)
21 3
|
8天前
|
存储 XML 编解码
PyMuPDF 1.24.4 中文文档(三)(2)
PyMuPDF 1.24.4 中文文档(三)
16 0
PyMuPDF 1.24.4 中文文档(三)(2)
|
8天前
|
XML JavaScript 前端开发
PyMuPDF 1.24.4 中文文档(十)(1)
PyMuPDF 1.24.4 中文文档(十)
10 0
|
8天前
|
存储 Python
PyMuPDF 1.24.4 中文文档(四)(4)
PyMuPDF 1.24.4 中文文档(四)
11 0
|
8天前
|
安全 API 数据安全/隐私保护
PyMuPDF 1.24.4 中文文档(一)(5)
PyMuPDF 1.24.4 中文文档(一)
13 3
PyMuPDF 1.24.4 中文文档(一)(5)
|
8天前
|
文字识别 API 数据安全/隐私保护
PyMuPDF 1.24.4 中文文档(一)(4)
PyMuPDF 1.24.4 中文文档(一)
17 3
|
8天前
|
安全 API 数据安全/隐私保护
PyMuPDF 1.24.4 中文文档(一)(3)
PyMuPDF 1.24.4 中文文档(一)
15 2
|
8天前
|
XML 编解码 文字识别
PyMuPDF 1.24.4 中文文档(八)(4)
PyMuPDF 1.24.4 中文文档(八)
13 1
|
8天前
|
存储 机器学习/深度学习 XML
PyMuPDF 1.24.4 中文文档(二)(3)
PyMuPDF 1.24.4 中文文档(二)
16 0
PyMuPDF 1.24.4 中文文档(二)(3)
|
8天前
|
存储 资源调度 JavaScript
PyMuPDF 1.24.4 中文文档(八)(1)
PyMuPDF 1.24.4 中文文档(八)
20 0
PyMuPDF 1.24.4 中文文档(八)(1)