对pdf文件的常见操作需求包括读取pdf中的文字图表,新建或截取pdf,pdf与其他格式的转换等。通过代码可更灵活的实现各种功能需求。在众多可处理pdf的包中选择PyMuPDF进行介绍。PyMuPDF是MuPDF的python接口,可处理 的文件格式后缀包括 pdf,xps,oxps,cbz,fb2, epub。另外也可处理10余种常见图片格式,包括:png,jpg,bmp,tiff等。
pip install pymupdf 或 PyMuPDF
由于历史原因,导入PyMuPDF 包的语句为:
import fitz
以下以 1.18.17 版本为例介绍。
读取pdf文件
可直接打开支持的文件类型,输入文件名即可。也可以打开已经由其他工具读取的文件流。打开后,可对其中的页面进行操作。
doc = fitz.open(filename)
# 先从zip压缩文件读取,再使用fitz打开
doc = fitz.open(stream=zfile.read(pdf), filetype="pdf")
# 获取pdf中页面
first_page = doc.load_page(0)
# 或直接遍历
for page in doc:
# do something
提取pdf中全部文本或搜索文本
遍历所有页面,获取文本。搜索文本只能在单个页面上进行,可通过遍历获取全部结果。
texts = ""
with fitz.open(path) as doc:
for page in doc:
# 提取文字
texts += page.getText() # 现更改为 page.get_text()
# 在当前页面上搜索指定内容
rect = page.search_for("keyward")
# 或直接在doc水平,加载指定页面进行搜索
doc.search_page_for(page_num,"keyward")
读取各种格式的图片
可读取普通格式,二进制文件流或base64格式的图片。
if type == "byte":
img = fitz.open(stream=f, filetype=filetype)
elif type == "base64":
img = fitz.open(stream=io.BytesIO(base64.b64decode(f)), filetype=filetype)
else:
img = fitz.open(f)
提取页面中的图片
首先需要获取xref (cross-reference number)。xref是交叉引用编号,这是pdf中对象的整数唯一标识。每个pdf都存在一个交叉引用表(物理上可能有几个单独的部分组成)。它存储每个对象的相对位置,以便快速查找。其中item 0是保留项,不会以任何方式使用。 许多PyMuPDF类有一个xref属性(非PDF为0),可以获得pdf中对象的总数 :Document.xref_length() - 1
。有两种方式获取xref,得到xref后又有两种方式提取图片,如下:
#获取单个页面上图片的xref
Page.get_images()
# 得到pdf的xref数目后全部遍历,找到需要的图片对应的xref
doc.extract_image(xref)
# 2种方式提取图片
pix = fitz.Pixmap(doc, xref)
img = doc.extract_image(xref)
其中Page.get_images()的返回内容为包含多个信息的list,内容为(xref, smask, width, height, bpc, colorspace, alt.colorspace, name, filter, referencer)。
pix = page.get_pixmap() # render page to an image
pix.save("page-%i.png" % page.number) # 保存图片
zoom_x = 2 # 放大2倍
zoom_y = 2
rotate = int(0)
mat = fitz.Matrix(zoom_x, zoom_y).preRotate(rotate)
pix = page.getPixmap(matrix=mat, alpha=False)
pdfDoc = fitz.open(pdf_path)
pageNum = pdfDoc.pageCount
pdfDoc.select([i for i in range(pageNum -5, pageNum )]) # 选择最后5页进行保存
pdfDoc.save(new_pdf_path, garbage=3) # 保存为新的pdf
pdfDoc.close()
doc = fitz.open()
for i, f in enumerate(images):
img = fitz.open(f)
rect = img[0].rect # pic dimension
pdfbytes = img.convert_to_pdf() # 图片转换为pdf字节
img.close() # no longer needed
imgPDF = fitz.open("pdf", pdfbytes) # open stream as PDF
page = doc.new_page(width=rect.width, height=rect.height) # pic dimension
page.show_pdf_page(rect, imgPDF, 0) # 将图片转换后的pdf对象填充到页面
doc.save(outfile)
PyMuPDF中有一些最常用的类,也是pdf各种核心操作的对象,其属性值可提供各种信息,上述各种操作需求也是基于对象方法的使用,仅仅是一些常见需求。更多功能操作或需求,以及全部类更详细的属性方法可参考官方文档。常用的有以下几种: