济南市护送服务网

Python借助 Spire.PDF for Python提取PDF图片的终极指南

2026-04-09 11:00:04 浏览次数:0
详细信息

Python 使用 Spire.PDF for Python 提取 PDF 图片的完整指南

Spire.PDF for Python 是一个强大的 PDF 处理库,可以用于提取 PDF 中的图片。以下是详细的使用指南:

1. 安装与准备

安装 Spire.PDF

pip install Spire.PDF

2. 基础图片提取示例

示例 1:提取所有图片到指定文件夹

from spire.pdf import *
from spire.pdf.common import *

def extract_all_images(pdf_path, output_folder):
    """
    提取PDF中的所有图片
    """
    # 创建PDF文档对象
    pdf = PdfDocument()

    # 加载PDF文件
    pdf.LoadFromFile(pdf_path)

    # 创建图像提取器
    image_extractor = ImageExtractor(pdf)

    # 遍历所有页面
    for page_index in range(pdf.Pages.Count):
        page = pdf.Pages.get_Item(page_index)

        # 获取当前页面的图片
        images = image_extractor.ExtractImages(page_index)

        # 保存图片
        for i, image in enumerate(images):
            # 构建文件名
            filename = f"{output_folder}/page_{page_index + 1}_img_{i + 1}.png"

            # 保存为PNG格式
            image.Save(filename, ImageFormat.get_Png())
            print(f"保存图片: {filename}")

    # 关闭文档
    pdf.Close()

# 使用示例
if __name__ == "__main__":
    extract_all_images("input.pdf", "./extracted_images")

示例 2:提取特定格式的图片

def extract_images_by_format(pdf_path, output_folder, image_format="png"):
    """
    按指定格式提取图片
    """
    pdf = PdfDocument()
    pdf.LoadFromFile(pdf_path)

    image_extractor = ImageExtractor(pdf)

    # 支持的格式映射
    format_mapping = {
        "png": ImageFormat.get_Png(),
        "jpg": ImageFormat.get_Jpeg(),
        "jpeg": ImageFormat.get_Jpeg(),
        "bmp": ImageFormat.get_Bmp(),
        "tiff": ImageFormat.get_Tiff(),
    }

    if image_format.lower() not in format_mapping:
        raise ValueError(f"不支持的格式: {image_format}")

    selected_format = format_mapping[image_format.lower()]

    for page_index in range(pdf.Pages.Count):
        images = image_extractor.ExtractImages(page_index)

        for i, image in enumerate(images):
            filename = f"{output_folder}/page_{page_index + 1}_img_{i + 1}.{image_format}"
            image.Save(filename, selected_format)
            print(f"保存图片: {filename}")

    pdf.Close()

3. 高级提取功能

示例 3:提取特定页面范围的图片

def extract_images_by_page_range(pdf_path, output_folder, start_page=1, end_page=None):
    """
    提取指定页面范围内的图片
    """
    pdf = PdfDocument()
    pdf.LoadFromFile(pdf_path)

    # 如果未指定结束页,则提取到最后
    if end_page is None or end_page > pdf.Pages.Count:
        end_page = pdf.Pages.Count

    image_extractor = ImageExtractor(pdf)

    for page_index in range(start_page - 1, end_page):
        images = image_extractor.ExtractImages(page_index)

        if len(images) > 0:
            print(f"第 {page_index + 1} 页找到 {len(images)} 张图片")

            for i, image in enumerate(images):
                # 获取图片尺寸信息
                width = image.Width
                height = image.Height

                filename = f"{output_folder}/page_{page_index + 1}_img_{i + 1}_{width}x{height}.png"
                image.Save(filename, ImageFormat.get_Png())

    pdf.Close()

示例 4:按尺寸筛选图片

