PyMuPDF 1.24.4 中文文档(十)(2)https://developer.aliyun.com/article/1559522
Span 字典
Span 包含实际文本。如果一行包含具有不同字体属性的文本,则包含多个 span。
- 自版本 1.14.17 更改 Spans 现在也有一个 bbox 键(再次)。
- 自版本 1.17.6 更改 Spans 现在也有一个 origin 键。
Key | Value |
bbox | span 矩形,rect_like |
origin | 第一个字符的来源,point_like |
font | 字体名称 (字符串) |
ascender | 字体的 ascender (浮点数) |
descender | 字体的 descender (浮点数) |
size | 字体大小 (浮点数) |
flags | 字体特性 (整数) |
color | sRGB 格式下的文本颜色 (整数) |
text | (仅适用于 extractDICT() ) 文本 (字符串) |
chars | (仅适用于 extractRAWDICT() ) 字符字典的列表 |
(新增于版本 1.16.0): “color” 是以 sRGB 编码的文本颜色(整数),例如红色为 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 是一个负值。以下图片展示了它们与其他值和属性的关系。
这些数字可以用来计算字符(或 span)的最小高度,与“bbox”值中提供的标准高度相对应(实际上代表行高)。以下代码重新计算 span 的 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 尝试提供一个合理的 bbox 高度,与 PDF 中找到的 fontsize
无关。因此,请确保 span["bbox"]
的高度大于 span["size"]
。
注意
您可以通过执行 pymupdf.TOOLS.set_small_glyph_heights(True)
要求 PyMuPDF 自动执行以上所有操作。这会设置一个全局参数,以便所有后续的文本搜索和文本提取都基于降低的字形高度,而这些高度是有意义的。
下图显示了原始 span 矩形为红色,重新计算高度后的矩形为蓝色。
“标志” 是一个整数,代表字体属性,但第一个位 0 除外。其解释如下:
- 第 0 位:上标 (2⁰) - 不是字体属性,MuPDF 代码检测到的。
- 第 1 位:斜体 (2¹)
- 位 2:衬线体 (2²)
- 位 3:等宽字体 (2³)
- 第 4 位:粗体 (2⁴)
测试这些特性的方式如下:
>>> if flags & 2**1: print("italic") >>> # etc.
位 1 到 4 是字体属性,即在字体程序中编码。请注意,此信息未必正确或完整:字体往往在这里包含错误数据。
extractRAWDICT()
的字符字典
键 | 值 |
origin | 字符的左基线点,point_like |
bbox | 字符矩形,rect_like |
c | 字符(Unicode) |
此图显示了字符的边界框和其四边形之间的关系:
脚注
你对这一页有什么反馈吗?
此软件按原样提供,不带任何明示或暗示的保证。此软件根据许可分发,未经授权不得复制、修改或分发。有关详细信息,请参阅artifex.com,或联系美国加利福尼亚州旧金山市 Mesa 街 39 号 108A 室的 Artifex Software Inc。。
此文档涵盖了所有 1.24.4 版本及以前的版本。
## 字典输出的结构
方法 TextPage.extractDICT()
,TextPage.extractJSON()
,TextPage.extractRAWDICT()
和 TextPage.extractRAWJSON()
返回包含页面文本和图像内容的字典。所有四种方法的字典结构几乎相同。它们力图通过表示每个子字典来尽可能精确地映射文本页面的信息层次结构:块、行、跨度和字符:
- 一个 页面 由一系列 块字典 组成。
- 一个(文本) 块 由一系列 行字典 组成。
- 一条 线 由一系列 跨度字典 组成。
- 一个 跨度 可以是文本本身,也可以是原始变体的 字符字典 列表。
- 原始变体:一个 字符 是其原点、边界框和 Unicode 的字典。
这里所有的 PyMuPDF 几何对象(点、矩形、矩阵)都用其 “like” 格式表示:使用 rect_like
元组 代替 Rect 等。这样做是出于性能和内存考虑:
- 此代码是用 C 语言编写的,其中 Python 元组可以轻松生成。另一方面,几何对象仅在 Python 源代码中定义。将每个 Python 元组转换为其相应的几何对象会增加显著的执行时间,这在大多数情况下是不必要的。
- 一个 4 元组大约需要 168 字节,相应的 Rect 则需要 472 字节,几乎是前者的三倍大小。一个文本密集型页面的 “dict” 字典包含 300 多个 bbox 对象,因此以 4 元组形式需要约 50 KB 存储空间,而以 Rect 对象形式需要约 140 KB。然而,对于这样的页面,“rawdict”输出将包含 4 到 5 千个 bbox,这种情况下大约是 750 KB 对比 2 MB。
还请注意,仅返回 bboxes (= rect_like
4 元组),而 TextPage 实际上具有完整的位置信息 – 以 Quad 格式表示。再次考虑内存使用的原因,做出这样的决定:quad_like
需要 488 字节(是 rect_like
的三倍大小)。考虑到生成的 bbox 数量,返回 quad_like
信息会有显著影响。
在绝大多数情况下,我们只处理 水平文本,在这种情况下,bbox 提供的信息已经完全足够。
另外,完整的四边形信息没有丢失:可以根据需要使用以下列表中的适当函数来恢复行、跨度和字符的四边形信息:
recover_quad()
– 完整跨度的四边形recover_span_quad()
– 跨度子集的四边形recover_line_quad()
– 行的四边形recover_char_quad()
– 字符的四边形
正如前述的,只有在文本 非水平写入 的情况下才需要使用这些函数 – line["dir"] != (1, 0)
– 并且需要用于文本标记注释的四边形 (Page.add_highlight_annot()
和其它相关函数)。
页面字典
键 | 值 |
width | clip 矩形的宽度 (浮点数) |
height | clip 矩形的高度 (浮点数) |
blocks | 块字典的 列表 |
块字典
块字典有两种不同的格式,分别用于 图像块 和 文本块。
- (更改于 v1.18.0) – 新字典键 number,块编号。
- (更改于 v1.18.11) – 新字典键 transform,图像块的图像变换矩阵。
- (更改于 v1.18.11) – 新字典键 size,图像块中图像的大小(以字节为单位)。
图像块:
键 | 值 |
type | 1 = 图像 (整数) |
bbox | 页面上图像边界框(rect_like ) |
number | 块计数 (整数) |
ext | 图像类型 (字符串),作为文件扩展名,详见下文 |
width | 原始图像宽度 (整数) |
height | 原始图像高度 (整数) |
colorspace | 色彩空间组件计数 (整数) |
xres | x 方向的分辨率 (整数) |
yres | y 方向的分辨率 (整数) |
bpc | 每个组件的比特数 (整数) |
transform | 将图像矩形转换为边界框的矩阵(matrix_like ) |
size | 图像大小,以字节为单位 (整数) |
image | 图像内容 (字节) |
“ext” 键的可能取值包括 “bmp”, “gif”, “jpeg”, “jpx” (JPEG 2000), “jxr” (JPEG XR), “png”, “pnm” 和 “tiff”。
注意
- 对页面上每个图像出现的位置生成图像块。因此,如果图像在不同位置显示,则可能存在重复。
- TextPage 和相应方法
Page.get_text()
适用于所有文档类型。仅针对 PDF 文档,方法Document.get_page_images()
/Page.get_images()
在图像列表方面提供了一些重叠功能。但两个列表可能或可能不会包含相同的项目。任何差异很可能是由以下原因之一引起的:
- PDF 页面的“内联”图像(参见 Adobe PDF 参考手册第 214 页)包含在文本页中,但不会出现在
Page.get_images()
中。- 注释中也可能包含图像 – 这些图像将不会出现在
Page.get_images()
中。- 在文本页中,每个图像位置都会生成图像块 – 无论是否存在任何重复。这与
Page.get_images()
不同,后者只会列出每个图像一次(根据引用名称)。- 在页面的
object
定义中提到的图像将始终出现在Page.get_images()
中[1]。但可能会出现这样的情况,即页面的contents
中没有“display”命令(错误地或有意)。在这种情况下,该图像将不会出现在文本页中。
- 图像的“变换矩阵”定义为矩阵,使得表达式
bbox / transform == pymupdf.Rect(0, 0, 1, 1)
成立,请参阅详细信息:图像变换矩阵。
文本块:
键 | 值 |
type | 0 = 文本 (整数) |
bbox | 块矩形,rect_like |
number | 块计数 (整数) |
lines | 文本行字典的列表 |
行字典
键 | 值 |
bbox | 行矩形,rect_like |
wmode | 书写模式 (int): 0 = 水平, 1 = 垂直 |
dir | 书写方向,point_like |
spans | 跨度字典的列表 |
键*“dir”*的值是角度相对于 x 轴的单位向量 dir = (cosine, -sine)
,见图示:每个象限中的词(从右上方逆时针到右下方)分别旋转 30 度、120 度、210 度和 300 度。
跨度字典
跨度包含实际文本。如果一行包含具有不同字体属性的文本,则该行包含多个跨度。
- 从版本 1.14.17 更改,跨度现在也有一个bbox键(再次)。
- 从版本 1.17.6 更改,跨度现在也有一个origin键。
键 | 值 |
bbox | 跨度矩形,rect_like |
origin | 第一个字符的起源,point_like |
font | 字体名称 (str) |
ascender | 字体的上升部分 (float) |
descender | 字体的下降部分 (float) |
size | 字体大小 (float) |
flags | 字体特性 (int) |
color | sRGB 格式文本颜色 (int) |
text | (仅适用于extractDICT() )文本 (str) |
chars | (仅适用于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 是一个负值。以下图片显示了与其他值和属性的关系。
这些数字可用于计算字符(或跨度)的最小高度 - 与“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'
注意
上述计算可能会得到更大的高度!这可能发生在 OCRed 文档中,那里各种文本伪影的风险很高。MuPDF 试图独立于 PDF 中找到的fontsize
,提供一个合理的 bbox 高度。因此,请确保span["bbox"]
的高度大于span["size"]
。
注意
您可以通过执行pymupdf.TOOLS.set_small_glyph_heights(True)
来请求 PyMuPDF 自动执行上述所有操作。这会设置一个全局参数,以便所有后续的文本搜索和文本提取都基于降低的字形高度(在有意义时)。
这里显示了原始跨度矩形为红色,重新计算高度后的矩形为蓝色。
“flags” 是一个整数,代表除了第一个位 0 以外的字体属性。它们应该按照以下方式解释:
- 位 0: 上标(2⁰) – 不是字体属性,由 MuPDF 代码检测。
- 位 1: 斜体(2¹)
- 位 2: 衬线字体(2²)
- 位 3: 等宽字体(2³)
- 位 4: 粗体(2⁴)
如此测试这些特性:
>>> if flags & 2**1: print("italic") >>> # etc.
位 1 到 4 是字体属性,即编码在字体程序中。请注意,此信息未必正确或完整:字体往往在此处包含错误数据。
extractRAWDICT()
的字符字典
关键字 | 数值 |
origin | 字符左基线点,point_like |
bbox | 字符矩形,rect_like |
c | 字符(unicode) |
这幅图展示了字符 bbox 与其 quad 之间的关系:
脚注
您对本页面有何反馈?
此软件按原样提供,不带任何明示或暗示的担保。此软件在许可证下分发,并且未经授权不得复制、修改或分发。请参阅artifex.com的许可信息或联系美国加利福尼亚州旧金山 Mesa 街 39 号 108A 套房的 Artifex Software Inc.了解更多信息。
本文档涵盖所有 1.24.4 版本及更早版本。
页面字典
关键字 | 数值 |
width | clip 矩形的宽度 (浮点数) |
height | clip 矩形的高度 (浮点数) |
blocks | 块 字典列表 |
块字典
块字典有两种不同的格式,适用于图像块和文本块。
- (在 v1.18.0 中更改) – 新的字典键 number,块编号。
- (在 v1.18.11 中更改) – 新字典键 transform,图像块的转换矩阵。
- (在 v1.18.11 中更改) – 新字典键 size,图像块的字节大小。
图像块:
关键字 | 数值 |
类型 | 1 = 图像 (int) |
bbox | 页面上的图像边界框 (rect_like ) |
数量 | 块计数 (int) |
扩展名 | 图像类型 (str),作为文件扩展名,见下文 |
宽度 | 原始图像宽度 (int) |
高度 | 原始图像高度 (int) |
颜色空间 | 颜色空间组件计数 (int) |
xres | x 方向分辨率 (int) |
yres | y 方向分辨率 (int) |
bpc | 每分量的位数 (int) |
转换 | 将图像矩形转换为边界框的矩阵 (matrix_like ) |
大小 | 图像大小(字节为单位) (int) |
图像 | 图像内容 (bytes) |
“ext” 键的可能值为 “bmp”, “gif”, “jpeg”, “jpx” (JPEG 2000), “jxr” (JPEG XR), “png”, “pnm”, 和 “tiff”。
注:
- 文本页中为每个图像位置生成图像块 —— 因此如果图像在不同位置显示,则可能存在重复。
TextPage
和对应的方法Page.get_text()
适用于所有文档类型。对于 PDF 文档,方法Document.get_page_images()
/Page.get_images()
在图像列表方面提供了一些重叠功能。但是这两个列表可能会或者可能不会包含相同的项目。任何差异很可能是由以下原因之一造成的:
- PDF 页的“内联”图像(见 Adobe PDF 参考手册第 214 页)包含在文本页中,但不会出现在
Page.get_images()
中。- 注释中也可能包含图像 —— 这些图像不会出现在
Page.get_images()
中。- 文本页中的图像块为每个图像位置生成 —— 无论是否存在任何重复。这与
Page.get_images()
的行为形成对比,后者将仅列出每个图像的一次(每个参考名称)。- 在页面的
object
定义中提到的图像将始终出现在Page.get_images()
中 [1]。但可能会出现以下情况,在页面的contents
中没有“display”命令(错误或故意省略)。在这种情况下,图像将不会出现在文本页中。
- 图像的“转换矩阵”被定义为满足表达式
bbox / transform == pymupdf.Rect(0, 0, 1, 1)
的矩阵,详情请参见:图像转换矩阵。
文本块:
键 | 值 |
类型 | 0 = 文本 (整数) |
bbox | 块矩形,rect_like |
数量 | 块计数 (整数) |
lines | 文本行字典列表 |
行字典
键 | 值 |
bbox | 行矩形,rect_like |
wmode | 写作模式 (整数):0 = 水平,1 = 垂直 |
dir | 写作方向,point_like |
spans | 跨度字典列表 |
键值 “dir” 的值是文本相对于 x 轴的角度的 单位向量 dir = (cosine, -sine)
[2]。请参见下图:每个象限的单词(从右上到右下逆时针)分别旋转了 30、120、210 和 300 度。
跨度字典
跨度包含实际的文本。只有当一行包含具有不同字体属性的文本时,它才包含 多个跨度。
- 更改于版本 1.14.17,跨度现在也有一个 bbox 键(再次)。
- 更改于版本 1.17.6,跨度现在也有一个 origin 键。
键 | 值 |
bbox | 跨度矩形,rect_like |
origin | 第一个字符的原点,point_like |
font | 字体名称 (字符串) |
ascender | 字体的升头 (浮点数) |
降头 | 字体的降头 (浮点数) |
size | 字体大小 (浮点数) |
flags | 字体特征 (整数) |
color | 文本颜色,sRGB 格式 (整数) |
text | (仅用于 extractDICT() )文本 (字符串) |
chars | (仅用于 extractRAWDICT() )字符字典列表 |
(版本 1.16.0 新增): “color” 是以 sRGB (整数) 格式编码的文本颜色,例如红色的 0xFF0000。有函数可以将此整数转换回格式(r,g,b)(从 0 到 1 的浮点数)sRGB_to_pdf()
,或(R,G,B),sRGB_to_rgb()
(从 0 到 255 的整数值)。
(版本 1.18.5 新增): “ascender” 和 “descender” 是字体属性,相对于 fontsize
1 提供。请注意,descender 是一个负值。下图显示了它们与其他值和属性的关系。
这些数字可用于计算字符(或跨度)的最小高度 - 与“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 试图提供一个合理的 bbox 高度,独立于 PDF 中找到的fontsize
。因此,请确保span["bbox"]
的高度大于span["size"]
。
注意
您可以通过执行pymupdf.TOOLS.set_small_glyph_heights(True)
来请求 PyMuPDF 自动完成上述所有操作。这将设置一个全局参数,以便所有后续的文本搜索和文本提取都基于降低的字形高度,以提供更有意义的结果。
下面显示了原始 span 矩形为红色,重新计算高度后的矩形为蓝色。
*“flags”*是一个整数,代表字体属性,除了第一个位 0。它们应该这样解释:
- bit 0: 上标(2⁰) - 不是字体属性,由 MuPDF 代码检测到。
- bit 1: 斜体(2¹)
- bit 2: 衬线字体(2²)
- bit 3: 等宽字体(2³)
- bit 4: 粗体(2⁴)
测试这些特性如下:
>>> if flags & 2**1: print("italic") >>> # etc.
位 1 到 4 是字体属性,即编码在字体程序中。请注意,这些信息不一定正确或完整:字体往往在这里包含错误的数据。
提取extractRAWDICT()
的字符字典
关键词 | 数值 |
origin | 字符的左基线点,point_like |
bbox | 字符矩形,rect_like |
c | 字符(Unicode) |
此图片展示了字符 bbox 与其 quad 之间的关系:
脚注
您对本页有任何反馈吗?
本软件按原样提供,不附带任何明示或暗示的保证。此软件在许可下分发,未经授权不得复制、修改或分发。请参阅artifex.com的许可信息或联系美国旧金山 CA 94129 Mesa 街 39 号 108A 套房的 Artifex Software Inc.以获取更多信息。
此文档覆盖了所有版本直到 1.24.4。
PyMuPDF 1.24.4 中文文档(十)(4)https://developer.aliyun.com/article/1559524