You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python从PDF提取带页码、页面坐标信息的无失真图片

Python实现带坐标元信息的PDF图片无损提取方案

核心思路

直接提取PDF内嵌的原始图片对象,不做整页渲染截图,正确处理图片的透明蒙版、色彩空间转换逻辑,对齐Java PDFBox的提取效果,同时保留页码、页面坐标元数据,完全匹配指定命名规则,规避现有开源库常见的黑底、画质损失、文字覆盖问题。

前置依赖安装

执行以下命令安装需要的依赖包:

pip install pdfplumber pillow

可直接运行的实现代码

import pdfplumber
from PIL import Image
import io
import os

def extract_pdf_images(pdf_path: str, output_dir: str):
    # 输出目录不存在则创建
    os.makedirs(output_dir, exist_ok=True)
    with pdfplumber.open(pdf_path) as pdf:
        # 遍历所有页面,页码从1开始计数
        for page_num, page in enumerate(pdf.pages, start=1):
            page_img_serial = 1
            # 遍历当前页所有内嵌图片对象
            for img_meta in page.images:
                try:
                    # 读取图片原始流数据
                    raw_stream = img_meta["stream"].get_data()
                    img = Image.open(io.BytesIO(raw_stream))

                    # 处理SMask透明蒙版,解决透明区域变黑的问题
                    if "SMask" in img_meta:
                        mask_stream = img_meta["SMask"].get_data()
                        alpha_mask = Image.open(io.BytesIO(mask_stream)).convert("L")
                        if img.mode != "RGBA":
                            img = img.convert("RGBA")
                        img.putalpha(alpha_mask)

                    # 处理CMYK色彩空间转RGB,避免色偏、黑底异常
                    if img.mode == "CMYK":
                        img = img.convert("RGB")

                    # 按指定规则生成文件名,坐标保留2位小数避免文件名过长
                    # 注:如果需要PDF原生左下角原点的Y坐标,替换为img_meta["y0"]、img_meta["y1"]即可
                    x1 = round(img_meta["x0"], 2)
                    x2 = round(img_meta["x1"], 2)
                    y1 = round(img_meta["top"], 2)
                    y2 = round(img_meta["bottom"], 2)
                    file_name = f"image_{page_num}_{page_img_serial}_{x1}_{x2}__{y1}_{y2}.png"

                    # 保存为PNG格式
                    img.save(os.path.join(output_dir, file_name), format="PNG")
                    page_img_serial += 1
                except Exception:
                    # 跳过损坏、无法解析的图片流,对齐PDFBox的容错逻辑
                    page_img_serial += 1
                    continue

# 调用示例
if __name__ == "__main__":
    extract_pdf_images("target.pdf", "./extracted_images")

关键问题说明

  • 拒绝渲染截图方案:整页渲染后裁剪的方式本质是对页面做二次栅格化,不仅会压缩原图分辨率导致画质下降,还会将同坐标位置的文字、矢量线条一并截取,必然出现文字覆盖图片的问题,本方案直接提取PDF内嵌的原始图片资源,不存在该问题。
  • 解决黑底、文字遮挡异常:之前测试pdfminer.six、PyMuPDF出现的黑底问题,核心原因是这类库默认没有正确处理图片附带的SMask透明通道,也没有做CMYK到RGB的正确色彩转换,透明区域被默认填充为黑色;本方案专门补全了这部分处理逻辑,提取效果和Java版PDFBox一致,不会出现这类异常。
  • 坐标适配:代码默认使用左上角为原点的页面坐标(和多数PDF预览工具的坐标体系对齐),如果需要使用PDF标准的左下角原点坐标,只需将文件名生成部分的y1、y2替换为img_meta["y0"]、img_meta["y1"]即可。

内容的提问来源于stack exchange,提问作者peter.murray.rust

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 04:24:15