文本页面#

该类表示在文档页面上显示的文本和图像。所有 MuPDF 文档类型 都受到支持。

创建文本页面的常用方法是 DisplayList.get_textpage()Page.get_textpage()。由于这个类中的方法数量有限,因此在 Page 中存在更方便使用的封装。此表格的最后一列显示了这些对应的 Page 方法。

有关此类的描述,请参见附录2。

None None None None None

方法

描述

页面获取文本或搜索方法

extractText()

提取纯文本

“text”

extractTEXT()

前一个的同义词

“文本”

extractBLOCKS()

以块为单位分组的纯文本

“blocks”

extractWORDS()

所有单词及其边界框

“words”

extractHTML()

页面内容以HTML格式显示

“html”

extractXHTML()

页面内容以XHTML格式

“xhtml”

extractXML()

以XML格式的页面文本

“xml”

extractDICT()

dict 格式的页面内容

“dict”

extractJSON()

以 JSON 格式显示的页面内容

“json”

extractRAWDICT()

dict 格式的页面内容

“rawdict”

extractRAWJSON()

以JSON格式呈现的页面内容

“rawjson”

search()

在页面中搜索字符串

Page.search_for()

类 API

class TextPage#
extractText(sort=False)#
extractTEXT(sort=False)#

返回页面完整文本的字符串。文本为UTF-8 Unicode,并且与文档创建时指定的顺序相同。

None
Parameters:

sort (bool) – (新功能在 v1.19.1)按垂直,然后按水平坐标排序输出。在许多情况下,这应该足以生成“自然”的阅读顺序。

None
Return type:

字符串

extractBLOCKS()#

文本页面内容作为按块分组的文本行列表。每个列表项看起来像这样:

None
(x0, y0, x1, y1, "lines in the block", block_no, block_type)

前四个条目是块的边界框坐标,block_type 为 1 表示图像块,0 表示文本。block_no 是块的序列号。多行文本通过换行符连接。

None

对于图像块,它的边界框和一条带有一些图像元信息的文本行被包含在内 - 不包括图像内容

None

这是一个高速方法,提供了足够的信息以按所需的阅读顺序输出纯文本。

None
Return type:

列表

extractWORDS(delimiters=None)#
  • 在v1.23.5中更改:添加了 delimiters 参数

文本页面内容以单词列表和边界框信息呈现。该列表中的一项看起来像这样:

None
(x0, y0, x1, y1, "word", block_no, line_no, word_no)
Parameters:

分隔符 (str) – (在v1.23.5中新增加) 使用这些字符作为附加单词分隔符。默认情况下,所有空格(包括不换行空格 0xA0)表示一个单词的开始和结束。现在你可以指定更多导致这种情况的字符。例如,默认将返回 "john.doe@outlook.com" 作为一个单词。如果你指定 delimiters="@.",那么将返回四个单词 "john""doe""outlook""com"。其他可能的用法包括忽略标点字符 delimiters=string.punctuation。这些“单词”字符串将不包含任何分隔字符。

None

这是一个高速方法,例如允许从给定区域中提取文本或恢复文本阅读顺序。

None
Return type:

列表

extractHTML()#

文本页面内容作为HTML格式的字符串。此版本包含完整的格式和定位信息。图像包含在内(编码为base64字符串)。您需要一个HTML包才能在Python中解释输出。您的互联网浏览器应该能够充分显示这些信息,但请参见控制HTML输出质量

None
Return type:

字符串

extractDICT(sort=False)#

文本页面内容作为一个Python字典。提供与HTML相同的信息细节。请参见下面的结构。

None
Parameters:

sort (bool) – (新功能在 v1.19.1)按垂直,然后按水平坐标排序输出。在许多情况下,这应该足以生成“自然”的阅读顺序。

None
Return type:

字典

extractJSON(sort=False)#

文本页面内容作为一个 JSON 字符串。由 json.dumps(TextPage.extractDICT()) 创建。包含此内容是为了向后兼容。您可能只会使用此方法将结果输出到某个文件。该方法检测二进制图像数据并将其转换为 base64 编码的字符串。

None
Parameters:

sort (bool) – (新功能在 v1.19.1)按垂直,然后按水平坐标排序输出。在许多情况下,这应该足以生成“自然”的阅读顺序。

None
Return type:

字符串

extractXHTML()#

以XHTML格式呈现的文本页面内容。文本信息详细内容可以与 extractTEXT() 相比,但也包含图像(base64编码)。此方法并不尝试重新创建原始视觉外观。

