当前位置:首页 > Python > 正文

Python读取PDF中的图片:完整教程与代码示例 | Python PDF处理指南

Python读取PDF中的图片:完整教程

使用PyPDF2和pdf2image两种方法提取PDF文件中的图像

PDF文件是文档共享的常见格式,其中经常包含有价值的图像内容。本教程将详细介绍如何使用Python从PDF文件中提取图片,包含两种主流方法:PyPDF2(纯Python实现)和pdf2image(基于Poppler的高性能解决方案)。

应用场景: 从扫描的PDF文档中提取图像、获取PDF报告中的图表、批量处理包含图像的PDF文档、PDF内容分析等。

准备工作

在开始之前,请确保已安装Python环境(建议Python 3.7+)。我们将使用以下库:

1

安装PyPDF2

PyPDF2是纯Python的PDF处理库,无需外部依赖:

pip install PyPDF2
2

安装pdf2image

pdf2image提供更强大的图像提取功能,但需要安装Poppler:

pip install pdf2image

安装Poppler:

  • Windows: 下载并添加到PATH
  • macOS: brew install poppler
  • Linux: sudo apt-get install poppler-utils

方法一:使用PyPDF2提取图片

PyPDF2适合处理简单的PDF文件,下面是完整的代码示例:

import PyPDF2
from PIL import Image
import os

def extract_images_with_pypdf2(pdf_path, output_folder):
    # 确保输出目录存在
    os.makedirs(output_folder, exist_ok=True)
    
    # 打开PDF文件
    pdf_file = open(pdf_path, 'rb')
    pdf_reader = PyPDF2.PdfReader(pdf_file)
    
    # 遍历所有页面
    for page_num in range(len(pdf_reader.pages)):
        page = pdf_reader.pages[page_num]
        
        # 获取页面中的XObject
        if '/XObject' in page['/Resources']:
            x_object = page['/Resources']['/XObject'].get_object()
            
            for obj in x_object:
                if x_object[obj]['/Subtype'] == '/Image':
                    # 获取图像对象
                    img = x_object[obj]
                    
                    # 获取图像数据
                    img_data = img.get_data()
                    
                    # 根据图像格式保存
                    if '/Filter' in img:
                        if img['/Filter'] == '/FlateDecode':
                            # 保存为PNG
                            img_path = os.path.join(output_folder, 
                                                  f"page_{page_num+1}_img_{obj[1:]}.png")
                            with open(img_path, 'wb') as img_file:
                                img_file.write(img_data)
                        elif img['/Filter'] == '/DCTDecode':
                            # 保存为JPEG
                            img_path = os.path.join(output_folder, 
                                                  f"page_{page_num+1}_img_{obj[1:]}.jpg")
                            with open(img_path, 'wb') as img_file:
                                img_file.write(img_data)
                        elif img['/Filter'] == '/JPXDecode':
                            # 保存为JPEG 2000
                            img_path = os.path.join(output_folder, 
                                                  f"page_{page_num+1}_img_{obj[1:]}.jp2")
                            with open(img_path, 'wb') as img_file:
                                img_file.write(img_data)
                    else:
                        # 尝试保存为PNG
                        img_path = os.path.join(output_folder, 
                                              f"page_{page_num+1}_img_{obj[1:]}.png")
                        with open(img_path, 'wb') as img_file:
                            img_file.write(img_data)
    
    pdf_file.close()
    print(f"图片已提取到: {output_folder}")

# 使用示例
extract_images_with_pypdf2('example.pdf', 'extracted_images')

✅ 优点

  • 纯Python实现,无需外部依赖
  • 适合简单PDF文档
  • 可以处理多种图像格式

❌ 缺点

  • 对于复杂PDF支持有限
  • 不能处理扫描的PDF文档
  • 对某些图像格式支持不完善

方法二:使用pdf2image提取图片

pdf2image库通过Poppler提供更强大、更可靠的PDF图像提取功能:

from pdf2image import convert_from_path
import os

def extract_images_with_pdf2image(pdf_path, output_folder, dpi=200, 
                                 fmt='jpeg', thread_count=4):
    """
    使用pdf2image从PDF中提取图片
    
    参数:
        pdf_path: PDF文件路径
        output_folder: 输出目录
        dpi: 图像分辨率(默认为200)
        fmt: 输出格式('jpeg', 'png', 'tiff')
        thread_count: 使用的线程数
    """
    # 确保输出目录存在
    os.makedirs(output_folder, exist_ok=True)
    
    # 转换PDF为图像
    images = convert_from_path(pdf_path, 
                              dpi=dpi, 
                              fmt=fmt,
                              output_folder=output_folder,
                              output_file='page',
                              paths_only=True,
                              thread_count=thread_count)
    
    print(f"成功提取 {len(images)} 张图片到 {output_folder}")

# 使用示例
extract_images_with_pdf2image('example.pdf', 'pdf_images', dpi=300)

参数说明:

  • dpi - 设置图像分辨率(建议200-300)
  • fmt - 输出格式(jpeg, png, tiff)
  • thread_count - 多线程处理加速提取
  • output_file - 输出文件名模式

两种方法对比

特性 PyPDF2 pdf2image
处理速度 中等 快速(支持多线程)
图像质量 原始质量 可调整DPI
扫描PDF支持 ❌ 不支持 ✅ 支持
外部依赖 需要Poppler
输出格式 多种格式 JPG/PNG/TIFF
推荐场景 简单PDF文档 专业级应用

常见问题与解决方案

1. 提取的图像质量差

使用pdf2image时增加DPI值:

images = convert_from_path('doc.pdf', dpi=300)

2. 内存占用过高

对于大型PDF,使用分页处理:

# 每次只处理一页
for page_num in range(10):  # 处理前10页
    images = convert_from_path('large.pdf', 
                             first_page=page_num+1, 
                             last_page=page_num+1)

3. 找不到Poppler路径

在代码中指定Poppler路径:

images = convert_from_path('doc.pdf', 
                         poppler_path=r'C:\path\to\poppler\bin')

提示: 处理扫描的PDF文档时,pdf2image是更好的选择,因为它实际上是将PDF页面转换为图像,而不是提取嵌入的图像对象。

总结

本文介绍了两种Python提取PDF图片的方法:

  1. PyPDF2 - 适合简单的PDF文档,纯Python实现,无需外部依赖
  2. pdf2image - 功能更强大,支持扫描文档和高质量输出,需要Poppler

对于大多数应用场景,推荐使用pdf2image库,尽管需要安装外部依赖,但它提供了更可靠的结果和更丰富的功能选项。

© 2023 Python PDF处理教程 | 本教程仅用于学习目的

发表评论