如何用Python提取PDF文件中的图片
上文我们介绍如何用pdfplumber快速将PDF文档转化为可编辑的纯文本文件,这次我们来看看对图片的提取(对应的视频课程已先在视频号「退役程序员」中发布)。
所需要的库pdfplumber
有很多的库都可以用于处理PDF文档,例如PyMuPDF、PyPDF2、pdfplumber、pikepdf等等,它们各自有着特定的优势和用途,为了实现对文本、图片和表格的简单提取功能,这里我选用的是pdfplumber,大家可以访问下面链接来对这个库有个大致了解:
https://pypi.org/project/pdfplumber/
在开始写代码前,我们需要用以下命令对这个库进行安装:
pip install pdfplumber
提取图片的代码部分
def extract_image(file_path):
try:
with pdfplumber.open(file_path) as pdf:
for i, page in enumerate(pdf.pages):
for j, image in enumerate(page.images):
image_stream = image['stream']
image_data = image_stream.get_data()
image_bytes = io.BytesIO(image_data)
extrImage = Image.open(image_bytes)
extrImage.save(f"image_{i+1}_{j}.jpg")
except FileNotFoundError:
print(f"Error: The file '{file_path}' does not exist.")
except Exception as e:
print(f"Error: An error occurred while processing the file: {e}")代码解析
for i, page in enumerate(pdf.pages):
for j, image in enumerate(page.images):这两行代码中的第一个for循环,用于遍历PDF文档中的每一页。pdf.pages是一个类似于列表的对象,包含PDF的所有页面。enumerate函数用于同时获取页面的索引
(i,从 0 开始) 和页面对象 (page)。
而嵌套的第二个for循环遍历当前page上找到的每一个图像。page.images提供了一个包含该特定页面上所有图像对象的列表。同样,enumerate
用于获取图像的索引 (j) 和image对象。
image_stream = image['stream']这里的每个image对象是一个字典类型的数据,包含着各种键值。这行代码访问存储在'stream'键下原始图像数据流,并将其赋值给image_stream。
image_data = image_stream.get_data()这行代码通过调用image_stream对象的get_data()方法,从
image_stream中提取实际的二进制图像数据。这些数据随后存储在
image_data变量中。
image_bytes = io.BytesIO(image_data)用于图像处理的PIL(Pillow)
库通常要求图像数据以类似文件对象的格式存在。这行代码使用io.BytesIO将原始image_data包装在一个内存中的二进制流中,使其表现得像一个文件。
extrImage = Image.open(image_bytes)这行代码使用Pillow库中的Image.open()函数从image_bytes流中打开图像数据。打开的图像对象被赋值给extrImage。
extrImage.save(f"image_{i+1}_{j}.jpg")这行代码将提取的图像保存到文件中。文件名使用 f-string 构建:
{i+1}表示页码(i从 0 开始,所以加 1)。{j}表示该页面上的图像序号(从 0 开始)。
完整代码
# pdfconverter.py
import pdfplumber
import sys
import io
from PIL import Image
def extract_text(file_path):
"""
Extracts text from a PDF file and saves it as a TXT file.
Args:
file_path (str): Path to the PDF file.
Returns:
None
"""
output_file = file_path.split('.')[0] + '.txt'
try:
with pdfplumber.open(file_path) as pdf:
txt = ''
for page in pdf.pages:
txt += page.extract_text()
with open(output_file, 'w', encoding='utf-8') as f:
f.write(txt)
except FileNotFoundError:
print(f"Error: The file '{file_path}' does not exist.")
except Exception as e:
print(f"Error: An error occurred while processing the file: {e}")
def extract_image(file_path):
try:
with pdfplumber.open(file_path) as pdf:
for i, page in enumerate(pdf.pages):
for j, image in enumerate(page.images):
image_stream = image['stream']
image_data = image_stream.get_data()
image_bytes = io.BytesIO(image_data)
extrImage = Image.open(image_bytes)
extrImage.save(f"image_{i+1}_{j}.jpg")
except FileNotFoundError:
print(f"Error: The file '{file_path}' does not exist.")
except Exception as e:
print(f"Error: An error occurred while processing the file: {e}")
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python pdfconverter.py <pdf_file>")
else:
file_path = sys.argv[1]
extract_text(file_path)
extract_image(file_path)