None
Return type:

字符串

extractXML()#

文本页面内容作为XML格式的字符串。这包含关于页面上每个字符的完整格式信息:字体、大小、行、段落、位置、颜色等。不包含图像。您需要一个XML包来在Python中解释输出。

None
Return type:

字符串

extractRAWDICT(sort=False)#

文本页面内容作为一个Python字典 - 在技术上类似于 extractDICT(),并且它将该信息作为一个子集(包括任何图片)包含在内。它提供了每个字符的额外细节,这使得在许多情况下使用XML变得过时。请参见下面的结构。

None
Parameters:

sort (bool) – (新功能在 v1.19.1)按垂直,然后按水平坐标排序输出。在许多情况下,这应该足以生成“自然”的阅读顺序。

None
Return type:

字典

extractRAWJSON(sort=False)#

将文本页面内容作为JSON字符串。由 json.dumps(TextPage.extractRAWDICT()) 创建。您可能只会将此方法用于将结果输出到某些文件。该方法检测二进制图像数据并将其转换为base64编码字符串。

None
Parameters:

sort (bool) – (新功能在 v1.19.1)按垂直,然后按水平坐标排序输出。在许多情况下,这应该足以生成“自然”的阅读顺序。

None
Return type:

字符串

search(needle, quads=False)#
  • 在 v1.18.2 中更改

    None

搜索 string 并返回找到的位置列表。

None
Parameters:
  • needle (str) – 要搜索的字符串。如果needle仅由ASCII字母组成,则大小写都将匹配——尚不支持“Ä”与“ä”等的比较。

    None
  • quads (bool) – 返回四边形而不是矩形。

    None
Return type:

列表

Returns:

一个RectQuad对象的列表,每个对象都围绕着找到的needle出现。由于搜索字符串可能包含空格,它的部分可能会出现在不同的行中。在这种情况下,将返回多个矩形(或四边形)。(在v1.18.2中更改) 该方法现在支持去连字符,因此它将找到例如“method”,即使它在两行之间被连字符拆分为“meth-”和“od”。返回的两个矩形将包含“meth”(没有连字符)和“od”。

None

注意

v1.18.2版本的变更概述:

None
  1. 参数 hit_max 已被移除:所有的点击都将始终返回。

    None
  2. 现在尊重TextPageRect参数:仅在该区域内的文本会被检查。只有完全包含在边界框内的字符才会被考虑。包装方法Page.search_for()相应地支持clip参数。

    None
  3. 带连字符的单词 现在被发现了。

    None
  4. 重叠的矩形现在会自动连接在同一行中。我们假设这种分隔是由多个标记内容组创建的伪影,这些内容组包含同一搜索针的部分。

示例四边形与矩形:当搜索针“pymupdf”时,相应的条目将是蓝色矩形,或者,如果指定了quads,则为四边形Quad(ul, ur, ll, lr)

_images/img-quads.jpg
rect#

与文本页面关联的矩形。这要么等于创建页面的矩形,要么等于 clip 参数的 Page.get_textpage() 和文本提取/搜索方法。

None

注意

文本搜索和大多数文本提取的输出 限制在这个矩形内。但是,(X)HTML和XML输出将始终提取整个页面。

字典输出的结构#

方法 TextPage.extractDICT()TextPage.extractJSON()TextPage.extractRAWDICT()TextPage.extractRAWJSON() 返回字典,包含页面的文本和图像内容。这四种方法的字典结构几乎相同。它们努力尽可能精确地映射文本页面的信息层级,包括块、行、跨度和字符,每个元素用自己的子字典表示:

  • 一个 页面 由一系列 块字典 组成。

  • A (text) consists of a list of 行字典.

  • A line consists of a list of span dictionaries.一行由一系列组成。

  • A span 要么由文本本身组成,要么对于 RAW 变体,由一组 字符字典 组成。

  • RAW 变体:一个 字符 是其来源、边界框和unicode的字典。

这里所有的 PyMuPDF 几何对象(点、矩形、矩阵)都通过它们的 “类似于” 格式表示:使用 rect_like 元组 来代替 Rect,等等。这样做的原因是为了性能和内存的考虑:

  • 这段代码是用C语言编写的,其中Python元组可以轻松生成。另一方面,几何对象仅在Python源代码中定义。将每个Python元组转换为其相应的几何对象将会增加显著的——且在很大程度上是不必要的——执行时间。

  • 一个4元组大约需要168字节,相应的Rect占用472字节——几乎是其大小的三倍。一个针对文本密集型页面的“dict”字典包含300多个bbox对象——因此作为4元组大约需要50 KB存储,而作为Rect对象则需要140 KB。然而,对于这样的页面,“rawdict”的输出将包含4到5千个bboxes,因此在这种情况下,我们讨论的是750 KB与2 MB。

