本章提供了关于 PyMuPDF 中嵌入式文件支持的一些背景信息。
从版本 1.4 开始,PDF 支持将任意文件作为 PDF 文档文件的一部分(“嵌入式文件流”)嵌入其中(参见章节“7.11.4 嵌入式文件流”,第 103 页的 Adobe PDF 参考手册)。
在许多方面,这与 ZIP 文件或 MS Windows 中的 OLE 技术中的概念相似。然而,PDF 嵌入式文件不支持像 ZIP 格式那样的目录结构。一个嵌入式文件可以包含自身的嵌入式文件。
这个概念的优点在于,嵌入式文件位于 PDF 的保护伞之下,从其权限/密码保护和完整性方面受益:PDF 可能引用或甚至依赖的所有数据都可以捆绑到其中,因此形成一个单一的、一致的信息单元。
除了嵌入式文件外,PDF 1.7 还添加了集合到其支持范围中。这是一种高级的存储和展示嵌入式文件元信息(即任意和可扩展属性)的方式。
在 MuPDF 版本 1.11 中添加对集合(portfolio)和*/EmbeddedFiles*的初始支持后,此支持在版本 1.15 中再次被删除。
作为结果,命令行实用程序mutool不再提供访问嵌入式文件的功能。
由于 PyMuPDF 在其 1.11.0 版本中响应地实现了*/EmbeddedFiles* API,因此在其 1.16.0 版本开始,不得不改变方向(我们从未发布过与 MuPDF v1.15.x 兼容的 PyMuPDF)。
我们现在正在维护我们自己的代码库,支持嵌入式文件。该代码仅使用基本的 MuPDF 字典和数组函数。
我们继续支持旧的 API,关于嵌入式文件的所有内容,只做了轻微的、表面上的变化。
还有一个新功能,可以提供 PDF 中所有已注册嵌入数据名称列表,Document.embfile_names()
。
对本页有任何反馈吗?
本软件按原样提供,不带任何明示或暗示的保证。此软件根据许可证分发,未经授权许可,不得复制、修改或分发。有关更多信息,请参阅artifex.com上的许可信息或联系 Artifex Software Inc.,39 Mesa Street,Suite 108A,San Francisco CA 94129,美国。
本文档涵盖了所有版本直到 1.24.4。
[外链图片转存中…(img-Qb7tttpJ-1718851590733)]
从版本 1.4 开始,PDF 支持将任意文件嵌入作为 PDF 文档文件的一部分(“嵌入文件流”),详见第 7.11.4 章节,“7.11.4 嵌入文件流”页,Adobe PDF 参考手册。
在许多方面,这与 ZIP 文件或 MS Windows 中的 OLE 技术中发现的概念相似。但是,PDF 嵌入文件不支持像 ZIP 格式那样的目录结构。一个嵌入文件可以包含其自身的嵌入文件。
此概念的优势在于嵌入文件位于 PDF 的总称之下,从而受益于其权限/密码保护和完整性方面:PDF 可能引用的或甚至可能依赖的所有数据都可以捆绑到其中,形成一个单一、一致的信息单元。
除了嵌入文件外,PDF 1.7 还扩展了对 collections 的支持范围。这是一种存储和展示嵌入文件元信息(即任意和可扩展属性)的高级方式。
在 MuPDF 版本 1.11 中添加了对 collections(文件集合)和 /EmbeddedFiles 的初始支持后,该支持在版本 1.15 中被再次取消。
因此,cli 实用程序 mutool 不再提供对嵌入文件的访问。
作为其 1.11.0 版本中响应的 /EmbeddedFiles API 的一部分,PyMuPDF 被迫在其 1.16.0 版本中改变方向(我们从未发布过与 MuPDF v1.15.x 兼容的 PyMuPDF)。
现在我们正在维护支持嵌入文件的自有代码库。该代码仅使用基本的 MuPDF 字典和数组功能。
我们继续支持关于嵌入文件的完整旧 API,仅有轻微的表现变化。
还有一个新功能,它提供了 PDF 中所有注册嵌入数据名称列表,Document.embfile_names()
。
您对本页面有任何反馈意见吗?
此软件按原样提供,没有明示或暗示的任何保证。此软件在许可下分发,未经授权不得复制、修改或分发。有关详细信息,请参阅artifex.com,或联系美国加利福尼亚州旧金山 Mesa 街 39 号 108A 室的 Artifex Software 公司。
此文档涵盖了所有版本直至 1.24.4。
[外链图片转存中…(img-t7xYWJxx-1718851590734)]
本节涉及各种技术主题,它们并非必然相关。
从版本 1.18.11 开始,一些文本和图像提取方法返回图像变换矩阵:Page.get_text()
和 Page.get_image_bbox()
。
变换矩阵包含关于图像如何转换以适应某文档页面上的矩形(其“边界框”=“bbox”)的信息。通过检查页面上图像的 bbox 和此矩阵,可以确定例如图像是否以缩放或旋转的方式显示在页面上。
图像尺寸与页面上其 bbox 之间的关系如下:
使用原始图像的宽度和高度,
imgrect = pymupdf.Rect(0, 0, width, height)
shrink = pymupdf.Matrix(1/width, 0, 0, 1/height, 0, 0)
。
使用其缩小矩阵转换图像矩形将导致单位矩形:imgrect * shrink = pymupdf.Rect(0, 0, 1, 1)
。
使用图像变换矩阵“transform”,以下步骤将计算出 bbox:
imgrect = pymupdf.Rect(0, 0, width, height)
shrink = pymupdf.Matrix(1/width, 0, 0, 1/height, 0, 0)
bbox = imgrect * shrink * transform
检查矩阵乘积 shrink * transform
将显示有关使图像矩形适应页面 bbox 所发生的一切信息:旋转、边缘缩放和原点平移。让我们看一个例子:
>>> imginfo = page.get_images()[0] # get an image item on a page
>>> imginfo
(5, 0, 439, 501, 8, 'DeviceRGB', '', 'fzImg0', 'DCTDecode')
>>> #------------------------------------------------
>>> # define image shrink matrix and rectangle
>>> #------------------------------------------------
>>> shrink = pymupdf.Matrix(1 / 439, 0, 0, 1 / 501, 0, 0)
>>> imgrect = pymupdf.Rect(0, 0, 439, 501)
>>> #------------------------------------------------
>>> # determine image bbox and transformation matrix:
>>> #------------------------------------------------
>>> bbox, transform = page.get_image_bbox("fzImg0", transform=True)
>>> #------------------------------------------------
>>> # confirm equality - permitting rounding errors
>>> #------------------------------------------------
>>> bbox
Rect(100.0, 112.37525939941406, 300.0, 287.624755859375)
>>> imgrect * shrink * transform
Rect(100.0, 112.375244140625, 300.0, 287.6247253417969)
>>> #------------------------------------------------
>>> shrink * transform
Matrix(0.0, -0.39920157194137573, 0.3992016017436981, 0.0, 100.0, 287.6247253417969)
>>> #------------------------------------------------
>>> # the above shows:
>>> # image sides are scaled by same factor ~0.4,
>>> # and the image is rotated by 90 degrees clockwise
>>> # compare this with pymupdf.Matrix(-90) * 0.4
>>> #------------------------------------------------
所有 PDF 阅读器必须支持以下 14 种内置字体名称。它们作为一个字典提供,将它们的全名及其小写缩写映射到完整的字体基本名称。在 PyMuPDF 中需要提供字体名称时,可以使用字典中的任何键或值:
In [2]: pymupdf.Base14_fontdict
Out[2]:
{'courier': 'Courier',
'courier-oblique': 'Courier-Oblique',
'courier-bold': 'Courier-Bold',
'courier-boldoblique': 'Courier-BoldOblique',
'helvetica': 'Helvetica',
'helvetica-oblique': 'Helvetica-Oblique',
'helvetica-bold': 'Helvetica-Bold',
'helvetica-boldoblique': 'Helvetica-BoldOblique',
'times-roman': 'Times-Roman',
'times-italic': 'Times-Italic',
'times-bold': 'Times-Bold',
'times-bolditalic': 'Times-BoldItalic',
'symbol': 'Symbol',
'zapfdingbats': 'ZapfDingbats',
'helv': 'Helvetica',
'heit': 'Helvetica-Oblique',
'hebo': 'Helvetica-Bold',
'hebi': 'Helvetica-BoldOblique',
'cour': 'Courier',
'coit': 'Courier-Oblique',
'cobo': 'Courier-Bold',
'cobi': 'Courier-BoldOblique',
'tiro': 'Times-Roman',
'tibo': 'Times-Bold',
'tiit': 'Times-Italic',
'tibi': 'Times-BoldItalic',
'symb': 'Symbol',
'zadb': 'ZapfDingbats'}
与其义务相反,并非所有 PDF 阅读器都正确和完全支持这些字体——这对于 Symbol 和 ZapfDingbats 尤为明显。此外,字形(视觉)图像将针对每个阅读器具体展现。
要查看这些字体如何使用,包括CJK 内置字体,请参阅 Page.insert_font()
中的表格。
Adobe 发布的这本 PDF 参考手册经常在本文档中引用。可以从这里查看和下载。
注意
长时间以来,一个较旧的版本也可以在 这里 找到。似乎在 2021 年 10 月从网站上移除了该链接。早期(1.19.*之前)的 PyMuPDF 文档版本曾引用过这个文档。我们已经努力替换了上述当前规范的引用。
当 PyMuPDF 对象和方法需要 Python 列表 数值时,其他 Python 序列类型 也是允许的。如果 Python 类具有 __getitem__()
方法,则称其实现了 序列协议。
这基本上意味着,在这些情况下,你可以互换使用 Python list 或 tuple,甚至 array.array、numpy.array 和 bytearray 类型。
例如,在以下任何一种方式中指定序列 "s"
s = [1, 2]
– 一个列表
s = (1, 2)
– 一个元组
s = array.array("i", (1, 2))
– 一个 array.array
s = numpy.array((1, 2))
– 一个 numpy 数组
s = bytearray((1, 2))
– 一个 bytearray
这将使其在以下示例表达式中可用:
pymupdf.Point(s)
pymupdf.Point(x, y) + s
doc.select(s)
与所有几何对象 Rect、IRect、Matrix 和 Point 类似。
因为所有 PyMuPDF 几何类本身都是序列的特殊情况(Quad 除外——见下文),它们可以自由地在可以使用数字序列的地方使用,例如作为 list()、tuple()、array.array() 或 numpy.array() 的参数传递给函数。查看以下代码片段,看看这样做的效果。
>>> import pymupdf, array, numpy as np
>>> m = pymupdf.Matrix(1, 2, 3, 4, 5, 6)
>>>
>>> list(m)
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
>>>
>>> tuple(m)
(1.0, 2.0, 3.0, 4.0, 5.0, 6.0)
>>>
>>> array.array("f", m)
array('f', [1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
>>>
>>> np.array(m)
array([1., 2., 3., 4., 5., 6.])
注意
Quad 是一个 Python 序列对象,长度为 4。然而,它的项是point_like
类型的——而不是数字。因此,上述说明不适用。
PyMuPDF 是 C 库 MuPDF 的 Python 绑定。尽管 MuPDF 的创建者已经投入了大量精力来近似一种面向对象的行为,但他们显然无法克服 C 语言在这方面的基本缺陷。
另一方面,Python 以非常清晰的方式实现了面向对象模型。PyMuPDF 与 MuPDF 之间的接口代码由两个基本文件组成:pymupdf.py 和 fitz_wrap.c。它们由优秀的 SWIG 工具为每个新版本创建。
当你使用 PyMuPDF 的对象或方法之一时,将导致执行一些代码在 pymupdf.py 中,进而调用一些用 fitz_wrap.c 编译的 C 代码。
因为SWIG会尽力保持 Python 和 C 级别同步,如果严格遵循一定的规则,一切都会正常工作。例如:永远不要访问在关闭(或删除或设置为 None)拥有的文档之后的页面对象。或者,不那么明显的是:在执行文档方法 select()、delete_page()、insert_page() … 等之后,永远不要访问页面或其任何子元素(链接或注释)。
但仅仅不再访问失效的对象是不够的:它们应该被完全主动删除,以释放 C 级别资源(即分配的内存)。
这些规则的原因在于文档与其页面之间以及页面与其链接/注释之间存在层次化的二级一对多关系。为了保持一致的状态,任何上述操作都必须导致完全重置 - 在Python和同步在 C 中。
SWIG无法知道这一点,因此也不执行它。
因此,所需的逻辑已经内置到 PyMuPDF 本身中,如下所示。
程序员通常不会意识到这些情况。但是,如果试图访问失效的对象,则会引发异常。
无效的对象不能像 Python 语句 del page 或 page = None 等直接删除。而是必须调用它们的 del 方法。
所有页面、链接和注释都有属性 parent,指向拥有的对象。这是可以在应用程序级别检查的属性:如果 obj.parent == None,则对象的父对象已经不存在,对其属性或方法的任何引用都将引发异常,指示其处于“孤立”状态。
一个示例会话:
>>> page = doc[n]
>>> annot = page.first_annot
>>> annot.type # everything works fine
[5, 'Circle']
>>> page = None # this turns 'annot' into an orphan
>>> annot.type
<... omitted lines ...>
RuntimeError: orphaned object: parent is None
>>>
>>> # same happens, if you do this:
>>> annot = doc[n].first_annot # deletes the page again immediately!
>>> annot.type # so, 'annot' is 'born' orphaned
<... omitted lines ...>
RuntimeError: orphaned object: parent is None
这展示了级联效应:
>>> doc = pymupdf.open("some.pdf")
>>> page = doc[n]
>>> annot = page.first_annot
>>> page.rect
pymupdf.Rect(0.0, 0.0, 595.0, 842.0)
>>> annot.type
[5, 'Circle']
>>> del doc # or doc = None or doc.close()
>>> page.rect
<... omitted lines ...>
RuntimeError: orphaned object: parent is None
>>> annot.type
<... omitted lines ...>
RuntimeError: orphaned object: parent is None
注意
不包括在上述关系之外的对象。例如,如果通过 toc = doc.get_toc() 创建目录,然后关闭或更改文档,则变量 toc 不能也不会以任何方式改变。您有责任根据需要刷新这些变量。
Page.show_pdf_page()
该方法在当前页面的指定矩形内显示另一 PDF 文档的(“源”)页面的图像。
Page.insert_image()
相反,此显示为基于矢量的,因此在缩放级别上保持准确。
Page.insert_image()
一样,显示的尺寸根据给定的矩形进行调整。
目前支持以下显示变体:
"保持比例"
控制是否保持宽高比(默认)。
"剪辑"
限制了源页面矩形的可见部分。默认为整个页面。"旋转"
以任意角度(度数)旋转显示。如果角度不是 90 的整数倍,则如果"保持比例"
也为真,则可能只有 4 个角中的 2 个位置在目标边界上。
"覆盖"
控制是否将图像放置在当前页面内容的顶部(前景,默认)或不(背景)。
使用案例包括(但不限于)以下内容:
这是使用 PDF “表单 XObject” 完成的,参见 Adobe PDF References 第 8.10 节第 217 页。在执行Page.show_pdf_page()
时,将执行以下操作:
资源
和内容
对象被复制到目标文档,共同创建一个新的表单 XObject,具有以下属性。该对象的 PDF xref
编号由该方法返回。/BBox
等于源页面的/Mediabox
。/Matrix
等于单位矩阵。/资源
等同于源页面的内容。这包括对层级嵌套的其他对象(包括字体、图像等)进行“深复制”。此处涉及的复杂性由 MuPDF 的嫁接技术函数[1]覆盖。内容
对象的组合数据的精确副本。此表单 XObject 仅在显示源页面时执行一次。后续显示相同的源页面将跳过此步骤,并且仅为该对象创建“指针”形式的表单 XObject(在下一步中完成)。
/BBox
等于源页面的 /CropBox
(或 "clip"
)。/Matrix
表示 /BBox
到目标矩形的映射。/XObject
通过固定名称 fullpage
引用前面的 Form XObject。/fullpage Do
。"oc"
参数被指定,其值将被赋予此 Form XObject 作为 /OC
。resources
和 contents
对象如下。/Resources
的 /XObject
字典中增加一个条目,名称为 fzFrm
(选择 n 使得此条目在页面上是唯一的)。"overlay"
,在页面的 /Contents
数组之前或之后添加一个新对象,包含语句 q /fzFrm<n> Do Q
。这种设计方法确保:
"oc"
参数,用于单独控制源页面的可见性。 ## 重定向错误和警告消息
自 MuPDF 版本 1.16 起,错误和警告消息可以通过官方插件重定向。
PyMuPDF 会将错误消息放置在 sys.stderr
中,并以字符串 “mupdf:” 作为前缀。警告则会被内部存储,并可以通过 pymupdf.TOOLS.mupdf_warnings() 访问。还有一个函数可以清空这个存储。 ## 坐标
这是文档中最常用的术语之一。坐标通常指一对数字 (x, y)
,用于表示某个位置,比如矩形的角落(Rect),一个 Point 等等。这两个值通常是浮点数,但有些对象,比如图像,只允许它们为整数。
要实际 找到 坐标的位置,我们还需要知道 x
和 y
的 参考 点 - 换句话说,我们必须知道 (0, 0)
的位置在哪里。一旦知道了 (0, 0)
(“原点”),我们称之为 “坐标系统”。
文档处理中存在多个坐标系统。例如,PDF 页面和由其创建的图像的坐标系统是不同的。因此,我们需要方法来转换一个坐标系统到另一个(偶尔也需要反向转换)。这就是 Matrix 的任务。它是一个数学函数,类似于可以“乘”以点或矩形的因子,从而给出另一个坐标系统中相应的点/矩形。变换矩阵的逆矩阵可用于恢复变换。就像乘以某个因子,比如 3,可以通过将结果除以 3(或乘以 1/3)来恢复。
图像具有整数坐标的坐标系。原点 (0, 0)
是左上角。x
值必须在 range(width)
范围内,y
值必须在 range(height)
范围内。因此,如果我们向下移动,y
值会增加。每个图像只有有限数量的坐标,即 width * height
。图像中的位置也称为“像素”。
在 PDF 中,页面的原点 (0, 0)
位于其 左下角。而在 MuPDF 中,页面的原点 (0, 0)
位于其 左上角。
[外链图片转存中…(img-REgxR6q0-1718851590735)]
坐标是浮点数,并以 points 为单位,其中:
典型的文档页面大小包括 ISO A4 和 Letter。Letter 页面的尺寸为 8.5 x 11 英寸,对应 612 x 792 点。在 PDF 坐标系统中,Letter 页面的左上角因此具有坐标 (0, 792)
,因为y 轴向上。现在我们知道我们的文档大小,MuPDF 坐标系统的右下角坐标将是 (612, 792)
(对于 PDF,此坐标将是 (612, 0)
)。
理论上,PDF 页面上有无限多的坐标位置。然而,实际上,前 5 位小数足以保证合理的精度。
在 MuPDF 中,支持多种文档格式 - PDF 只是其中之一。图像也作为 MuPDF 中的文档进行支持(通常一页)。这也是为什么 MuPDF 使用坐标系,其原点 (0, 0)
是任何文档页面的 左上角 点。y 轴向下,与图像类似。在 MuPDF 中,坐标始终是浮点数,如 PDF 中一样。
例如,在 MuPDF(因此 PyMuPDF)中,矩形 Rect(0, 0, 100, 100)
是一个边长为 100 点的正方形(约为 1.39 英寸或 3.53 厘米)。其左上角是原点。为了在 PDF 和 MuPDF 之间切换坐标系,每个 Page 对象都有一个 Page.transformation_matrix
。其逆矩阵可用于计算矩形的 PDF 坐标。通过这种方式,我们可以方便地确定在 MuPDF 中的 Rect(0, 0, 100, 100)
与 PDF 中的 Rect(0, 692, 100, 792)
是相同的。参见以下代码片段:
>>> page = doc.new_page(width=612, height=792) # make new Letter page
>>> ptm = page.transformation_matrix
>>> # the inverse matrix of ptm is ~ptm
>>> pymupdf.Rect(0, 0, 100, 100) * ~ptm
Rect(0.0, 692.0, 100.0, 792.0)
脚注
您对此页面有任何反馈意见吗?
本软件按原样提供,不附带任何明示或暗示的保证。本软件在许可下分发,并且未经授权不得复制、修改或分发。有关更多信息,请参阅许可信息 artifex.com 或联系 Artifex Software Inc., 39 Mesa Street, Suite 108A, San Francisco CA 94129, United States。
本文档涵盖了所有版本直至 1.24.4。
[外链图片转存中…(img-Jmn2OXk1-1718851590735)] ## 图像变换矩阵
从版本 1.18.11 开始,某些文本和图像提取方法返回图像变换矩阵:Page.get_text()
和 Page.get_image_bbox()
。
变换矩阵包含关于如何将图像变换以适应文档页面上的矩形(其“边界框” = “bbox”)的信息。通过检查页面上图像的 bbox 和此矩阵,可以确定例如图像是否以缩放或旋转的方式显示在页面上。
图像尺寸与其页面上的 bbox 之间的关系如下:
使用原始图像的宽度和高度,
imgrect = pymupdf.Rect(0, 0, width, height)
shrink = pymupdf.Matrix(1/width, 0, 0, 1/height, 0, 0)
。
使用其缩放矩阵转换图像矩形,将得到单位矩形: imgrect * shrink = pymupdf.Rect(0, 0, 1, 1)
。
使用图像的 变换矩阵 “transform”,以下步骤将计算 bbox:
imgrect = pymupdf.Rect(0, 0, width, height)
shrink = pymupdf.Matrix(1/width, 0, 0, 1/height, 0, 0)
bbox = imgrect * shrink * transform
检查矩阵乘积 shrink * transform
将显示有关将图像矩形调整到页面上的 bbox 的所有信息:旋转、其边缘的缩放和原点的平移。让我们看一个例子:
>>> imginfo = page.get_images()[0] # get an image item on a page
>>> imginfo
(5, 0, 439, 501, 8, 'DeviceRGB', '', 'fzImg0', 'DCTDecode')
>>> #------------------------------------------------
>>> # define image shrink matrix and rectangle
>>> #------------------------------------------------
>>> shrink = pymupdf.Matrix(1 / 439, 0, 0, 1 / 501, 0, 0)
>>> imgrect = pymupdf.Rect(0, 0, 439, 501)
>>> #------------------------------------------------
>>> # determine image bbox and transformation matrix:
>>> #------------------------------------------------
>>> bbox, transform = page.get_image_bbox("fzImg0", transform=True)
>>> #------------------------------------------------
>>> # confirm equality - permitting rounding errors
>>> #------------------------------------------------
>>> bbox
Rect(100.0, 112.37525939941406, 300.0, 287.624755859375)
>>> imgrect * shrink * transform
Rect(100.0, 112.375244140625, 300.0, 287.6247253417969)
>>> #------------------------------------------------
>>> shrink * transform
Matrix(0.0, -0.39920157194137573, 0.3992016017436981, 0.0, 100.0, 287.6247253417969)
>>> #------------------------------------------------
>>> # the above shows:
>>> # image sides are scaled by same factor ~0.4,
>>> # and the image is rotated by 90 degrees clockwise
>>> # compare this with pymupdf.Matrix(-90) * 0.4
>>> #------------------------------------------------
下列 14 个内置字体名称 必须由每个 PDF 查看器 应用程序支持。它们可用作字典,将它们的全名和其缩写(小写)映射到完整的字体基本名称。在 PyMuPDF 中需要提供 字体名称 时,可以使用字典中的任何 键或值:
In [2]: pymupdf.Base14_fontdict
Out[2]:
{'courier': 'Courier',
'courier-oblique': 'Courier-Oblique',
'courier-bold': 'Courier-Bold',
'courier-boldoblique': 'Courier-BoldOblique',
'helvetica': 'Helvetica',
'helvetica-oblique': 'Helvetica-Oblique',
'helvetica-bold': 'Helvetica-Bold',
'helvetica-boldoblique': 'Helvetica-BoldOblique',
'times-roman': 'Times-Roman',
'times-italic': 'Times-Italic',
'times-bold': 'Times-Bold',
'times-bolditalic': 'Times-BoldItalic',
'symbol': 'Symbol',
'zapfdingbats': 'ZapfDingbats',
'helv': 'Helvetica',
'heit': 'Helvetica-Oblique',
'hebo': 'Helvetica-Bold',
'hebi': 'Helvetica-BoldOblique',
'cour': 'Courier',
'coit': 'Courier-Oblique',
'cobo': 'Courier-Bold',
'cobi': 'Courier-BoldOblique',
'tiro': 'Times-Roman',
'tibo': 'Times-Bold',
'tiit': 'Times-Italic',
'tibi': 'Times-BoldItalic',
'symb': 'Symbol',
'zadb': 'ZapfDingbats'}
与他们的义务相反,不是所有的 PDF 查看器都正确和完全支持这些字体 – 这对于 Symbol 和 ZapfDingbats 尤其如此。此外,字形(视觉)图像将针对每个阅读器具体化。
要查看这些字体如何使用,包括 内置 CJK 字体,请查看 Page.insert_font()
中的表格。
Adobe 发布的此 PDF 参考手册经常在本文档中引用。可以从 此处 查看和下载。
注意
长期以来,旧版本还可以在 此 链接下找到。看起来在 2021 年 10 月从网站上撤下了。早期(1.19.* 之前)版本的 PyMuPDF 文档曾参考过此文档。我们已经努力将对当前规范的引用替换为上面的规范。
当 PyMuPDF 对象和方法需要一个 Python 列表 的数值时,其他 Python 序列类型 也是允许的。如果 Python 类有一个 __getitem__()
方法,则称其实现了 序列协议。
这基本上意味着,你可以在这些情况下可以互换使用 Python 列表 或 元组,甚至 array.array、numpy.array 和 bytearray 类型。
例如,在以下任何一种方式中指定序列 "s"
s = [1, 2]
– 一个列表
s = (1, 2)
– 一个元组
s = array.array("i", (1, 2))
– 一个 array.array
s = numpy.array((1, 2))
– 一个 numpy 数组
s = bytearray((1, 2))
– 一个 bytearray
将使其在以下示例表达式中可用:
pymupdf.Point(s)
pymupdf.Point(x, y) + s
doc.select(s)
同样地,所有几何对象 Rect、IRect、Matrix 和 Point 也是如此。
因为所有的 PyMuPDF 几何类本身都是序列的特殊情况,所以它们(除了 Quad – 见下文)可以自由地用在可以使用数值序列的地方,例如作为 list()、tuple()、array.array() 或 numpy.array() 的参数。查看以下代码片段以查看其工作原理。
>>> import pymupdf, array, numpy as np
>>> m = pymupdf.Matrix(1, 2, 3, 4, 5, 6)
>>>
>>> list(m)
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]
>>>
>>> tuple(m)
(1.0, 2.0, 3.0, 4.0, 5.0, 6.0)
>>>
>>> array.array("f", m)
array('f', [1.0, 2.0, 3.0, 4.0, 5.0, 6.0])
>>>
>>> np.array(m)
array([1., 2., 3., 4., 5., 6.])
注意
四边形也是 Python 序列对象,长度为 4。然而,其项是point_like
,而不是数字。因此,上述评论不适用。
PyMuPDF 是 C 库 MuPDF 的 Python 绑定。尽管 MuPDF 的创建者已经付出了大量努力来模拟某种面向对象的行为,但他们确实无法克服 C 语言在这方面的基本缺陷。
另一方面,Python 非常清晰地实现了 OO 模型。PyMuPDF 与 MuPDF 之间的接口代码由两个基本文件组成:pymupdf.py和fitz_wrap.c。每个新版本都由优秀的 SWIG 工具创建。
当您使用 PyMuPDF 的对象或方法时,这将导致在pymupdf.py中执行一些代码,然后调用一些在fitz_wrap.c中编译的 C 代码。
因为 SWIG 在保持 Python 和 C 级别同步方面走了很长一段路,只要严格遵循一定的规则,一切都能正常工作。例如:在关闭(或删除或设置为None)所属文档之后,永远不要访问一个页面对象。或者,不那么明显的是:在执行文档方法select()、delete_page()、*insert_page()*等之后,永远不要访问页面或其任何子元素(链接或注释)。
但是仅仅停止访问无效对象是不够的:它们应该被完全删除,以释放 C 级资源(即分配的内存)。
这些规则的原因在于文档与其页面之间以及页面与其链接/注释之间存在层次化的二级一对多关系。为了保持一致的情况,上述任何操作都必须导致完全重置 - 在 Python 和 C 中同步进行。
SWIG 无法知道这一点,因此也不会执行。
因此,所需的逻辑已经内置到 PyMuPDF 中,如下所示。
程序员通常不会意识到这一点。然而,如果他试图访问无效的对象,将会引发异常。
无效的对象不能像使用 Python 语句del page或page = None等那样直接删除。相反,必须调用它们的*del*方法。
所有页面、链接和注释都有属性parent,指向拥有的对象。这是可以在应用程序级别检查的属性:如果obj.parent == None,则对象的父项已丢失,并且对其属性或方法的任何引用都将引发异常,通知此“孤立”的状态。
一个示例会话:
>>> page = doc[n]
>>> annot = page.first_annot
>>> annot.type # everything works fine
[5, 'Circle']
>>> page = None # this turns 'annot' into an orphan
>>> annot.type
<... omitted lines ...>
RuntimeError: orphaned object: parent is None
>>>
>>> # same happens, if you do this:
>>> annot = doc[n].first_annot # deletes the page again immediately!
>>> annot.type # so, 'annot' is 'born' orphaned
<... omitted lines ...>
RuntimeError: orphaned object: parent is None
这显示了级联效应:
>>> doc = pymupdf.open("some.pdf")
>>> page = doc[n]
>>> annot = page.first_annot
>>> page.rect
pymupdf.Rect(0.0, 0.0, 595.0, 842.0)
>>> annot.type
[5, 'Circle']
>>> del doc # or doc = None or doc.close()
>>> page.rect
<... omitted lines ...>
RuntimeError: orphaned object: parent is None
>>> annot.type
<... omitted lines ...>
RuntimeError: orphaned object: parent is None
注意
在上述关系之外的对象不包括在此机制中。例如,如果通过toc = doc.get_toc()创建了目录,然后关闭或更改文档,那么这不会也不能以任何方式更改变量toc。您有责任根据需要刷新此类变量。
Page.show_pdf_page()
该方法在当前(“包含”、“目标”)页面的指定矩形内显示另一个 PDF 文档的页面的图像。
Page.insert_image()
,此显示是基于矢量的,因此在缩放级别上保持准确。
Page.insert_image()
一样,显示的大小根据给定的矩形调整。
当前支持以下显示变体:
"keep_proportion"
控制是否保持纵横比(默认)。
"clip"
限制了源页面矩形的可见部分。默认为整个页面。"rotation"
将显示旋转一个任意角度(度)。如果角度不是 90 的整数倍,则如果也"keep_proportion"
为真,则可能只有 4 个角中的 2 个位于目标边界上。
"overlay"
控制是否将图像放在当前页面内容的顶部(前景,默认)或不放置在顶部(背景)。
用例包括(但不限于)以下内容:
这是使用 PDF **“表单 XObject”**完成的,请参阅 Adobe PDF 参考手册第 217 页的 8.10 节。在执行Page.show_pdf_page()
时,会发生以下事情:
resources
和contents
对象与目标文档一起复制,共同创建一个新的Form XObject,具有以下属性。此对象的 PDF xref
编号由该方法返回。/BBox
等于源页面的/Mediabox
/Matrix
等于单位矩阵。/资源
等同于源页面。这涉及“深拷贝”层次嵌套的其他对象(包括字体、图像等)。这里涉及的复杂性由 MuPDF 的嫁接[1]技术函数来处理。contents
对象的组合数据的精确副本。这个 Form XObject 仅在显示的源页面中执行一次。后续显示相同的源页面将跳过此步骤,仅为此对象创建“指针”Form XObjects(在下一步中完成)。
/BBox
等于源页面的/CropBox
(或"clip"
)。/Matrix
表示将/BBox
映射到目标矩形。/XObject
通过固定名称fullpage
引用前一个 Form XObject。/fullpage Do
。"oc"
参数已给出,则将其值分配给此 Form XObject 作为/OC
。resources
和contents
对象如下。/资源
的/XObject
字典中添加一个条目,名称为fzFrm
(n 选取得使该条目在页面上唯一)。"overlay"
,在页面的/Contents
数组之前或之后添加一个新对象,其中包含语句q /fzFrm<n> Do Q
。此设计方法确保:
"oc"
参数来单独控制源页面的可见性。
该方法在当前页面的指定矩形内显示另一个 PDF 文档的(“源”)页面图像。
Page.insert_image()
相比,此显示是基于矢量的,因此在缩放级别上保持准确。
Page.insert_image()
类似,显示的大小调整为给定的矩形。
当前支持以下显示变体:
"keep_proportion"
控制是否保持纵横比(默认)。
"clip"
限制源页面矩形的可见部分。默认为整个页面。"rotation"
按任意角度(度)旋转显示。如果角度不是 90 的整数倍,则如果也设置了"keep_proportion"
为真,则只有目标边框上的 2 个角可能会定位。
"overlay"
控制是否将图像放在当前页面内容的顶部(前景,默认)或不放置在其上(背景)。
使用情况包括(但不限于)以下内容:
这是使用 PDF **“Form XObjects”**完成的,请参阅 Adobe PDF References 第 8.10 节第 217 页。在执行Page.show_pdf_page()
时,会发生以下事情:
resources
和contents
对象被复制到目标文档,共同创建一个新的Form XObject,具有以下属性。此对象的 PDF xref
编号由该方法返回。/BBox
等于源页面的/Mediabox
。/Matrix
等于单位矩阵。/Resources
等于源页面的资源。这涉及到层次嵌套的其他对象(包括字体、图像等)的“深复制”。这里涉及的复杂性由 MuPDF 的嫁接技术函数[1]覆盖。contents
对象的组合数据的精确副本。这个 Form XObject 仅在每次显示源页面时执行一次。后续显示相同的源页面将跳过此步骤,并仅创建指向此对象的“指针”Form XObjects(在下一步完成)。
/BBox
等于源页面的/CropBox
(或"clip"
)。/Matrix
表示/BBox
到目标矩形的映射。/XObject
通过固定名称fullpage
引用前面的 Form XObject。/fullpage Do
。"oc"
参数给定,其值将分配给此 Form XObject 作为/OC
。resources
和 contents
对象现在修改如下。/Resources
的 /XObject
字典中添加一个条目,名称为 fzFrm
(选择 n 使得此条目在页面上唯一)。"overlay"
,在页面的 /Contents
数组前面或后面添加一个新对象,包含语句 q /fzFrm<n> Do Q
。这种设计方法确保了:
"oc"
参数,单独控制源页面的可见性。
自 MuPDF 版本 1.16 起,错误和警告消息可以通过官方插件进行重定向。
PyMuPDF 会将错误消息输出到 sys.stderr
,前缀为字符串 “mupdf:”。警告会被内部存储,并可通过 pymupdf.TOOLS.mupdf_warnings() 访问。还存在一个函数可以清空此存储。
这是文档中最常用的术语之一。一个坐标通常指的是一对数字 (x, y)
,表示某个位置,如矩形的角落(Rect)、Point 等。两个值通常是浮点数,但也有像图像这样的对象只允许它们是整数。
要实际找到坐标的位置,我们还需要知道 x
和 y
的参考点——换句话说,我们必须知道位置 (0, 0)
放置在哪里。一旦 (0, 0)
(“原点”)确定,我们就谈论一个“坐标系统”。
在文档处理过程中存在几种坐标系统。例如,PDF 页面和从中创建的图像的坐标系统是不同的。因此,我们需要方法来转换坐标,从一个系统到另一个系统(并且有时也需要反向转换)。这是一个矩阵的任务。它是一个数学函数,类似于一个因子,可以与一个点或矩形“相乘”,以给我们在另一个坐标系统中的对应点/矩形。变换矩阵的逆可以用来恢复变换。就像乘以某个因子,比如 3,可以通过将结果除以 3(或与 1/3 相乘)来恢复一样。
图像具有整数坐标的坐标系统。原点 (0, 0)
是左上角点。x
值必须在 range(width)
范围内,y
值在 range(height)
范围内。因此,y
值增加,如果我们向下移动。每个图像只有一个有限数量的坐标,即 width * height
。图像中的一个位置也称为“像素”。
在PDF中,页面的原点(0, 0)
位于其左下角。在MuPDF中,页面的原点(0, 0)
位于其左上角。
[外链图片转存中…(img-vmPvFaXc-1718851590736)]
坐标是浮点数,以**点(points)**为单位,其中:
典型的文档页面大小为ISO A4和Letter。Letter页面的大小为8.5 x 11 英寸,对应612 x 792 点。在PDF坐标系统中,Letter页面的左上角点的坐标因此是(0, 792)
,因为Y 轴向上指向。现在我们知道我们文档的大小,在MuPDF中,右下角的坐标将是(612, 792)
(对于PDF,这个坐标将是(612,0)
)。
从理论上讲,PDF页面上有无限多个坐标位置。然而,在实践中,至多前 5 位小数足以保证合理的精度。
在MuPDF中,支持多种文档格式 - PDF只是其中之一,总共有十几种其他格式。图像在MuPDF中也作为文档支持(因此通常只有一页)。这也是为什么MuPDF使用以坐标系,原点(0, 0)
是任何文档页面的左上角点。Y 轴向下指向,如同图像一样。MuPDF中的坐标无论如何都是浮点数,就像在PDF中一样。
例如,在MuPDF中的矩形Rect(0, 0, 100, 100)
(因此也适用于PyMuPDF),因此是一个边长为 100 点(= 1.39 英寸或 3.53 厘米)的正方形。它的左上角是原点。为了在PDF和MuPDF之间切换坐标系,每个 Page 对象都有一个Page.transformation_matrix
。它的逆可以用来计算矩形的 PDF 坐标。通过这种方式,我们可以方便地发现在MuPDF中的Rect(0, 0, 100, 100)
等同于PDF中的Rect(0, 692, 100, 792)
。请参阅以下代码片段:
>>> page = doc.new_page(width=612, height=792) # make new Letter page
>>> ptm = page.transformation_matrix
>>> # the inverse matrix of ptm is ~ptm
>>> pymupdf.Rect(0, 0, 100, 100) * ~ptm
Rect(0.0, 692.0, 100.0, 792.0)
脚注
这页有没有任何反馈?
此软件按原样提供,不带任何明示或暗示的担保。此软件根据许可证分发,未经明确授权不得复制、修改或分发。有关详细信息,请参阅artifex.com的许可信息或联系 Artifex Software Inc.,美国加利福尼亚州旧金山 Mesa 街 39 号 108A 套房。
本文档覆盖了所有版本直至 1.24.4。
[外链图片转存中…(img-x2zxKH5m-1718851590736)]
图像具有整数坐标系。原点(0, 0)
位于左上角。x
值必须在宽度范围
内,而y
值在高度范围
内。因此,如果我们向下移动,y
值将增加。对于每个图像,坐标仅有有限数量,即宽度 * 高度
。图像中的位置也称为“像素”。
在PDF中,页面的原点(0, 0)
位于其左下角。在MuPDF中,页面的原点(0, 0)
位于其左上角。
[外链图片转存中…(img-06tkDkAF-1718851590736)]
坐标是浮点数,以点为单位,其中:
典型的文档页面尺寸包括ISO A4和Letter。Letter页面的尺寸为8.5 x 11 英寸,对应612 x 792 点。在PDF坐标系统中,Letter页面的左上角点的坐标为(0, 792)
,因为y 轴向上。现在我们知道我们的文档大小,MuPDF中右下角的坐标将是(612, 792)
(对于PDF,此坐标将为(612,0)
)。
理论上,PDF页面上有无限多的坐标位置。然而,在实践中,前 5 位小数通常足以达到合理的精度。
在MuPDF中,支持多种文档格式 - PDF只是其中之一。图像也作为MuPDF中的文档被支持(通常每页一张)。这也是为什么MuPDF使用坐标系的原点(0, 0)
在任何文档页面上都是左上角的一个原因。y 轴向下,就像图像一样。在MuPDF中,坐标始终是浮点数,就像PDF中一样。
例如,MuPDF(因此也是PyMuPDF)中的一个矩形 Rect(0, 0, 100, 100)
实际上是一个边长为 100 点(= 1.39 英寸或 3.53 厘米)的正方形。其左上角是原点。要在 PDF 到 MuPDF 之间切换坐标系,每个 Page 对象都有一个 Page.transformation_matrix
。其逆矩阵可用于计算矩形的 PDF 坐标。通过这种方式,我们可以方便地发现在 MuPDF 中 Rect(0, 0, 100, 100)
与 PDF 中的 Rect(0, 692, 100, 792)
是相同的。参见以下代码片段:
>>> page = doc.new_page(width=612, height=792) # make new Letter page
>>> ptm = page.transformation_matrix
>>> # the inverse matrix of ptm is ~ptm
>>> pymupdf.Rect(0, 0, 100, 100) * ~ptm
Rect(0.0, 692.0, 100.0, 792.0)
脚注
你对本页面有任何反馈吗?
本软件按原样提供,不附带任何明示或暗示的担保。本软件以许可方式分发,未经许可,不得复制、修改或分发。请参考 artifex.com 获取许可信息,或联系美国加利福尼亚州旧金山市 Mesa 街 39 号 108A 套房,Artifex Software Inc. 获取更多信息。
本文档涵盖了所有版本,直至 1.24.4。
[外链图片转存中…(img-YkKEbmrz-1718851590736)]
本文记录了测量 PyMuPDF 性能的方法,以及用于比较的工具和示例文件。
下面的三个部分涉及不同的性能方面:
请注意,在所有情况下,实际处理 PDF 结构的速度并未直接测量:相反,时间记录还包括将文件写入操作系统文件系统的持续时间。这是不可避免的,因为除了 PyMuPDF 之外的工具不提供例如将图像创建步骤与将图像写入文件的后续步骤分离的选项。
因此,所有记录的时间都包括一个通用的面向操作系统的基本工作。因此,实际上每个工具的性能差异要比数字表明的大。
用于性能测试的八个文件集。每个文件我们都有以下信息:
名称 | 大小(字节) | 页数 | 目录大小 | 链接数 | KB/页 | 每页文本大小 | 备注 |
---|---|---|---|---|---|---|---|
adobe.pdf | 32,472,771 | 1,310 | 794 | 32,096 | 24 | 1,942 | 线性化,许多链接/书签 |
artifex-website.pdf | 31,570,732 | 47 | 46 | 2,035 | 656 | 3,538 | 图形导向 |
db-systems.pdf | 29,326,355 | 1,241 | 0 | 0 | 23 | 2,142 | |
fontforge.pdf | 8,222,384 | 214 | 31 | 242 | 38 | 1,058 | 文本和图形混合 |
pandas.pdf | 10,585,962 | 3,071 | 536 | 16,554 | 3 | 1,539 | 很多页 |
pymupdf.pdf | 6,805,176 | 478 | 276 | 5,277 | 14 | 1,937 | 文本导向 |
pythonbook.pdf | 9,983,856 | 669 | 198 | 1,953 | 15 | 1,929 | |
sample-50-MB-pdf-file.pdf | 52,521,850 | 1 | 0 | 0 | 51,291 | 23,860 | 单页,图形导向,文件体积大 |
注意
adobe.pdf 和 pymupdf.pdf 明显是文本导向的,artifex-website.pdf 和 sample-50-MB-pdf-file.pdf 是图形导向的。其他文件则是两者的混合。
在每个部分中,一组固定的 PDF 文件正在被一组工具处理。然而,每个性能方面使用的工具集合因其支持的工具特性而有所不同。
所有工具都是跨平台的,或者至少可以在 Windows 和 Unix/Linux 上运行。
工具 | 描述 |
---|---|
PyMuPDF | 本手册的工具。 |
PDFrw | 一个纯 Python 工具,被 rst2pdf 使用,具有与 ReportLab 的接口。 |
PyPDF2 | 一个功能丰富的纯 Python 工具集。 |
PDFMiner | 一个纯 Python 工具,用于从 PDF 中提取文本和其他数据。 |
XPDF | 一个带有多功能的命令行实用工具。 |
PikePDF | 类似于 PDFrw 的 Python 包,但基于 C++库 QPDF。 |
PDF2JPG | 专门用于将 PDF 页面渲染为 JPG 图像的 Python 包。 |
PDF 文件的读取速度和其内容解析的快慢如何?纯粹的解析性能无法直接比较,因为批处理实用工具总是一次性执行请求的任务,从头到尾完全执行。PDFrw 也对解析采取了惰性策略,意味着它只解析文档中任何时刻需要的那些部分。
因此,为了找到问题的答案,我们测量使用每个工具将 PDF 文件复制到输出文件的时间,不做其他操作。
这些是每个工具使用的 Python 命令:
PyMuPDF
import pymupdf
doc = pymupdf.open("input.pdf")
doc.save("output.pdf")
PDFrw
doc = PdfReader("input.pdf")
writer = PdfWriter()
writer.trailer = doc
writer.write("output.pdf")
PikePDF
from pikepdf import Pdf
doc = Pdf.open("input.pdf")
doc.save("output.pdf")
PyPDF2
pdfmerge = PyPDF2.PdfMerger()
pdfmerge.append("input.pdf")
pdfmerge.write("output.pdf")
pdfmerge.close()
观察
这些是我们在秒内的运行时发现,同时附带与 PyMuPDF 相比的基础速率摘要:
名称 | PyMuPDF | PDFrw | PikePDF | PyPDF2 |
---|---|---|---|---|
adobe.pdf | 1.75 | 5.15 | 22.37 | 374.05 |
artifex-website.pdf | 0.26 | 0.38 | 1.41 | 2.81 |
db-systems.pdf | 0.15 | 0.8 | 1.68 | 2.46 |
fontforge.pdf | 0.09 | 0.14 | 0.28 | 1.1 |
pandas.pdf | 0.38 | 2.21 | 2.73 | 70.3 |
pymupdf.pdf | 0.11 | 0.56 | 0.83 | 6.05 |
pythonbook.pdf | 0.19 | 1.2 | 1.34 | 37.19 |
sample-50-MB-pdf-file.pdf | 0.12 | 0.1 | 2.93 | 0.08 |
总计 | 3.05 | 10.54 | 33.57 | 494.04 |
| 与 PyMuPDF 相比的速率 | 1.0 | 3.5 | 11.0 | 162 | ## 文本提取
以下表格显示了纯文本提取持续时间。所有工具都使用了它们的最基本功能 - 即没有布局重新排列等。
观察
这些是我们的运行时发现,以秒为单位,以及与 PyMuPDF 相比的基本速率摘要:
名称 | PyMuPDF | XPDF | PyPDF2 | PDFMiner |
---|---|---|---|---|
adobe.pdf | 2.01 | 6.19 | 22.2 | 49.15 |
artifex-website.pdf | 0.18 | 0.3 | 1.1 | 4.06 |
db-systems.pdf | 1.57 | 4.26 | 25.75 | 42.19 |
fontforge.pdf | 0.24 | 0.47 | 2.69 | 4.2 |
pandas.pdf | 2.41 | 10.54 | 25.38 | 76.56 |
pymupdf.pdf | 0.49 | 2.34 | 6.44 | 13.55 |
pythonbook.pdf | 0.84 | 2.88 | 9.28 | 24.27 |
sample-50-MB-pdf-file.pdf | 0.27 | 0.44 | 8.8 | 13.29 |
总计 | 8.01 | 27.42 | 101.64 | 227.27 |
| 与 PyMuPDF 相比的速率 | 1.0 | 3.42 | 12.69 | 28.37 | ## 页面渲染
我们已经测试了 PyMuPDF 在 150 DPI 分辨率下的渲染速度,与 pdf2jpg 和 XPDF 进行比较,
这些是每个工具的使用 Python 命令:
PyMuPDF
def ProcessFile(datei):
print "processing:", datei
doc=pymupdf.open(datei)
for p in pymupdf.Pages(doc):
pix = p.get_pixmap(dpi=150)
pix.save("t-%s.png" % p.number)
pix = None
doc.close()
return
XPDF
pdftopng.exe -r 150 file.pdf ./
PDF2JPG
def ProcessFile(datei):
print("processing:", datei)
pdf2jpg.convert_pdf2jpg(datei, "images", pages="ALL", dpi=150)
return
观察
这些是我们的运行时发现,以秒为单位,以及与 PyMuPDF 相比的基本速率摘要:
名称 | PyMuPDF | XPDF | PDF2JPG |
---|---|---|---|
adobe.pdf | 51.33 | 98.16 | 75.71 |
artifex-website.pdf | 26.35 | 51.28 | 54.11 |
db-systems.pdf | 84.59 | 143.16 | 405.22 |
fontforge.pdf | 12.23 | 22.18 | 20.14 |
pandas.pdf | 138.74 | 241.67 | 202.06 |
pymupdf.pdf | 22.35 | 39.11 | 33.38 |
pythonbook.pdf | 30.44 | 49.12 | 55.68 |
sample-50-MB-pdf-file.pdf | 1.01 | 1.32 | 5.22 |
总计 | 367.04 | 646 | 851.52 |
与 PyMuPDF 相比的速率 | 1.0 | 1.76 | 2.32 |
对此页面有任何反馈吗?
此软件按原样提供,不附带任何明示或暗示的担保。此软件根据许可证分发,未经授权不得复制,修改或分发。有关更多信息,请参阅artifex.com的许可信息,或联系美国加利福尼亚州旧金山 Mesa Street 39 号 108A 套房的 Artifex Software Inc。
此文档涵盖了直到 1.24.4 的所有版本。
[外链图片转存中…(img-v2kodKdJ-1718851590737)] ## 使用的文件
一组八个文件用于性能测试。对于每个文件,我们有以下信息:
名称 | 大小(字节) | 页数 | 目录大小 | 链接数 | KB/页 | 文本大小/页 | 备注 |
---|---|---|---|---|---|---|---|
adobe.pdf | 32,472,771 | 1,310 | 794 | 32,096 | 24 | 1,942 | 线性化,许多链接 / 书签 |
artifex-website.pdf | 31,570,732 | 47 | 46 | 2,035 | 656 | 3,538 | 以图形为导向 |
db-systems.pdf | 29,326,355 | 1,241 | 0 | 0 | 23 | 2,142 | |
fontforge.pdf | 8,222,384 | 214 | 31 | 242 | 38 | 1,058 | 文本和图形的混合 |
pandas.pdf | 10,585,962 | 3,071 | 536 | 16,554 | 3 | 1,539 | 很多页 |
pymupdf.pdf | 6,805,176 | 478 | 276 | 5,277 | 14 | 1,937 | 以文本为导向 |
pythonbook.pdf | 9,983,856 | 669 | 198 | 1,953 | 15 | 1,929 | |
sample-50-MB-pdf-file.pdf | 52,521,850 | 1 | 0 | 0 | 51,291 | 23,860 | 单页,以图形为导向,文件大小较大 |
注
adobe.pdf 和 pymupdf.pdf 明显以文本为导向,artifex-website.pdf 和 sample-50-MB-pdf-file.pdf 以图形为导向。其他文件则是文本和图形的混合。
在每个部分中,同一固定的 PDF 文件集被一组工具处理。然而,针对每个性能方面使用的工具集会有所不同,这取决于支持的工具功能。
所有工具都是平台无关的,或者至少可以在 Windows 和 Unix / Linux 上运行。
工具 | 描述 |
---|---|
PyMuPDF | 本手册的工具。 |
PDFrw | 纯 Python 工具,被 rst2pdf 使用,具有与 ReportLab 的接口。 |
PyPDF2 | 具有大量功能集的纯 Python 工具。 |
PDFMiner | 用于从 PDF 中提取文本和其他数据的纯 Python 工具。 |
XPDF | 具有多个功能的命令行实用程序。 |
PikePDF | 与 PDFrw 类似的 Python 包,但基于 C++ 库 QPDF。 |
PDF2JPG | 专门用于将 PDF 页面呈现为 JPG 图像的 Python 包。 |
读取 PDF 文件并解析其内容以进行进一步处理的速度有多快?由于批处理工具总是一次性执行所请求的任务,从头到尾完全完成,因此无法直接比较解析性能。 PDFrw 也具有惰性解析策略,这意味着它只解析在任何时刻都需要的文档部分。
因此,为了找到问题的答案,我们测量了使用每个工具将 PDF 文件复制到输出文件所需的时间,并且不做其他任何操作。
这些是每个工具使用的 Python 命令:
PyMuPDF
import pymupdf
doc = pymupdf.open("input.pdf")
doc.save("output.pdf")
PDFrw
doc = PdfReader("input.pdf")
writer = PdfWriter()
writer.trailer = doc
writer.write("output.pdf")
PikePDF
from pikepdf import Pdf
doc = Pdf.open("input.pdf")
doc.save("output.pdf")
PyPDF2
pdfmerge = PyPDF2.PdfMerger()
pdfmerge.append("input.pdf")
pdfmerge.write("output.pdf")
pdfmerge.close()
观察
这些是我们的运行时间发现,以秒为单位,以及与 PyMuPDF 比较的基准速率摘要:
名称 | PyMuPDF | PDFrw | PikePDF | PyPDF2 |
---|---|---|---|---|
adobe.pdf | 1.75 | 5.15 | 22.37 | 374.05 |
artifex-website.pdf | 0.26 | 0.38 | 1.41 | 2.81 |
db-systems.pdf | 0.15 | 0.8 | 1.68 | 2.46 |
fontforge.pdf | 0.09 | 0.14 | 0.28 | 1.1 |
pandas.pdf | 0.38 | 2.21 | 2.73 | 70.3 |
pymupdf.pdf | 0.11 | 0.56 | 0.83 | 6.05 |
pythonbook.pdf | 0.19 | 1.2 | 1.34 | 37.19 |
sample-50-MB-pdf-file.pdf | 0.12 | 0.1 | 2.93 | 0.08 |
总计 | 3.05 | 10.54 | 33.57 | 494.04 |
与 PyMuPDF 比较的速率 | 1.0 | 3.5 | 11.0 | 162 |
以下表格显示了纯文本提取持续时间。所有工具均使用其最基本的功能 - 即没有布局重新排列等。
观察
这些是我们的运行时间发现,以秒为单位,以及与 PyMuPDF 比较的基准速率摘要:
名称 | PyMuPDF | XPDF | PyPDF2 | PDFMiner |
---|---|---|---|---|
adobe.pdf | 2.01 | 6.19 | 22.2 | 49.15 |
artifex-website.pdf | 0.18 | 0.3 | 1.1 | 4.06 |
db-systems.pdf | 1.57 | 4.26 | 25.75 | 42.19 |
fontforge.pdf | 0.24 | 0.47 | 2.69 | 4.2 |
pandas.pdf | 2.41 | 10.54 | 25.38 | 76.56 |
pymupdf.pdf | 0.49 | 2.34 | 6.44 | 13.55 |
pythonbook.pdf | 0.84 | 2.88 | 9.28 | 24.27 |
sample-50-MB-pdf-file.pdf | 0.27 | 0.44 | 8.8 | 13.29 |
总计 | 8.01 | 27.42 | 101.64 | 227.27 |
与 PyMuPDF 比较的速率 | 1.0 | 3.42 | 12.69 | 28.37 |
我们已经在分辨率为 150 DPI 的情况下测试了 PyMuPDF 与 pdf2jpg 和 XPDF 的渲染速度,
这些是每个工具使用的 Python 命令:
PyMuPDF
def ProcessFile(datei):
print "processing:", datei
doc=pymupdf.open(datei)
for p in pymupdf.Pages(doc):
pix = p.get_pixmap(dpi=150)
pix.save("t-%s.png" % p.number)
pix = None
doc.close()
return
XPDF
pdftopng.exe -r 150 file.pdf ./
PDF2JPG
def ProcessFile(datei):
print("processing:", datei)
pdf2jpg.convert_pdf2jpg(datei, "images", pages="ALL", dpi=150)
return
观察
这些是我们的运行时间发现,以秒为单位,以及与 PyMuPDF 比较的基准速率摘要:
名称 | PyMuPDF | XPDF | PDF2JPG |
---|---|---|---|
adobe.pdf | 51.33 | 98.16 | 75.71 |
artifex-website.pdf | 26.35 | 51.28 | 54.11 |
db-systems.pdf | 84.59 | 143.16 | 405.22 |
fontforge.pdf | 12.23 | 22.18 | 20.14 |
pandas.pdf | 138.74 | 241.67 | 202.06 |
pymupdf.pdf | 22.35 | 39.11 | 33.38 |
pythonbook.pdf | 30.44 | 49.12 | 55.68 |
sample-50-MB-pdf-file.pdf | 1.01 | 1.32 | 5.22 |
总计 | 367.04 | 646 | 851.52 |
与 PyMuPDF 比较的速率 | 1.0 | 1.76 | 2.32 |
你对这个页面有什么反馈吗?
此软件按原样提供,不提供任何明示或暗示的保证。此软件根据许可协议分发,未经许可明确授权,不得复制、修改或分发。请参阅artifex.com上的许可信息,或联系美国加利福尼亚州旧金山市 94129 Mesa 街 39 号 108A 套房的 Artifex Software Inc. 获取更多信息。
本文档涵盖了所有版本,直至 1.24.4。
[外链图片转存中…(img-h34TQaNr-1718851590737)]
1.24.4 版本变更(2024-05-16)
utils.do_links()
崩溃问题。
page_merge()
中的错误。
1.24.3 版本变更(2024-05-09)
pymupdf
。fitz
仍支持向后兼容。
Page.remove_rotation()
:新功能,将页面旋转设置为零但保持外观。1.24.2 版本变更(2024-04-17)
fitz_old
可用)。
Document.bake()
:新功能,使注释/字段内容永久化。
Page.cluster_drawings()
:新功能,根据它们的几何接近性识别彼此属于的绘图项目(即矢量图形或线条艺术)。
Page.apply_redactions()
:添加了新参数text
。
Document.subset_fonts()
:使用 MuPDF 的 pdf_subset_fonts()
替代 PyMuPDF 的代码。
1.24.1 版本(2024-04-02)的变更
Document.save()
, Document.ez_save()
和 Document.write()
现在支持新参数 use_objstm
, compression_effort
和 preserve_metadata
。
1.24.0 版本(2024-03-21)的变更
apply_redactions()
删除了注释框外的文本。
get_drawings
的项缺少 h 路径操作符的行。
page.get_text()
对一些字符返回十六进制文本。
get_pixmap
方法在一页上卡住且永远运行。
版本 1.23.26(2024-02-29)中的更改
版本 1.23.25(2024-02-20)中的更改
PIPCL_PYTHON_CONFIG
。版本 1.23.24(2024-02-19)中的更改
sudo pip install
而不是 venv 测试系统安装。版本 1.23.23(2024-02-18)中的更改
pdf_rearrange_pages()
改进了 Document.select()
。这是对所需操作更完整(且更快速)的实现,不仅会重新排列页面,还会对目录、链接到已删除页面的链接以及可选内容定义中受影响的条目进行相关更改。
TextWriter.appendv()
:添加了 small_caps
参数。
Document.insert_image()
。
版本 1.23.22(2024-02-12)中的更改
fz_image_size()
的使用。版本 1.23.21(2024-02-01)中的更改
3112 https://github.com/pymupdf/PyMuPDF/pull/3112>
_:修复 pdf_add_stream 元数据错误。
TextPage
中缺少 .parent
成员的问题,从 Annot.get_textpage()
中。
Page.add_widget()
中的错误。
版本 1.23.20(2024-01-29)中的更改
Document.get_toc()
的速度。版本 1.23.19(2024-01-25)中的更改
Font.bbox
属性。
版本 1.23.18(2024-01-23)中的更改
Annot.file_info()
如果没有 Desc
项的问题。
版本 1.23.17(2024-01-22)的变更
Page.links()
中的 bug(PR #3075)。
Page.get_bboxlog()
在使用层时的 bug。
scripts/
和 tests/run_compound.py
。
版本 1.23.16(2024-01-18)的变更
版本 1.23.15(2024-01-16)的变更
pix.set_pixel
在 c.append( ord(i))
方面存在问题。Page.find_tables()
的文档。版本 1.23.14(2024-01-15)的变更
Page.get_drawings()
中的“derotated pages” 中有效的 “re” 矩形。版本 1.23.13(2024-01-15)的变更
Rect.height
和 Rect.width
以确保不返回负值。
TextPage.extractIMGINFO()
返回的 dictkey_yres
值。
版本 1.23.12(2024-01-12)的变更
Page.get_text
对于 ‘parent’ 抛出属性错误。版本 1.23.11(2024-01-12)的变更
Pixmap.yres()
。
版本 1.23.10(2024-01-12)的变更
Page.delete_image()
。版本 1.23.9(2024-01-11)的变更
import fitz_old as fitz
使用旧的“经典”实现。
github.com/pymupdf/PyMuPDF/discussions/2680
Page.derotation_matrix
返回元组而非 Matrix,基于 rebase 的实现
apply_redactions()
时出现的 ZeroDivisionError: float division by zero
apply_redactions()
移动文本
annot.next
抛出 AttributeError
clean_contents
时发生段错误
Page.insert_htmlbox()
。
add_redact_annot()
问题。
Page.rotation()
在非 PDF 文档中返回 0 而非抛出异常。
fitz.pymupdf_version_tuple
- 之前设置为 mupdf 版本。
flake8
添加到 scripts/gh_release.py:test_packages
中。
scripts/test.py
以帮助调查 MuPDF 问题。
1.23.8 版本变更(2023-12-19)
Page.insert_htmlbox()
:使用 Story 的新的、更强大的替代Page.insert_textbox()
或TextWriter.fill_textbox()
,新增。
Story.fit*()
:用于将 Story 安装到扩展的矩形中的新方法。
Story.write_with_links()
:新增对外部链接的支持。
Document.language()
:修复为使用 MuPDF 的新mupdf.fz_string_from_text_language2()
。
Document.subset_fonts()
- 修复。
Archive._add_treeitem()
方法。
fitz_new.__doc__
,内容包含了 PyMuPDF 和 Python 版本信息,以及操作系统名称。
(*args, **kwargs)
在 API 中,现在明确指定关键字参数。
button_states()
指向间接对象时返回 None 的错误。
fitz.css_for_pymupdf_font()
的测试(使用包pymupdf-fonts
)。
tests/README.md
。
版本 1.23.7 (2023-11-30) 中的更改:
scripts/test.py
,用于 PyMuPDF git 检出的简单构建+测试。
fitz.pymupdf_version_tuple
,例如 (1, 23, 6)
。
mupdf_warnings()
返回的警告中包含任何尾随的 ... 重复 <N> 次...
文本(仅 rebase)。
1.23.6 版本变更(2023-11-06)
1.23.5 版本变更(2023-10-11)
版本 1.23.4(2023-09-26)中的更改
版本 1.23.3(2023-08-31)中的更改
版本 1.23.2(2023-08-28)中的更改
版本 1.23.1(2023-08-24)中的更改
import fitz
失败,出现ImportError: libcrypt.so.2: cannot open shared object file: No such file or directory
。
incompatible architecture
错误。
版本 1.23.0(2023-08-22)中的更改
find_tables()
到 Page 对象。
这允许在任何支持的文档页面上定位表格,并通过单元格提取表格内容。
fitz_new
。它可以用作import fitz_new as fitz
的直接替换。
PyMuPDFb
的 wheel 中,pip 将自动安装它。
这是为了节省空间在 pypi.org 上 - 一个完整的发布只需要一个PyMuPDFb
wheel 对于每个操作系统。
/Contents
清理。
我们需要将 pdf_filter_options::no_update
设置为零。
get_tessdata()
。
/Annot
数组。
在方法 Document.insert_pdf
中复制页面注释时,我们之前未检查 /Annots
数组成员的有效性。对于故障成员(如 null 或非字典项),这可能导致不必要的异常。此修复实现了更多的检查并跳过这些数组项。
/Annots
数组时,避免方法 insert_pdf()
中的异常。
{}
。这要求注释 .update()
方法做出相应的更改,特别是对于虚线和边框宽度。
set_rect
限制为适用的注释类型。
我们之前在 set_rect()
方法中未能充分排除不适用的注释类型。现在让 MuPDF 捕获不支持的注释,并在这些情况下返回 False
。
page.get_texttrace()
中错误地计算了字体大小。
计算字体大小时我们使用了最终文本转换矩阵,而应该使用 span->trm
。这里进行了修正。
pdf_lookup_anchor()
已移除。
fill_textbox
以更好地尊重 rect.width
。
fill_textbox
中的 norm_words
函数在其最后一个循环中存在 bug,当实际测量 n 个字符的宽度时,会附加 n+1 个字符。这导致当您尝试写入一个主要由“宽”字母(M,m,W,w…)组成的单词时,会导致写入的文本超出给定的矩形框。
修复仅仅将 n+1 替换为 n 的问题。
script_focus
和 script_blur
选项。
1.22.5 版本变更 (2023-06-21):
MuPDF-1.22.2
。
Annot.border
属性新增了clouds
项,方法Annot.set_border()
支持相应的clouds
参数。
/Locked
关键字。现在可以提取和设置/OCProperties
内部的数组。
tessdata
的支持。新函数get_tessdata()
可以定位语言支持文件夹,如果安装了 Tesseract。
版本 1.22.3(2023-05-10)中的更改
MuPDF-1.22.0
。
版本 1.22.2(2023-04-26)中的更改
MuPDF-1.22.0
。
版本 1.22.1(2023-04-18)中的更改
MuPDF-1.22.0
。
版本 1.22.0 中的变更 (2023-04-14)
MuPDF-1.22.0
。
page.add_highlight_annot(start=pointa, stop=pointb)
无效
pixmap.tint_with()
的文档错误
apply_redactions()
将 pdf 文本移动到删除后
Page.delete_image()
| 对象没有属性 is_image
Story.element_positions()
中会静默退出
mupdf_display_errors
不适用于 Pixmap
Annot.get_text("words")
- 不返回第一行单词
Page.get_text(“dict”)
和 Fitz.get_page_images()
返回的图像格式/数据不同
Document
方法 has_xref_streams()
和 has_old_style_xrefs()
,因为 MuPDF 中的相应方法已被删除。
Document
方法和属性以获取/设置 /PageMode
、/PageLayout
和 /MarkInfo
。
Document
属性 version_count
,其中包含增量保存的次数加一。
Document
属性 is_fast_webaccess
,用于指示文档是否是线性化的。
DocumentWriter
现在是一个上下文管理器。
Pixmap
JPEG 输出的支持。
get_drawings()
: 添加了可选的 extended
参数。
fitz.Page.get_texttrace()
等的数据可能会稍微更改,例如 linewidth
值。
fitz/
目录的当前目录,则向 stderr
输出警告,因为这可能会破坏对 fitz
模块的导入。例如,如果尝试在当前目录是 PyMuPDF 检出时使用 fitz
,就会发生这种情况。
insert_file()
文档。
get_bboxlog()
: 向 get_bboxlog()
添加了可选的 layers
。
Page.get_texttrace()
: 添加了新的字典键 layer
,表示可选内容组的名称。
changes.txt
和 docs/changes.rst
的重复。
pyproject.toml
文件以改善使用 pip 等构建的过程。版本 1.21.1 中的更改(2022-12-13)
MuPDF-1.21.1
。
Document.save()
的 owner_pw
和 user_pw
存在缓冲区溢出漏洞
fitz.py
中的段错误
PyMuPDF 1.21.0
中 Document.save
的垃圾参数不起作用
1.21.0
中的无效大小
SystemError: <built-in function Page_get_texttrace>
返回带有错误设置的结果。
1.21.0
无法构建到系统 libmupdf
的问题
Archive::Archive
定义两次
Page.replace_image()
和 Page.delete_image()
。
1.21.0 版本变更(2022-11-8)
MuPDF-1.21.0
。
Document.delete_pages()
拒绝关键字参数。
page.apply_redactions()
中的访问冲突错误。
fontname="Helvetica"
添加文本可能会静默失败。
draw_rect()
:如果未指定颜色,则不会遵守宽度。
subset_fonts()
:现在可以静音输出。
clean=True
保存时出现分段错误。
pdfocr_save()
硬崩溃。
get_drawings()
时发生分段错误。
get_text()
文档中,block_no
和block_type
被错误地交换。
set_name()
和set_rect()
中处理异常的问题。
swig-python
以解决#875。
版本 1.20.2 中的变更
MuPDF-1.20.3
。
MuPDF-1.20.3
中已修复。)
docs/installation.rst
中改进了有关从源代码构建的信息。
pyJM_MEMORY` in ``docs/tools.rst
。
docs/app3.rst
中对 PDF 参考手册的链接。
docs/faq.rst
移动到单独的docs/recipes-*
文件中。
installation/
docs/wheelnames.txt
版本 1.20.1 中的变更
linkDest()
中对re.match()
的调用存在问题,这在 1.20.0 中引入。
get_drawings()
和get_cdrawings()
之前总是以closePath=False
返回。
.txt
文件重命名为.rst
后缀。
1.20.0 版本变更
本次发布使用了MuPDF-1.20.0
,发布日期为 2022-06-15。
#<int>,<int>,<int>
更改为#page=<int>&zoom=<float>,<float>,<float>
。tests/test_insertpdf.py
中,使用新的参考输出joined-1.20.pdf
。我们还检查新的输出值是否与旧的大致相同。pdf_graft_map
泄漏问题。还修复了一个由于不正确释放底层 fz_document 而导致的 SEGV 问题。
Annotation.get_pixmap()
的所有权。
构建/发布流程的变更:
setup.py
进行了各种更改,以根据需要下载所需的 MuPDF 发布版。有关详细信息,请参阅 setup.py 开头的注释。
.github/workflows/build_wheels.yml
来控制在 Github 上构建轮子。
1.19.6 版本变更
Page.get_textpage()
创建的 TextPage 现在将正确释放(去除内存泄漏)。
EmptyFileError
- 当尝试从空文件或零长度内存创建文档 (fitz.open()
) 时引发。FileDataError
- 当 MuPDF 遇到不可恢复的文档结构问题时引发。Page.load_widget()
,给定 PDF 字段的 xref。
pdfcolor
,其中包含约 500 种 PDF 颜色值,以小写颜色名称作为键。
TEXTFLAGS_WORDS
用于page.get_text("words")
。参见文本提取标志默认值。
Page.annots()
和 Page.widgets()
,以检测和防止在迭代器循环中(通过Document.reload_page()
)非法重新加载页面。这将降低解释器。记录了在适当设计的循环内进行注释和小部件大规模更新的干净方式。
Document.update_stream()
以始终接受流更新 - 无论 xref 后面的字典对象是否已经是流。因此,以前的new
参数现在被忽略,并将在 v1.20.0 中删除。
版本 1.19.5 变更
"null"
对象。
fz_drop_document()
调用不足导致的。这也修复了#1550。
point_like
方面的几个未记录问题。
Page.get_texttrace()
计算字符 bbox 时的未记录错误。
image_properties()
返回的字典项:orientation
和transform
报告自然图像方向(EXIF 数据)。
Document.xref_copy()
。它可以使目标 PDF 对象成为源对象的精确副本。
版本 1.19.4 变更
/ArtBox
, /BleedBox
, /TrimBox
。
TESSDATA_PREFIX
,用于轻松检查 OCR 支持。
Document.xref_set_key()
,使字典键如果设置为值 "null"
将被物理删除。
Document.extract_font()
可选择返回字典(而非元组)。
版本 1.19.3 中的变更
此补丁版本对 Pixmap 进行了一些重要修复和一些小改进。
Document.insert_pdf()
时文件句柄增长问题的方法。
Document.insert_pdf()
时内存增长问题的方法。
Pixmap.color_topusage()
用于确定最常用颜色的份额。解决了 #1397。
Pixmap.warp()
,从位图内部的任意凸四边形生成新位图。
Annot.irt_xref
和 Annot.set_irt_xref()
用于查询或设置注释的 /IRT
(“响应于”)属性。实现 #1450。
Rect.torect()
和 IRect.torect()
,用于计算将矩形转换为给定其他矩形的矩阵。
Pixmap.color_count()
还会返回每种颜色的计数。
Page.get_texttrace()
方法,以便在 span["dir"] != (1, 0)
时也返回正确的跨度和字符边界框。
版本 1.19.2 变更
此补丁版本对 Page.get_drawings()
进行了轻微改进,同时修复了一些重要问题。
Page.get_text()
的 “words” 和 “dict” 选项返回的行号不一致的问题。
recover_span_quad()
中对 "rawdict"
跨度的检查已正常工作。
Page.show_pdf_page()
中矩形无限性检查的问题。
Page.get_drawings()
和 Page.get_cdrawings()
方法,以返回矩形覆盖的区域方向指示器。这实现了 #1355。此外,矩形和四边形的识别率显著提高。
flags
选项 TEXT_MEDIABOX_CLIP
默认设置为打开状态。该位控制自动抑制所有完全位于页面媒体框外的字符(在文档类型支持的范围内)。这消除了需要使用 clip=page.rect
或类似选项来省略可见区域外文本的需求。
"dpi"
参数到 Page.get_pixmap()
和 Annot.get_pixmap()
方法。当给定时,忽略 "matrix"
参数,创建一个具有所需每英寸点数的 Pixmap。
Pixmap.is_monochrome
和 Pixmap.is_unicolor
,允许快速检查位图属性。解决了 #1397 的问题。
Pixmap.color_count()
以确定位图中唯一颜色的数量。
Document.update_stream()
的布尔参数 "compress"
。解决了 #1408 的问题。
版本 1.19.1 变更
这是支持 MuPDF v1.19.0 的第一个补丁版本。除了一个 bug 修复外,还包括 OCR 支持的重要改进以及对提取文本进行排序到标准阅读顺序“从左上到右下”的选项。
(x0, y0)
坐标。
Page.get_textpage_ocr()
:现在支持参数dpi
来控制 OCR 质量。还可以选择是对整页进行 OCR 还是仅对页面显示的图像进行 OCR。
Page.get_drawings()
和Page.get_cdrawings()
,以自动将颜色转换为 RGB 颜色元组。实现了#1332。类似的更改也应用于Page.get_texttrace()
。
Page.get_text()
以支持参数sort
。如果设置为True
,输出将方便地排序。
1.19.0 版本的变更
这是支持 MuPDF 1.19.*的第一个版本,发布于 2021-10-05。与前一个版本 1.18.*相比,引入了许多新功能。
PyMuPDF 现在已经支持了集成的 Tesseract OCR 支持,这在 MuPDF v1.18.0 中已经存在。
"tessdata"
文件夹的位置,其中存储了其语言支持数据。此位置必须作为环境变量TESSDATA_PREFIX
可用。
新的 MuPDF 功能是记录 PDF 更新,这也得到了 PyMuPDF 版本的支持。更改可能被记录、回滚或重播,允许实现对 PDF 文档完整性的全新控制级别,类似于现代数据库系统中的功能。
第三个功能(与新 MuPDF 版本无关)包括检测页面对象何时覆盖或隐藏彼此。例如,现在可以看到文本被绘图或图像覆盖。
"no_new_id"
的参数到Document.save()
/ Document.tobytes()
方法中。使用它来抑制更新 PDF 文档的第二项/ID
,在 PDF 中表示原始文件已被更新。如果 PDF 中还没有/ID
,则也不会创建新的/ID
。
Document.journal_enable()
及相关方法。
Pixmap.pdfocr_save()
和 Pixmap.pdfocr_tobytes()
,生成包含 OCR 文本层的 PNG 图像的单页 PDF。
Page.get_textpage_ocr()
方法,用于执行页面的光学字符识别,然后将结果提取并与“普通”页面内容一起存储在 TextPage 中。在后续的文本提取和文本搜索中使用或重复使用此对象,以避免多次努力。已扩展现有的文本搜索和文本提取方法以支持单独创建的 textpage — 请参阅下一项。
textpage
的参数到文本提取和文本搜索方法中。这允许重复使用之前创建的 TextPage,从而实现显著的运行时优势——这对于新的 OCR 功能尤为重要。但“普通”的文本提取也能从中受益。
Page.get_texttrace()
方法,提供低级文本字符属性的技术方法。它以前是一个私有方法,但作者认为现在它已经足够成熟,可以正式提供。它特别包括一个“序列号”,指示绘制文本的页面外观构建操作。
Page.get_bboxlog()
方法,提供页面对象(如文本、图像或绘图)的矩形列表。其重要性在于其顺序:索引较低的矩形覆盖或隐藏了其后的区域。
Page.get_drawings()
和 Page.get_cdrawings()
,现在包括一个表示页面外观构建操作创建的“序列号”。
版本 1.18.18 / 1.18.19 的变更
Pixmap.samples
的失败已在新版本 1.18.19 中进行了热修复。
zoom
值。
Page.get_image__bbox()
方法中正确计算变换矩阵。
Page.get_textbox()
中返回工件字符。
Page.get_drawings()
,Page.get_cdrawings()
。
版本 1.18.17 的变更
本版本的重点是对选定功能的主要性能改进。
Document.get_page_images()
及其相关方法中使用不存在的页码不再导致段错误。
Page.get_drawings()
,现在区分“描边”、“填充”和组合路径。现在支持包含多个矩形(即“re”项)的路径。提取“剪辑”路径现在作为选项可用。
Page.get_cdrawings()
,性能优化版本的Page.get_drawings()
。
Pixmap.samples_mv
,像素图像素区域的memoryview。不会复制,因此始终访问该区域的当前状态。
Pixmap.samples_ptr
,Python 中一个指向像素图像素区域的“指针”。可以大大加快创建(速度提高 800+倍)Qt 图像的速度。
1.18.16 版本变更
clip
时,文本搜索结果现在应该是正确的。
Link.flags
和Link.set_flags()
到 Link 类。实现增强请求 #1187。
TextWriter.fill_textbox()
的输出,以预测给定文本在文本框中占据的行数。
fitz
CLI 模块的子命令gettext
的文本输出支持。最重要的是,现在支持原始物理文本布局的再现。
1.18.15 版本变更
Annot.update()
中的fill_color=[]
参数以及Annot.set_colors()
中的fill=[]
。
Document.subset_fonts()
:修复了某些字体的字符宽度错误的问题。
Page.get_text()
和其他与文本提取相关的方法:更改了 TextPage flags
参数的默认值。现在保留所有空白和连字。
fitz.detTextlength
现在已正确定义。
Document.subset_fonts()
现在将正确地前缀字体子集,符合 PDF 规范的六个大写字母标签。
Widget.button_states()
,返回按钮类型字段在设置为“on”或“off”时可能具有的值。
small_caps
反映出来。
版本 1.18.14 变更
Page.insert_image()
:如给定,则在哈希计算中包括图像掩码。
Pixmap.getPNGdata
添加到Pixmap.tobytes()
的别名中。
Page.get_drawings()
返回。
TextWriter.fill_textbox()
输出文本时偶尔导致循环的内部错误。
Font.char_lengths()
,返回字符串的字符宽度元组。
Document.delete_pages()
。现在可以指定序列(列表、元组或范围),并且可以使用 Python 的del
语句。在后一种情况下,也接受 Python 的切片。
Document.del_toc_item()
,禁用 TOC 中的单个项目:以前是移除标题文本,现在支持视图器显示整个项目为灰色。
版本 1.18.13 变更
Page.get_image_bbox()
。
Document.xref_get_keys()
,Document.xref_get_key()
和Document.xref_set_key()
。
Page.insert_image()
。
Page.get_image_rects()
,这是 Page.get_image_bbox()
的改进版本。
Document.delete_pages()
以支持多种指定要删除页面的方法。实现了 #1042。
Page.insert_image()
还接受文件中现有图像的交叉引用。这允许在页面之间“复制”图像,并且支持极快的多次插入。
Page.insert_image()
还接受整数参数 alpha
。用于性能改进。
Pixmap.set_alpha()
以支持使用其 alpha 值预乘颜色和设置特定颜色为完全透明(例如白色)。
Document.embfile_add()
自动设置创建和修改日期时间。对应地,Document.embfile_upd()
自动维护修改日期时间(PDF 键 /ModDate
),并且 Document.embfile_info()
相应地报告这些数据。此外,通过其 xref
,还包括了嵌入文件的相关“集合项”,这支持开发 PDF 组合应用。
版本 1.18.11 / 1.18.12 中的更改
Page.get_xobjects()
提供了 Document.get_page_xobjects()
的结果。
Page.get_image_info()
提供了页面上所有图像的元信息。
Tools.mupdf_display_warnings()
允许设置开启/关闭 MuPDF 生成的警告显示。默认为关闭。
Document.ez_save()
是 Document.save()
的方便别名,具有一些不同的默认设置。
Page.get_image_bbox()
和Page.get_text()
的 DICT、JSON、RAWDICT 和 RAWJSON 变体。
1.18.10 版本更改
DisplayList.get_pixmap()
和DisplayList.get_textpage()
添加了旧别名。
Document.scrub()
稳定移除 JavaScript 对象。
TextWriter.fill_textbox()
中移除了一个循环。
Document.xref_get_keys()
和Document.xref_get_key()
,还允许访问 PDF 尾部字典。可以通过将 xref 编号参数设置为-1
来实现。
Page.get_text()
选项“dict”和“rawdict”提取的文本行、跨度和字符的四边形函数。参见recover_quad()
及相关函数。
Tools.unset_quad_corrections()
以抑制字符四边形校正(偶尔对错误字体需要)。
1.18.9 版本更改
Tools.set_subset_fontnames()
。
pathlib.Paths
作为文件名也可以创建位图。
Document.subset_fonts()
:文本不再被重写,因此保留所有原始属性,如隐藏或由可选内容机制控制。
TextWriter.fill_textbox()
,TextWriter.append()
。这些方法现在接受一个新的布尔参数 right_to_left
,默认为 False。实现了请求 #897。
TextWriter.fill_textbox()
以返回未适合给定矩形的所有文本行。还将 warn
参数的默认值更改为在溢出情况下不再打印警告消息。
recover_quad()
,用于计算跨度的四边形。这个函数可用于正确标记使用 Page.get_text()
的“dict”或“rawdict”选项提取的文本。
1.18.8 版本变更
这只是一个修复 bug 的版本。我们提前发布是因为这些功能可能被广泛使用。
1.18.7 版本变更
Document.subset_fonts()
,根据 PDF 中文本使用情况减小合格字体的大小。实现了请求 #855。
Document.convert_to_pdf()
现在还支持 PDF 文档。
Document.write
重命名为 Document.tobytes()
以增强清晰度。但废弃的名称仍然可用一段时间。
Document.tobytes()
现在支持线性化 PDF 输出。Document.save()
现在也支持向 Python 文件对象写入。此外,open 函数现在也支持 Python 文件对象。
Document.get_page_labels()
返回 PDF 的页面标签定义列表。
Document.has_annots()
和 Document.has_links()
用于检查 PDF 中是否存在这些对象类型。
Document.xref_get_keys()
列出对象xref
的键,Document.xref_get_key()
返回键的类型和内容,以及Document.xref_set_key()
修改键的值。
thumbnails
到Document.scrub()
,以允许删除页面缩略图图像。
我们继续将方法和属性从*“mixedCase”重命名为“snake_case”*的过程。文档通常仅提及新名称,但旧的弃用名称在一段时间内仍然可用。
版本 1.18.6 中的更改
clip=None
,则文本搜索和文本提取将完全不进行矩形包含检查。
Page.get_label()
返回页面标签,Document.get_page_numbers()
返回具有指定标签的所有页面编号,Document.set_page_labels()
添加或更新 PDF 的页面标签定义。
注意
此版本引入了Python 类型提示。目标是为所有函数和方法的每个参数和返回值提供类型信息。尽管大部分函数已经处理,但仍在进行中。
版本 1.18.5 的变更
除了几个修复外,此版本还专注于几个次要但重要的功能改进。其中之一是更精确地计算适合文本书写/插入的适当行高和插入点。与使用字体无关的常量不同,现在这些值来自于字体的属性。
还请注意,这是不再为 Python 版本低于 3.6 提供预生成轮子的第一个版本。PIP 也将在 2020 年底停止对这些版本的支持。
Tools.set_small_glyph_heights()
– 同时响应问题#739。此方法设置或取消一个全局参数,以始终使用字体大小计算边界框。如果“开启”,则文本搜索和所有文本提取都将返回高度较小的矩形、边界框和四边形。
Page.getImageBbox()
,以便在图像包含在 XObject 中时也计算其 bbox。
Shape.insertTextbox()
、Page.insertTextbox()
和TextWriter.fillTextbox()
方法,以在计算行高和插入点时尊重字体的“上升部分”和“下降部分”。这不再导致多行输出的行重叠。这些方法以前忽略了字体的特定信息,而是使用固定值。
1.18.4 版本变更
该版本添加了多项功能以支持 PDF 可选内容。其中包括具有全面*“可见性表达式”*(PDF 键/VE
)的 OCMDs(可选内容成员字典)、文本插入(包括 TextWriter 类)和绘图。
fill_color=None
时支持无颜色矩形。
Page.getText()
输出的 UTF-8 编码错误。
Document.set_oc()
和Document.get_oc()
方法,用于设置或获取现有图像和表单 XObject 的可选内容引用。这些方法与 Annot 中同名方法类似。
Document.set_ocmd()
和Document.get_ocmd()
方法,用于处理 OCMDs。
Page.deleteWidget()
方法,用于从页面中删除表单字段。这类似于删除注释。
Annot.set_popup()
、Annot.set_open()
、Annot.has_popup
、Annot.is_open
、Annot.popup_rect
、Annot.popup_xref
。
其他变更:
版本 1.18.3 的更改
作为一个重要的新功能,此版本引入了对 PDF 的 可选内容 概念的支持。
expand
和 deflate
参数在 Document.save()
和 Document.write()
方法中的问题。现在个别图像和字体的压缩应该最终能够正常工作。解决问题 #713。
版本 1.18.2 的更改
此版本对文本搜索进行了一些有趣的改进:现在返回任意数量的搜索结果,并且删除了 hit_max 参数。此外,新增的 clip 参数还允许限制搜索区域。现在搜索会检测换行时的连字符,并相应地找到连字符词。
quads=False
,则同一行上重叠的矩形将合并。之前,搜索字符串的部分属于不同的“标记内容”项,每个生成自己的矩形,就像它们出现在不同的行上一样。
Document.isRepaired
,如果 PDF 在打开时被修复,则为 true。
Document.setXmlMetadata()
方法,用于更新或创建 PDF 的 XML 元数据。实现问题 #691。
Document.getXmlMetadata()
返回 PDF 的 XML 元数据。
/ID
字段)。实现问题 #691。
Page.searchFor()
:现在接受一个新的 clip
参数,以限制搜索到这个矩形区域内。相应地,TextPage.search()
现在尊重 TextPage.rect
属性。
Page.searchFor()
和 TextPage.search()
中的参数 hit_max
现在已经过时:这些方法将返回所有命中结果。
Page.getText()
中的字符选择标准:如果其包围框完全包含,则现在将字符视为 clip
的一部分。在此之前,非空交集是足够的。
Document.scrub()
来支持新选项 redact_images
。这解决了问题 #697。
1.18.1 版本的变更
Page.insertText()
,Page.insertTextbox()
,Shape.finish()
,Shape.insertText()
和 Shape.insertTextbox()
都支持两个新参数:stroke_opacity 和 fill_opacity。
Page.insertImage()
添加了新参数 mask
,用于可选地提供外部图像掩码。解决了问题 #685。
Annot.soundGet()
用于提取音频注释的声音。
1.18.0 版本的变更
这是第一个支持 MuPDF v1.18 的 PyMuPDF 版本。重点在于扩展 PyMuPDF 的功能——除了修复错误之外。随后的 PyMuPDF 补丁可能会解决 MuPDF 中新增的功能。
size_t
而不是 int
在 C 中,应该可以正确处理非常大的像素图。
Page.insert_pdf()
中的一个主要内存泄漏源。
Page.apply_redactions()
中添加了关键字 “images”,以精细控制图像的处理方式。
Annot.getText()
和 Annot.getTextbox()
,提供与 Page 版本相同的功能。
Page.getText()
/ Annot.getText()
的块字典中添加了键 “number”,用于选项“dict”和“rawdict”。
glyph_name_to_unicode()
和 unicode_to_glyph_name()
。这两个函数不再依赖于特定的字体,现在也可以独立使用。数据现在基于Adobe Glyph List。
adobe_glyph_names()
和 adobe_glyph_unicodes()
,它们返回相应的可用数据。
Page.getDrawings()
,返回文档页面上绘图操作的详细信息。适用于所有文档类型。
Document.insert_pdf()
的性能。现在还跨多个独立插入操作抑制了多个对象的复制。这节省了时间、内存和目标文件大小。之前这种机制仅在单个方法执行中有效。还可以通过新方法的布尔参数 final=1 来禁止该功能,默认情况下是激活的。
Pixmap.xres
和 Pixmap.yres
值自动设置。
1.17.7 版本变更
Pixmap.set_origin()
再次设置。
Page.insertImage()
再次接受 rect_like
参数。
Document.insert_pdf()
的选项,允许显示进度消息。解决了问题 #640。
Page.getTextbox()
,它可以提取矩形框中包含的文本。在许多情况下,这应该可以替代编写自己的脚本来完成这种任务。
clip
参数到 Page.getText()
,以简化和加速页面子区域的文本提取。
TextWriter.appendv()
以垂直写入模式添加文本。解决了问题 #653
1.17.6 版本变更
origin
,包含该跨度中第一个字符的左下角坐标。
Font.buffer
,一个字体文件的 bytes 复制。
Page.cleanContents()
。允许切换清理,因此只进行语法清理。
1.17.5 版本变更
TextWriter.writeText()
中指定的不透明度。
fitz_fontdescriptors
。包含来自仓库 pymupdf-fonts 的可用字体信息。
Font.valid_codepoints()
返回一个包含字体具有字形的 Unicode 码点数组。
text_as_path
到 Page.getSVGimage()
。实现了 #580。如果设置为 False,生成的 SVG 文件会更小且包含可解析的文本。
1.17.4 版本变更
repair_mono_font()
用于修正某些等宽字体的显示字符间距。
Document.need_appearances()
用于精细控制 PDF 表单的行为。解决了问题 #563。
sRGB_to_pdf()
用于将 sRGB 格式的颜色整数转换为 PDF 颜色三元组。
sRGB_to_rgb()
用于将 sRGB 格式的颜色整数转换为(R, G, B)颜色三元组。
make_table()
,用于根据给定的矩形和所需的列数和行数生成表格单元。
版本 1.17.3 中的变更
Page.cleanContents()
时可能无法完全清除 PDF 页面。
LINK_NAMED
。
TextWriter.fillTextbox()
中文本开始位置。实现 #549。
Page.add_redact_annot()
的文档,以解释非内置字体的使用方式。
版本 1.17.2 中的变更
版本 1.17.1 中的变更
还显著改进了内联文档,以更好地支持交互式帮助。
版本 1.17.0 中的变更
此版本基于 MuPDF v1.17。以下是新功能和更改的亮点:
Document.loadPage()
的变更,以及“索引”页面访问 doc[n] 的变更:除了以前指定页面编号外,现在还可以指定元组 (章节, 页码) 来标识所需的页面。
其他变更:
TextWriter.writeText()
方法,现在支持 “morph” 参数。
Rect.morph()
, IRect.morph()
和 Quad.morph()
,它们返回一个新的 Quad 对象。
Page.add_freetext_annot()
方法,现在支持通过新的 “align” 参数进行文本对齐。
Document.convertToPDF()
现在不应再导致内存泄漏。
Page.rotationMatrix
和 Page.derotationMatrix
,用于支持 PDF 页面旋转后和原始版本之间的坐标转换。
可能会导致代码兼容性问题的更改:
Page._getTransformation()
已被移除。请使用公共方法 Page.transformationMattrix
替代。版本 1.16.18 的变更
本版本引入了几个围绕 PDF 文本输出的新功能。目的是简化此任务,同时提供扩展功能。
一个主要的成就是利用 MuPDF 的功能动态选择回退字体,以便在当前字体中找不到字符时使用。这对 Base-14 字体与 CJK 字体(中文、日文、韩文)的组合无缝运作。因此,文本可以包含来自拉丁文、希腊文、俄文、中文、日文和韩文的 任意组合的字符。
Pixmap(doc, xref)
现在应正确地反映已加载的图像对象。
Page.writeText()
方法,用于向页面写入一个或多个 TextWriter 对象。
版本 1.16.17 的变更
Pixmap.set_dpi()
,用于设置图像在 x 和 y 方向的分辨率。
版本 1.16.16 变更
版本 1.16.14 变更
Document.scrub()
,用于从 PDF 中 删除可能敏感的数据。实现了 #453。
Annot.blendMode()
,用于返回注释的 混合模式。
Annot.setBlendMode()
,用于设置注释的混合模式。解决了问题 #416。
Annot.update()
,以接受用于设置混合模式和不透明度的附加参数。
Tools.set_aa_level()
。解决了 #467。
版本 1.16.13 变更
Document.getPageXObjectList()
,返回页面的 Form XObjects 列表。
Page.setMediaBox()
,用于更改物理 PDF 页面大小。
Page.cleanContents()
(= Page._cleanContents()
)、Page.getContents()
(= Page._getContents()
)、Page.getTransformation()
(= Page._getTransformation()
)。
版本 1.16.12 变更
Annot.delete_responses()
,用于删除引用当前注释的 ‘Popup’ 和响应注释。主要用于数据保护目的。
Widget.reset()
,将字段值重置为其默认值。
版本 1.16.11 中的变化
Page.add_redact_annot()
和 Page.apply_redactions()
支持清除注释的功能。
版本 1.16.10 中的变化
Annot.setInfo()
,现在也可以接受直接参数,而不仅仅是字典。
Annot.info
,现在还会显示注释的唯一标识(/NM PDF 键)(如果存在)。
Page.annot_names()
方法,返回所有注释名称(/NM 键)的列表。
Page.load_annot()
方法,根据其唯一标识(/NM 键)加载注释。
Document.reload_page()
方法,在完成对页面的所有待处理更新后,提供页面的新副本。
版本 1.16.9 中的变化
Annot.setBorder()
、Annot.setColors()
、Link.setBorder()
和 Link.setColors()
,现在也可以接受直接参数,而不仅仅是冗长的字典。
版本 1.16.8 中的变化
Document.xrefObject()
、Document.xrefStream()
、Document.xrefStreamRaw()
、Document.PDFTrailer()
、Document.PDFCatalog()
、Document.metadataXML()
、Document.updateObject()
和 Document.updateStream()
。
Tools.mupdf_disply_errors()
,设置 mupdf 错误在 sys.stderr 上的显示。
版本 1.16.7 的更改
对于 TextPage 图像块和 Document.extractImage()
图像,进行了微小的更改,以更好地同步二进制图像流。
Tools.mupdf_warnings()
,现在会自动清空存储(如果没有通过参数停用)。
Page.getImageBbox()
,如果无法在页面上定位图像,则返回一个无限矩形,而不是引发异常。
版本 1.16.6 的更改
Page.searchFor()
/ Document.searchPageFor()
,现在也支持 flags 参数,用于控制包含在 TextPage 中的数据。
Document.getPageImageList()
,Document.getPageFontList()
及其 Page 对应方法,支持新的 full 参数。如果为 true,则返回的项目将包含引用字体或图像的 Form XObject 的 xref
。
版本 1.16.5 的更改
进一步优化文本提取性能。
Page.getTextPage()
,现在不再需要为文本提取创建中间显示列表。页面级别的文本提取和文本搜索现在都基于此方法,预计可以提高约 5% 的性能。
版本 1.16.4 的更改
Document.pages()
,用于生成页面范围的迭代器。
Page.links()
,用于生成页面链接的迭代器。
Page.annots()
,用于生成页面注释的迭代器。
Page.widgets()
,用于生成页面表单字段的迭代器。
Document.is_form_pdf
,现在包含小部件的数量,如果不是 PDF 或此数量为零,则为 False。
版本 1.16.3 的更改
与版本 1.16.2 相比,较小的变化。Page.getText()
的“dict”和“rawdict”变体代码已经移植到了 C 中,极大地提高了性能。这在文本导向的文档中特别明显,现在几乎可以快两倍执行。
Page.getText()
已修改以接受额外的关键字“blocks”和“words”。它们将分别返回Page.getTextBlocks()
和Page.getTextWords()
的结果。因此,所有文本提取方法现在通过统一的 API 可用。对应地,现在有新的方法TextPage.extractBLOCKS()
和TextPage.extractWords()
。
Page.getText()
将默认的位指示器TEXT_INHIBIT_SPACES设为off。默认情况下不会抑制额外空格的插入。
版本 1.16.2 中的更改
planish_line()
用于将给定线(定义为一对点)映射到 x 轴。
Page.getText()
时,遇到某些非 UTF-8 可编码字符时,解释器崩溃。
版本 1.16.1 中的更改
Quad.is_convex
,用于检查线是否包含在四边形中,如果连接了它的两个点。
Document.insert_pdf()
现在允许在复制期间独立地放弃或包含链接和注释。修复了问题 #352 (“损坏的 PDF 数据和…”),在使用该方法处理某些问题 PDF 文件时似乎偶尔会出现。
版本 1.16.0 中的更改
MuPDF 的这个重大新版本带来了几个不错的新特性或更改。其中一些暗示了编程 API 的变化。这是变化的概述:
Page.firstAnnot
或 Annot.next()
时,永远不会遇到小部件。您必须使用 Page.firstWidget
和 Widget.next()
来访问表单字段。
变更详情列表:
Document.can_save_incrementally()
,检查阻止使用选项 incremental=True 的 Document.save()
的条件。
Page.firstWidget
,指向页面上第一个字段。
Page.getImageBbox()
,返回页面上显示的图像所占用的矩形。
Annot.setName()
,允许您更改(图标)名称字段。
Page.getText()
中输出文本颜色的功能:“dict”,“rawdict” 和 “xml” 选项现在还显示 sRGB 格式的颜色。
Document.permissions
现在包含一个布尔指示器的整数 – 之前是一个字典。
Document.save()
,Document.write()
,现在完全支持基于密码的 PDF 文件解密和加密。
Tools.mupdf_warnings()
,清空此缓冲区的函数现在称为 Tools.reset_mupdf_warnings()
。
Page.getPixmap()
和 Document.get_page_pixmap()
:现在可以使用新的布尔参数 annots 来抑制页面上注释的渲染。
Page.add_file_annot()
和 Page.add_text_annot()
,可以设置图标。
MuPDF v1.15.0 未发布任何版本
1.14.20 / 1.14.21 版本变更
1.14.19 版本变更
Document.get_sigflags()
,用于返回 PDF 签名信息。解决问题 #326(“如何检测表单 PDF 中的签名?”)。
1.14.17 版本变更
Document.fullcopyPage()
,用于在 PDF 中进行完整页面复制(不仅是 Document.copyPage()
中的引用复制)。
Page.getPixmap()
和 Document.get_page_pixmap()
,现在默认使用 alpha=False。
Document.movePage()
和 Document.copyPage()
,使用直接函数而不是包装 Document.select()
– 类似于 v1.14.16 中的 Document.delete_page()
。
1.14.16 版本变更
Document.embfile_Count()
,现在是一个函数(之前是一个属性)。
Document.embfile_Names()
,用于返回嵌入文件的名称列表。
Document.delete_page()
和 Document.delete_pages()
在内部不再使用 Document.select()
,而是直接使用函数执行删除。由于已经发现,Document.select()
方法对于非常复杂的 PDF 和注释使用复杂的文档(目录表)生成了无效的大纲树。
1.14.15 版本变更
Page.getText()
的 “dict”、“rawdict” 和 “json” 版本后内存没有(完全)释放。
1.14.14 版本变更
ImageProperties()
,用于确定图像的许多特征。
Document.is_stream()
,用于检查对象是否为流类型。
Document._getXrefString()
和 Document._getTrailerString()
现在默认以格式化形式返回对象定义,这使得解析变得容易。
1.14.13 版本变更
1.14.12 版本变更
Document.insert_page()
进行文本插入时。
1.14.11 版本变更
Page.show_pdf_page()
以始终将源矩形居中放置在目标中。此方法现在还支持任意角度的旋转。参数 reuse_xref 已被弃用:防止重复现在内部处理。
Page.insertImage()
以支持图像的旋转显示并保持纵横比。此处仅支持 90 度的倍数旋转。
Document.insert_page()
时插入文本时发生。
1.14.10 版本变更
Page.show_pdf_page()
以支持源矩形的旋转。修复了 #261 号问题(“无法旋转插入的页面”)。
Page.insertImage()
中的一个错误,该错误阻止了以流的形式插入多个图像。
1.14.9 版本变更
Document._getTrailerString()
,它返回 PDF 的尾部对象。这与 Document._getXrefString()
类似,但 PDF 尾部没有 / 不需要 xref
来标识它。
Document.extractImage()
现在将以原始格式返回它们。先前使用的是 MuPDF 基本库,它以 PNG 格式返回它们(导致了巨大的大小增加)。
get_text_length()
的用法,并删除了长单词的额外换行。
1.14.8 版本变更
Pixmap.set_rect()
以更改矩形中的像素值。这也是设置完整 Pixmap 颜色(Pixmap.clear_with()
)的替代方法。
Page.getText()
(参数“dict”和“rawdict”)和 Document.extractImage()
方法中。
Pixmap.clear_with()
)的清除不正确的问题。
Pixmap.invert_irect()
)的颜色未正确反转的问题。
版本 1.14.7 中的变更
Pixmap.set_pixel()
方法,用于改变一个像素值。
get_text_length()
函数,用于确定给定字体的字符串长度。
Pixmap.save()
和 Pixmap.tobytes()
)。
Pixmap.save()
和 Pixmap.tobytes()
以确保颜色空间、alpha 和输出格式的有效组合。
Pixmap.save()
方法:现在所需的格式可以从文件名推断出来。
Annot.update()
。
版本 1.14.5 中的变更
Pixmap.pixel()
方法,用于返回给定像素坐标的像素值(一个列表)。
Pixmap.tobytes()
方法,用于返回表示各种格式的 pixmap 的字节对象。先前,这仅适用于 PNG 输出(Pixmap.tobytes()
)。
Pixmap.save()
方法及(新的)Pixmap.tobytes()
方法的输出现在也可能是 PSD(Adobe Photoshop Document)格式。
Shape.drawQuad()
方法,用于绘制 Quad。实际上,这是使用四边形的边缘进行 Shape.drawPolyline()
的简写。
Shape.drawOval()
方法:现在参数可以是一个矩形(rect_like
)或者一个四边形(quad_like
)。
版本 1.14.4 中的变更
版本 1.14.3 中的变更
此补丁版本包含了次要错误修复和 CJK 字体输出支持。
Page.insertFont()
、Shape.insertText()
、Shape.insertTextbox()
方法及其对应的 Page 方法。新字体可在“保留”字体名称下使用,包括 “china-t”(繁体中文)、“china-s”(简体中文)、“japan”(日文)和 “korea”(韩文)。
版本 1.14.1 的变更
此补丁版本包含轻微的性能改进。
版本 1.14.0 的变更
为了支持 MuPDF v1.14.0,PyMuPDF 需要进行了大量的更改 - 其中大部分是技术性的,对开发人员的可见性不大。但也有相当多的有趣的新功能和改进功能。以下是详细信息:
Document.save()
和Document.write()
。现在,保存受密码保护的 PDF 时可以保持加密。
Annot.update()
才能生效。
Page.searchFor()
,可选择返回四边形而不是矩形对象,围绕每个搜索命中。
在幕后,我们已经改变了几何对象的实现方式:它们现在完全存在于 Python 中,不再在 C 级别(MuPDF 中)存在“影子”双胞胎。这在该领域的处理速度提高了两倍以上。
由于同样的原因,现在大多数涉及几何参数的方法也接受相应的 Python 序列。例如,在方法*“page.show_pdf_page(rect, …)”中,参数rect*现在可以是任何rect_like
序列。
我们还投入了大量精力来进一步扩展和改进常见问题解答(FAQ)章节。
版本 1.13.19 的变更
此版本包含一些技术/性能改进和错误修复。
TextPage.extractRAWDICT()
(= Page.getText(“rawdict”))时导致解释器崩溃。
版本 1.13.18 变更
TextPage.extractRAWDICT()
,以及相应的新字符串参数“rawdict”到方法Page.getText()
。它以 Python dict 形式从页面提取文本和图像,类似于 TextPage.extractDICT()
,但具有 TextPage.extractXML()
的详细级别,即位置信息下到每个单个字符。版本 1.13.17 变更
Page.show_pdf_page()
中的异常,当来自许多不同源 PDF 的页面显示时。
Document.extractImage()
现在返回有关提取图像的更多元信息。此外,其性能已大大提高。几个演示脚本已更改以使用此方法。
Document._getXrefStream()
现在如果对象不是流则返回 None,并且不再引发异常。
Document._deleteObject()
,它删除由其 xref
标识的 PDF 对象。只能由经验丰富的 PDF 专家使用。
paper_rect()
,它返回所提供纸张格式字符串的 Rect。示例:fitz.paper_rect(“letter”) = fitz.Rect(0.0, 0.0, 612.0, 792.0)。
版本 1.13.16 变更
Tools.fitz_config
gives “cannot resize a buffer with shared storage” error’)。
版本 1.13.15 变更
版本 1.13.14 中的变化
这个补丁版本包含了几个改进,主要是用于注释。
Annot.lineEnds
现在是表示行结束符号的两个整数的列表。之前是一个字符串的字典。
Annot.setLineEnds()
用于向适用的注释类型(‘Line’、‘PolyLine’、‘Polygon’)添加行结束符号。
Page.insertImage()
和 Page.show_pdf_page()
的技术实现:它们现在会创建自己的内容对象,从而避免了对潜在大流的更改,避免了压缩/解压缩工作以及增量更新时的高更改量。
版本 1.13.13 中的变化
这个补丁版本包含了几个嵌入文件和文件附件注释的改进。
Document.embfile_Upd()
允许更改嵌入文件的文件内容和元数据。它取代了旧方法 Document.embfile_SetInfo()
(将在将来的版本中删除)。内容会自动压缩,元数据可以是 Unicode。
Document.embfile_Add()
现在会自动压缩文件内容。相关元数据现在可以是 Unicode(过去必须是 ASCII)。
Document.embfile_Del()
现在会自动删除所有具有提供的标识名称的条目。返回码现在是被删除条目的整数计数(之前是None)。
Page.add_file_annot()
用于添加新的文件附件注释。
Annot.fileUpd()
(文件附件注释)现在还接受 PDF 的 Unicode ufilename 参数。描述参数desc可以正确使用 Unicode。此外,所有参数都是可选的,因此可以更改元数据而不必替换文件内容。
Annot.fileInfo()
(文件附件注释)现在还会显示 PDF 的 Unicode 文件名作为参数ufilename。
1.13.12 版本变更
Widget.choice_values
。
Annot.updateWidget()
允许更改现有表单字段,包括字段值。
1.13.11 版本变更
尽管前几个补丁子版本只包含各种修复,但此版本再次引入了重要的新功能:
1.13.7 版本变更
Document.layout()
。
Annot.opacity
,Annot.setOpacity()
)。
Annot.vertices
:点坐标现在被分组为浮点数对(不再作为单独的浮点数)。
Document.isDirty
如果 PDF 在本次会话中已更改,则为 True。每次 Document.save()
或 Document.write()
后重置为 False。
版本 1.13.6 变更
版本 1.13.5 变更
Page._setContents()
定义了一个由其 xref
指定的对象,作为 contents
对象。
Annot.widget_value
。现在支持所有表单字段类型的值(除了签名)。新属性 Annot.widget_choices
包含列表框和组合框的可选值。如果没有值存在,所有这些属性现在都包含 None。
版本 1.13.4 变更
Document.convertToPDF()
现在支持页面范围、恢复的页面顺序和页面旋转。如果文档已经是 PDF,则会引发异常。
Page.insertImage()
。
版本 1.13.3 变更
引入了一种将 任何 MuPDF 支持的文档 转换为 PDF 的方法。如果您希望将 XPS、EPUB、CBZ 或 FB2 文件转换为 PDF 版本,这里有一个方法。
Document.convertToPDF()
返回一个 Python 的 bytes 对象,以 PDF 格式呈现。可以像普通文件一样在 PyMuPDF 中打开,或者带有 “.pdf” 扩展名写入磁盘。版本 1.13.2 变更
主要增强是 PDF 表单字段支持。表单字段是类型为 (19, ‘Widget’) 的注释。有一个新的文档方法来检查 PDF 是否为表单。Annot 类具有描述字段详细信息的新属性。
Document.is_form_pdf
如果对象类型为 /AcroForm 并且至少存在一个表单字段,则为 true。
Annot.widget_type
、Annot.widget_text
和 Annot.widget_name
包含表单字段(即“Widget”注释)的详细信息。
版本 1.13.1 变更
TextPage.extractDICT()
是提取文档页(文本和图像)内容的新方法。与其他 TextPage extract()* 方法一样,支持所有文档类型。返回的对象是嵌套列表和其他字典的字典,与旧的 TextPage.extractJSON()
的 JSON 反序列化完全相同。不同之处在于结果是直接创建的 – 不使用 JSON 模块。因为用户无需 JSON 模块来解释信息,所以使用起来应该更容易,而且性能更好,因为它包含图像的原始 二进制格式 – 无需进行 base64 解码。
Page.getText()
相应地支持新参数值 “dict” 以调用上述方法。
TextPage.extractJSON()
(或 Page.getText(“json”))仍然为方便起见支持,但预计其使用将减少。
版本 1.13.0 的变更
本版本基于 MuPDF v1.13.0. 此版本是“主要的 bug 修复版本”。
在 PyMuPDF 中,我们还进行了一些 bug 修复,同时引入了一些小的增强功能。对用户 API 仅有非常小的更改。
Document.save()
再次提供完整的垃圾回收范围 0 到 4. 由于 xref
维护中的一个 bug,我们不得不临时强制 garbage > 1。最终解决了 问题 #148。
Document.save()
现在提供通过额外的参数“美化” PDF 源码的选项。
Page.insertImage()
现在有了额外的 stream 参数,指定一个保存图像的内存区域。
版本 1.12.4 的变更
这是 1.12.3 版本的扩展。
Document.getPageFontlist()
和 Document.getPageImagelist()
现在还显示通过“Form XObjects”嵌套的 resources
中包含的字体和图像。
Document.getPageFontlist()
现在包含列表中每个字体的编码名称。
Document.getPageImagelist()
现在包含列表中每个图像的解码方法名称。
版本 1.12.3 的变更
这是 1.12.2 版本的扩展。
Document.close()
, Document.save()
, Document.select()
, Pixmap.save()
和许多其他函数)。版本 1.12.2 变更
这是 1.12.1 版本的扩展。
Page.show_pdf_page()
现在接受新的 clip 参数。这指定了应限制显示的源页面区域。
Page.CropBox
和 Page.MediaBox
。
版本 1.12.1 变更
这是 1.12.0 版本的扩展。
Page.show_pdf_page()
显示另一个 PDF 页面。这是一个矢量图像,因此在缩放时保持精确。两个涉及的文档必须是 PDF 格式。
Page.getSVGimage()
创建页面的 SVG 图像。与位图的光栅图像相比,这是一种矢量图像格式。返回的是一个 Unicode 文本字符串,可以保存在 .svg 文件中。
Page.getTextBlocks()
现在接受额外的布尔参数 “images”。如果设置为 true(默认为 false),则包括图像块(仅元数据)在内的列表,从而允许检测包含渲染图像的区域。
Page.getText()
的 “text” 结果通过使用单个空格字符连接块内所有行。MuPDF 的原始版本使用 “\n”,导致输出比较不规则。
Page.MediaBoxSize
和 Page.CropBoxPosition
提供了关于页面尺寸的更多信息。对于非 PDF 文件(以及大多数 PDF 文件),它们将等同于 Page.rect.bottom_right
和 Page.rect.top_left
。例如,类 Shape 使用它们正确地定位其项目。
版本 1.12.0 变更
此版本基于并需要 MuPDF v1.12.0。新的 MuPDF 版本包含了许多变更,主要围绕文本提取。其中一些变更影响了程序员的 API。
Outline.saveText()
和 Outline.saveXML()
被删除且没有替代。你可能并未经常使用它们。但如果你在寻找替代方案:Document.get_toc()
的输出可以轻松用于生成等效内容。
Page.getText()
的所有输出格式现在都支持创建完整的、有效的文档,通过添加适当的头部和尾部信息进行包装。如果您有兴趣使用 HTML 输出,请确保阅读 控制 HTML 输出的质量。
TextPage.extractJSON()
或 TextPage.extractXML()
那样绕弯子:使用 Page.getTextBlocks()
或 Page.getTextWords()
来创建文本块或单词列表,它们附带其矩形。这应该比标准文本提取方法快得多,也避免了使用额外的包来解释它们的输出。
版本 1.11.2 中的更改
这是 v1.11.1 的扩展版本。
Page.insertFont()
创建一个 PDF 的 /Font 对象并返回其对象编号。
Document.extractFont()
提取给定对象编号的嵌入字体的内容。
Pixmap.shrink()
在原地按比例减小了像素图。版本 1.11.1 中的更改
这是 v1.11.0 的扩展版本。
contents
对象的更新次数。
point_like
”(或 matrix_like
、rect_like
)。
matrix_like
对象 m,则为 p * ~m。同样,如果 r 是一个矩形,则 r |= (3, 4) 是包含 fitz.Point(3, 4) 的新矩形,r &= (1, 2, 3, 4) 则是与 fitz.Rect(1, 2, 3, 4) 的交集。
版本 1.11.0 中的变更
此版本基于并需要 MuPDF v1.11。
虽然 MuPDF 已经声明这主要是一个修复 bug 的版本,但确实包含一个重要的新功能:支持嵌入文件,也称为组合或集合。我们已扩展了 PyMuPDF 的功能,以支持这一功能,超过了 mutool 实用程序的范围。
版本 1.10.0 中的更改
MuPDF v1.10 影响
MuPDF 版本 1.10 对我们的绑定产生了重大影响。一些更改也影响了 API - 换句话说,你作为 PyMuPDF 用户受到了影响。
与版本 1.9.3 相比的其他更改
版本 1.9.3 中的变更
此版本还基于 MuPDF v1.9a。与版本 1.9.2 相比的更改包括:
版本 1.9.2 的变更
此版本还基于 MuPDF v1.9a。与版本 1.9.1 相比的更改如下:
内存区域stream的类型可以是bytes或bytearray。因此,例如,可以直接使用area = open(“file.pdf”, “rb”).read()(而不必先转换为 bytearray)。
len(doc) == doc.pageCount
。
xref
编号创建像素图。
版本 1.9.1 的变更
此版本的 PyMuPDF 基于 MuPDF 库源代码版本 1.9a,发布于 2016 年 4 月 21 日。
请查看 MuPDF 的网站,了解包含的变更和增强功能。
与版本 1.8.0 相比,版本 1.9.1 的更改如下:
您对本页有何反馈?
本软件按原样提供,没有明示或暗示的任何保证。本软件根据许可证分发,除非在许可证条款明确授权,否则不得复制、修改或分发。请参考 artifex.com 的许可信息或联系位于美国加利福尼亚州旧金山 Mesa Street 39 号 108A 套房的 Artifex Software Inc. 了解更多信息。
此文档覆盖所有版本,直到 1.24.4。