def extract_images_by_size(pdf_path, output_folder, min_width=100, min_height=100):
    """
    只提取尺寸大于指定最小值的图片
    """
    pdf = PdfDocument()
    pdf.LoadFromFile(pdf_path)

    image_extractor = ImageExtractor(pdf)
    saved_count = 0

    for page_index in range(pdf.Pages.Count):
        images = image_extractor.ExtractImages(page_index)

        for i, image in enumerate(images):
            # 检查图片尺寸
            if image.Width >= min_width and image.Height >= min_height:
                saved_count += 1
                filename = f"{output_folder}/image_{saved_count:03d}.png"
                image.Save(filename, ImageFormat.get_Png())
                print(f"保存图片 {saved_count}: {filename} ({image.Width}x{image.Height})")
            else:
                print(f"跳过小图片: {image.Width}x{image.Height}")

    print(f"\n共提取 {saved_count} 张符合条件的图片")
    pdf.Close()

4. 提取并处理图片信息

示例 5:提取图片并保存元数据

import json

def extract_images_with_metadata(pdf_path, output_folder):
    """
    提取图片并保存元数据
    """
    pdf = PdfDocument()
    pdf.LoadFromFile(pdf_path)

    image_extractor = ImageExtractor(pdf)
    metadata = []

    for page_index in range(pdf.Pages.Count):
        images = image_extractor.ExtractImages(page_index)

        for i, image in enumerate(images):
            # 创建唯一文件名
            import uuid
            unique_id = str(uuid.uuid4())[:8]
            filename = f"image_{unique_id}.png"
            filepath = f"{output_folder}/{filename}"

            # 保存图片
            image.Save(filepath, ImageFormat.get_Png())

            # 收集元数据
            img_info = {
                "filename": filename,
                "page": page_index + 1,
                "index": i + 1,
                "width": image.Width,
                "height": image.Height,
                "horizontal_resolution": image.HorizontalResolution,
                "vertical_resolution": image.VerticalResolution,
                "file_size": image.RawFormat  # 可以添加实际文件大小
            }
            metadata.append(img_info)

    # 保存元数据到JSON文件
    metadata_file = f"{output_folder}/metadata.json"
    with open(metadata_file, 'w', encoding='utf-8') as f:
        json.dump(metadata, f, ensure_ascii=False, indent=2)

    print(f"元数据已保存到: {metadata_file}")
    pdf.Close()

示例 6:批量处理多个PDF文件

import os

def batch_extract_images(pdf_folder, output_base_folder):
    """
    批量处理多个PDF文件
    """
    # 确保输出文件夹存在
    if not os.path.exists(output_base_folder):
        os.makedirs(output_base_folder)

    # 遍历PDF文件夹
    for filename in os.listdir(pdf_folder):
        if filename.lower().endswith('.pdf'):
            pdf_path = os.path.join(pdf_folder, filename)

            # 为每个PDF创建独立的输出文件夹
            pdf_name = os.path.splitext(filename)[0]
            output_folder = os.path.join(output_base_folder, pdf_name)

            if not os.path.exists(output_folder):
                os.makedirs(output_folder)

            print(f"\n处理文件: {filename}")
            print(f"输出到: {output_folder}")

            try:
                extract_all_images(pdf_path, output_folder)
                print(f"完成: {filename}")
            except Exception as e:
                print(f"处理失败 {filename}: {str(e)}")

5. 错误处理和优化

示例 7:带有错误处理的完整解决方案