请注意,只有 bboxes (= rect_like 4元组) 被返回,而 TextPage 实际上具有 完整的位置信息 – 采用 Quad 格式。这一决定的原因再次是出于内存考虑:一个 quad_like 需要 488 字节(是 rect_like 的三倍)。考虑到生成的 bboxes 的数量,返回 quad_like 信息将产生显著的影响。

在绝大多数情况下,我们处理的都是仅水平文本,在这种情况下,边界框提供了完全足够的信息。

此外,完整的四元信息不会丢失:可以根据需要通过使用以下列表中的适当函数来恢复行、跨度和字符:

如前所述,只有在文本不是水平书写时才需要使用这些函数 – line["dir"] != (1, 0) – 并且您需要四元组用于文本标记注释 (Page.add_highlight_annot() 和相关函数)。

_images/img-textpage.png

页面字典#

宽度

clip 矩形的宽度 (浮点数)

高度

clip 矩形的高度 (浮动)

区块

区块字典 的列表

块字典#

区块字典有两种不同的格式,一种用于图像块,另一种用于文本块

图像块:

类型

1 = 图片 (int)

边界框

页面上的图像边界框 (rect_like)

编号

区块数量 (int)

扩展名

图像类型 (str),作为文件扩展名,见下文

宽度

原始图像宽度 (int)

高度

原始图像高度 (int)

颜色空间

颜色空间组件数量 (int)

xres

x方向的分辨率 (int)

yres

y方向上的分辨率 (int)

bpc

每个组件的位数 (int)

变换

矩阵将图像框变换为边界框 (matrix_like)

大小

