程序员文章、书籍推荐和程序员创业信息与资源分享平台

网站首页 > 技术文章 正文

3 行代码扒光 PDF 所有图片?Python 办公实战秘籍来了

hfteth 2025-08-01 16:57:20 技术文章 6 ℃

一、为什么要学 PDF 图片提取?

上周帮设计师同事处理一份 500 页的产品手册 PDF 时,他突然哀嚎:"这 200 张产品图得一张张截图到猴年马月?"—— 如果你也遇到过类似场景,那这篇实战文能让你少走 3 小时弯路。

PDF 里的图片藏得比快递单信息还深:直接右键 "另存为" 大概率灰显,截图又会损失画质。但用 Python,只需几行代码就能批量拽出所有图片,甚至保留原始分辨率。今天就用 pdfplumber 库,手把手教你把 PDF 里的图片 "连根拔起"。

二、准备工作:30 秒搭好环境

工欲善其事,必先利其器。我们需要两个核心库:

  • pdfplumber:PDF 解析的 "瑞士军刀",能精准定位图片在页面中的位置并提取原始数据
  • Pillow:Python 图像处理神器,负责把二进制数据转成可保存的图片格式

打开终端,输入两行安装命令:

bash

pip install pdfplumber  # 解析PDF的核心库
pip install pillow      # 处理图片的必备工具

安装完成后,随便找一份带图片的 PDF(比如公司产品手册、学术论文),记住它的存放路径(比如D:/test.pdf),我们马上开始实战。

三、核心代码:5 步扒光 PDF 图片

直接上能跑的核心代码,每一步都标注了原理,新手也能看懂:

python

import pdfplumber  # 用于解析PDF
import io          # 处理二进制流
from PIL import Image  # 保存图片

def extract_pdf_images(pdf_path):
    # 1. 打开PDF文件(with语句自动关闭文件,避免资源泄露)
    with pdfplumber.open(pdf_path) as pdf:
        # 2. 遍历PDF的每一页(i是页码索引,从0开始)
        for page_num, page in enumerate(pdf.pages, start=1):
            # 3. 遍历当前页的所有图片(j是图片索引)
            for img_num, img in enumerate(page.images):
                # 4. 提取图片的二进制数据流
                img_stream = img["stream"]  # 获取原始流数据
                img_data = img_stream.get_data()  # 提取二进制数据
                # 5. 把二进制数据转成图片并保存
                img_bytes = io.BytesIO(img_data)  # 模拟文件对象
                with Image.open(img_bytes) as image:
                    # 保存路径:图片_页码_序号.jpg(比如image_3_2.jpg表示第3页第2张图)
                    save_path = f"image_{page_num}_{img_num}.jpg"
                    image.save(save_path)
                    print(f"已保存:{save_path}")

# 调用函数:传入你的PDF路径
extract_pdf_images("D:/test.pdf")


运行这段代码后,打开你的 Python 脚本所在文件夹,会看到一堆以image_页码_序号.jpg命名的图片 —— 这就是从 PDF 里扒出来的原图。

四、代码拆解:为什么这么写?

很多人学代码只抄不理解,遇到问题就卡壳。这里拆解 3 个关键知识点,让你不仅会用,还知道原理:

  1. 为什么用with语句?
    with pdfplumber.open(...)和with Image.open(...)能自动关闭文件,哪怕中途报错(比如 PDF 损坏),也不会导致文件被占用。如果不用with,可能出现 "文件被另一个程序占用" 的报错。
  2. page.images里有什么?
    每个img是一个字典,包含图片的坐标、大小、数据流等信息。我们只需要"stream"键对应的数据流 —— 这是图片的 "原始密码",有了它就能还原图片。
  3. io.BytesIO是干嘛的?
    Pillow 库的Image.open()需要 "类似文件的对象",但我们从 PDF 里拿到的是二进制数据(类似一堆 0 和 1)。BytesIO能把二进制数据 "伪装" 成文件,让 Pillow 能正常打开。

五、实战踩坑:这些问题 90% 的人会遇到

我用 100 + 份 PDF 测试过这个代码,总结了 3 个高频坑和解决办法:

  1. 报错 "文件不存在"
    原因:PDF 路径写错了(比如多写了空格、字母大小写错误)。
    解决:右键 PDF 文件→"属性"→复制 "位置" 和 "文件名",拼接成路径(比如C:/Users/Admin/Desktop/test.pdf)。
  2. 能运行但没图片?
    可能是这两种情况:PDF 是扫描件(本质是图片拼成的 PDF):这种需要 OCR 工具(比如 pytesseract)先转文字,再提取图片。图片被加密:用 Adobe Acrobat 解密后再试,或用pikepdf库解除密码限制。
  3. 图片保存后是空白 / 损坏?
    原因:部分 PDF 的图片用了特殊编码(比如 JPEG2000)。
    解决:在image.save()前加一行image = image.convert("RGB"),强制转成通用格式。

六、进阶技巧:让代码更实用

学会基础功能后,这 3 个进阶技巧能大幅提升效率:

  • 批量处理多个 PDF:用os.listdir()遍历文件夹里的所有 PDF,循环调用提取函数:

python

import os
for file in os.listdir("D:/pdfs"):
    if file.endswith(".pdf"):
        extract_pdf_images(f"D:/pdfs/{file}")


  • 指定保存路径:不想让图片堆在脚本文件夹?改save_path为绝对路径即可:
    save_path = f"D:/extracted_images/image_{page_num}_{img_num}.jpg"
  • 过滤小图片:想跳过图标、水印等无用图片?加一行判断图片大小的代码:

python

if img["width"] > 200 and img["height"] > 200:  # 只保存宽高>200像素的图片
    # 执行保存逻辑

七、总结:3 分钟搞定别人 3 小时的活

用 Python 提取 PDF 图片,核心就是 3 步:用 pdfplumber 解析 PDF→提取图片二进制数据→用 Pillow 保存。这套方法比手动截图快 100 倍,尤其适合需要批量处理的场景(比如整理 100 份论文里的图表)。

最后提醒:如果遇到复杂 PDF(加密、扫描件、特殊格式),可以试试其他库(比如 PyMuPDF 处理加密 PDF,pytesseract 处理扫描件),但 pdfplumber 的简洁性,足够应对 90% 的日常需求。

现在打开你的 PDF,复制上面的代码跑一遍 —— 亲眼看到图片从 PDF 里 "跳" 出来的瞬间,你会回来感谢我的。


感谢关注【AI码力】,获取更多Python秘籍!

Tags:

最近发表
标签列表