def safe_extract_images(pdf_path, output_folder):
    """
    带有完整错误处理的图片提取函数
    """
    pdf = None
    try:
        # 检查输入文件
        if not os.path.exists(pdf_path):
            raise FileNotFoundError(f"PDF文件不存在: {pdf_path}")

        # 检查输出文件夹
        if not os.path.exists(output_folder):
            os.makedirs(output_folder)

        # 初始化PDF文档
        pdf = PdfDocument()
        pdf.LoadFromFile(pdf_path)

        # 检查是否成功加载
        if pdf.Pages.Count == 0:
            print("警告: PDF文件为空或无法读取")
            return

        image_extractor = ImageExtractor(pdf)
        total_images = 0

        print(f"开始处理: {os.path.basename(pdf_path)}")
        print(f"总页数: {pdf.Pages.Count}")

        # 逐页提取
        for page_index in range(pdf.Pages.Count):
            try:
                images = image_extractor.ExtractImages(page_index)
                page_images_count = len(images)
                total_images += page_images_count

                if page_images_count > 0:
                    print(f"  第 {page_index + 1} 页: 找到 {page_images_count} 张图片")

                    for i, image in enumerate(images):
                        try:
                            # 生成安全的文件名
                            safe_index = i + 1
                            filename = f"page_{page_index + 1:03d}_img_{safe_index:03d}.png"
                            filepath = os.path.join(output_folder, filename)

                            # 保存图片
                            image.Save(filepath, ImageFormat.get_Png())
                        except Exception as img_error:
                            print(f"      保存图片 {i+1} 失败: {str(img_error)}")

            except Exception as page_error:
                print(f"  处理第 {page_index + 1} 页时出错: {str(page_error)}")
                continue

        print(f"\n处理完成!")
        print(f"总提取图片数: {total_images}")

    except Exception as e:
        print(f"发生错误: {str(e)}")
        raise

    finally:
        # 确保文档被关闭
        if pdf is not None:
            pdf.Close()

6. 使用示例脚本

完整的命令行工具示例

import argparse
import sys

def main():
    parser = argparse.ArgumentParser(description='从PDF中提取图片')
    parser.add_argument('input', help='输入PDF文件路径')
    parser.add_argument('-o', '--output', default='./extracted_images', 
                       help='输出文件夹路径 (默认: ./extracted_images)')
    parser.add_argument('-f', '--format', default='png', 
                       choices=['png', 'jpg', 'jpeg', 'bmp', 'tiff'],
                       help='输出图片格式 (默认: png)')
    parser.add_argument('--min-width', type=int, default=50,
                       help='最小图片宽度 (默认: 50)')
    parser.add_argument('--min-height', type=int, default=50,
                       help='最小图片高度 (默认: 50)')

    args = parser.parse_args()

    try:
        # 创建输出目录
        import os
        if not os.path.exists(args.output):
            os.makedirs(args.output)

        # 提取图片
        pdf = PdfDocument()
        pdf.LoadFromFile(args.input)

        image_extractor = ImageExtractor(pdf)
        image_count = 0

        for page_index in range(pdf.Pages.Count):
            images = image_extractor.ExtractImages(page_index)

            for i, image in enumerate(images):
                if image.Width >= args.min_width and image.Height >= args.min_height:
                    image_count += 1

                    # 根据格式保存
                    if args.format == 'png':
                        filename = f"{args.output}/image_{image_count:04d}.png"
                        image.Save(filename, ImageFormat.get_Png())
                    elif args.format in ['jpg', 'jpeg']:
                        filename = f"{args.output}/image_{image_count:04d}.jpg"
                        image.Save(filename, ImageFormat.get_Jpeg())
                    elif args.format == 'bmp':
                        filename = f"{args.output}/image_{image_count:04d}.bmp"
                        image.Save(filename, ImageFormat.get_Bmp())
                    elif args.format == 'tiff':
                        filename = f"{args.output}/image_{image_count:04d}.tiff"
                        image.Save(filename, ImageFormat.get_Tiff())

                    print(f"保存: {filename} ({image.Width}x{image.Height})")

        pdf.Close()
        print(f"\n完成! 共提取 {image_count} 张图片到 {args.output}")

    except Exception as e:
        print(f"错误: {str(e)}", file=sys.stderr)
        sys.exit(1)

if __name__ == "__main__":
    main()

使用建议和注意事项

许可证要求:Spire.PDF 需要有效的许可证才能使用所有功能 内存管理:处理大文件时注意内存使用,及时关闭文档 图片质量:提取的图片质量取决于PDF中嵌入的原始图片质量 格式支持:支持PNG、JPEG、BMP、TIFF等常见格式 性能优化:批量处理时可以考虑使用多线程

这个指南涵盖了从基础到高级的各种使用场景,你可以根据具体需求选择合适的方法。记得在实际使用前先测试代码,并根据具体需求进行调整。

相关推荐