图像的大小(以字节为单位)(int

图片

图像内容 (bytes)

掩码

透明图像的图像掩码内容 (bytes)

“ext”键的可能值有“bmp”、“gif”、“jpeg”、“jpx”(JPEG 2000)、“jxr”(JPEG XR)、“png”、“pnm”和“tiff”。

注意

  1. 为页面上的所有每个图像出现生成一个图像块。因此,如果图像在不同的位置显示,则可能会有重复。

  2. 文本页面 和相应的方法 Page.get_text() 对于 所有文档类型均可用。只有对于 PDF 文档,方法 Document.get_page_images() / Page.get_images() 在图片列表方面提供了一些重叠的功能。但这两个列表 可能包含相同的项目,也可能不包含。任何差异最可能是由于以下原因之一造成的:

    • PDF 页面中的“内联”图像(见 Adobe PDF References 第 214 页)包含在文本页面中,但 不出现Page.get_images() 中。

    • 注释也可以包含图片 - 这些将不会出现Page.get_images()中。

    • 文本页面中的图像块为每个图像位置生成,无论是否存在重复。这与Page.get_images()形成对比,该方法每个参照名称只列出一次每个图像。

    • 页面的object定义中提到的图像将始终出现在Page.get_images() [1]中。但有可能页面的contents中没有“display”命令(错误地或故意地)。在这种情况下,图像将不会出现在文本页面中。

  3. 图像的“变换矩阵”被定义为矩阵,对于这个表达式 bbox / transform == pymupdf.Rect(0, 0, 1, 1) 为真,在这里查找详细信息: 图像变换矩阵

  4. 透明图像可能会伴随一个蒙版图像。这个图像存储在键 "mask" 下,格式为 DeviceGray PNG 图像。否则,此键的值为 None。如果存在,你可能能够恢复(相当于)原始图像 – 即具有透明度 – 通过从“图像”和“蒙版”值创建 Pixmap 对象并将其叠加。这并不能保证总是有效,因为蒙版图像有多种格式,并不是所有格式都符合叠加 Pixmap 支持的条件。以下是一个代码片段:

>>> base = pymupdf.Pixmap(block["image"])
>>> mask = pymupdf.Pixmap(block["mask"])
>>> result = pymupdf.Pixmap(base, mask)

文本块:

类型

0 = 文本 (int)

边界框

块矩形, rect_like

数字

区块数 (int)

文本行字典的列表

行字典#

边界框

线矩形, rect_like

wmode

书写模式 (int): 0 = 水平, 1 = 垂直

dir

书写方向, point_like

跨度

跨度 字典的列表

“dir” 的值是角度的 单位向量 dir = (cosine, -sine),该角度相对于 x 轴 [2]。请参阅以下图片:每个象限中的单词(从右上角开始逆时针方向到右下角)分别旋转了 30、120、210 和 300 度。

_images/img-line-dir.png

跨度字典#

跨度包含实际文本。如果一行包含具有不同字体属性的文本,则该行 仅包含一个以上的跨度

  • 在版本 1.14.17 中更改 现在跨度也有一个 bbox 键(再次)。

  • 在版本 1.17.6 中更改,现在 Spans 也有一个 origin 键。

边界框

跨度矩形, rect_like

起源

第一个字符的起源, point_like

字体

字体名称 (str)

上升线

字体的上升线 (浮点数)

下行符

字体的下行符 (float)

大小

字体大小 (float)

标志

字体特征 (int)

字符标志

字符特征 (int)

颜色

以 sRGB 格式表示的文本颜色 (int)

文本

(仅适用于 extractDICT()) 文本 (字符串)

字符

(仅适用于 extractRAWDICT()) 字符字典 的列表

(版本 1.16.0 中新增): “color” 是以 sRGB (int) 格式编码的文本颜色,例如 0xFF0000 表示红色。 有将这个整数转换回格式 (r, g, b) (PDF 中的浮点值范围从 0 到 1) sRGB_to_pdf() 的函数,或者 (R, G, B), sRGB_to_rgb() (整数值范围从 0 到 255)。

(在 v1.18.5 中新增): “ascender”“descender” 是字体属性,相对于 fontsize 1 提供。请注意,descender 是一个负值。下图显示了与其他值和属性的关系。

_images/img-asc-desc.png

这些数字可以用来计算字符(或跨度)的最小高度 - 与“bbox”值中提供的标准高度相对(实际上代表了行高)。以下代码重新计算跨度的 bbox,以使其高度为fontsize,正好适合内部的文本:

>>> a = span["ascender"]
>>> d = span["descender"]
>>> r = pymupdf.Rect(span["bbox"])
>>> o = pymupdf.Point(span["origin"])  # its y-value is the baseline
>>> r.y1 = o.y - span["size"] * d / (a - d)
>>> r.y0 = r.y1 - span["size"]
>>> # r now is a rectangle of height 'fontsize'

注意

上述计算可能会产生一个 更大的 高度!这可能发生在 OCR 处理的文档中,那里各种文本伪影的风险很高。MuPDF 试图提出一个合理的边界框高度,与在 PDF 中找到的 fontsize 无关。因此,请确保 span["bbox"] 的高度大于 更大span["size"]

注意

您可以通过执行 pymupdf.TOOLS.set_small_glyph_heights(True) 请求 PyMuPDF 自动执行上述所有操作。这设置了一个全局参数,以便所有后续的文本搜索和文本提取都基于缩小的字形高度(在有意义的情况下)。

下图显示了原始的红色矩形和重新计算高度后的蓝色矩形。

_images/img-span-rect.png

“flags” 是一个整数,表示字体属性,除了第一个位 0。它们的解释如下:

  • 位 0: 上标 (20) – 不是字体属性,由 MuPDF 代码检测。

  • 位 1: 斜体 (21)

  • 位 2: 带衬线的 (22)

  • 位 3: 等宽字体 (23)

  • bit 4: 粗体 (24)

像这样测试这些特征:

>>> if flags & 2**1: print("italic")
>>> # etc.

位1到4是字体属性,即编码在字体程序中。请注意,这些信息不一定是正确或完整的:字体中往往包含错误的数据。

“char_flags” 是一个整数,表示额外的字符属性:

  • 位 0: 划掉。

  • 位 1:下划线。

  • 位 2:合成。

  • 位 3:已填充。

  • 位 4:已描边。

  • 位 5: 被截断。

例如,如果没有填充且没有边框 (if not (char_flags & 2**3 & 2**4): ...) 那么文本将不可见。

(char_flags 在 v1.25.2 中是新的。)

提取原始字典的字符字典 extractRAWDICT()#

原点

角色的左基线点, point_like

边界框

字符矩形, rect_like

c

字符(unicode)

此图显示了字符的边界框与其四边形之间的关系: textpagechar

脚注


本软件按原样提供,不作任何明示或暗示的担保。该软件根据许可证分发,除非按照该许可证的条款明确授权,否则不得复制、修改或分发。有关许可信息,请参阅artifex.com或联系Artifex Software Inc.,地址:39 Mesa Street, Suite 108A, San Francisco CA 94129, United States以获取更多信息。