本文作者:王碧琪
文字编辑:戴 雯
技术总编:张 邯
之前我们使用pymupdf提取了PDF文档中的文本信息,那么对于图片信息,也可以进行一波提取。今天我们一起来试试。
一、简介
待提取PDF文档“demo1”内容如下:
可以观察到,该文档中共有4张图片。提取思路为:首先得到PDF文档的所有对象,然后遍历它们判断是否是图片类型,再将图片信息写入,最后保存为png格式文件。
二、图片提取
(一)引入相应的库
import fitz #处理PDF
import re #使用正则表达式
import os #进行相关路径的判断
(二)导入PDF&创建导出图片的文件夹
path = r"F: \pdfs\demo1.pdf" #导入的pdf的路径
pic_path = r"F: \ima" #导出图片的文件夹
if not os.path.exists(pic_path):
os.mkdir(pic_path)
else:
print("文件夹已存在,不必重建!")
doc = fitz.open(path) #打开pdf文件
lenXREF = doc.xrefLength()-1 #获取对象数量长度
print(f"文件名:{path}, 页数: {doc.pageCount}, 对象: {lenXREF}") # 打印PDF的信息
运行结果为:
文件夹已存在,不必重建!
文件名:F: \pdfs\demo1.pdf, 页数: 3, 对象: 54
xref
是cross-reference
的缩写。xref比现有对象的数量大一个,所以可以用Document.xrefLength()-1
得到PDF文档中的对象总数。结果显示:demo1文档有3页,54个对象。
(三)遍历对象,定位图片
for i in range(1, lenXREF):
print(i)
text = doc.xrefObject(i) #得到xref对象的相关信息
print(text)
部分结果如下:
可以看到其中记录了每一个对象的信息。例如对象3,它是一个图片,text中记录了它的type和subtype。我们利用subtype
标记为image
这一点,来定位图片。
checkIM = r"/Subtype(?= */Image)" # 使用正则表达式来查找图片
for i in range(1, lenXREF):
text = doc.xrefObject(i) # 定义对象字符串
isImage = re.search(checkIM, text) # 查看是否是image
if isImage:
print(i)
运行结果为:
3
4
7
32
这样就定位到了文档中的4张图片。
(四)提取图片
使用fitz.Pixmap(doc,xref)
函数创建pixmap
。像素图的属性(宽度、高度等)将反映图像的属性。这里的xref要对应上面定位到的图片的xref标号。使用pixmap对象的writePNG(filename)
函数,可以将pixmap保存为png格式的图片。
imgcount = 0 # 图片计数
for i in range(1, lenXREF):
text = doc.xrefObject(i) # 定义对象字符串
isImage = re.search(checkIM, text) # 查看是否是image
if not isImage: # 如果不是图片,则进行下一个判断
continue
imgcount += 1 #图片计数
pix = fitz.Pixmap(doc, i) # 生成图像对象
new_name = f"图片{imgcount}.png" # 生成图片的名称
print(new_name)
pix.writePNG(os.path.join(pic_path, new_name))
pix = None
运行结果是:
图片1.png
图片2.png
图片3.png
图片4.png
去目标文件夹看一下,成功提取了相应的图片: