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

如何用PyMuPDF(fitz)提取PDF图片及其关联标注或说明?

基于PyMuPDF提取PDF文本、图片及关联标注

我需要用PyMuPDF(fitz)编写脚本,完成以下任务:

  • 提取PDF中的文本、超链接与图片
  • 获取图片附近的标注/说明(重点是课件、学术论文里图片上下方的内容)
  • 结构化输出这些内容,作为后续生成Jupyter Book格式MyST Markdown课件笔记的数据源,供AI代理处理生成带规范图片引用的高质量笔记

改进后的实现代码

import fitz
import os

# 配置路径
pdf_folder = "pdf_files"  # 存放PDF的文件夹
output_folder = "output"  # 输出文件夹
image_dir = os.path.join(output_folder, "images")

# 创建输出目录(已存在则跳过)
os.makedirs(output_folder, exist_ok=True)
os.makedirs(image_dir, exist_ok=True)

# 批量处理文件夹内的PDF文件
for pdf_file in os.listdir(pdf_folder):
    if not pdf_file.endswith(".pdf"):
        continue
    
    pdf_path = os.path.join(pdf_folder, pdf_file)
    base_name = os.path.splitext(pdf_file)[0]
    output_txt = os.path.join(output_folder, f"{base_name}.txt")
    
    doc = fitz.open(pdf_path)
    text_content = []
    
    for page_num in range(len(doc)):
        page = doc[page_num]
        page_num_display = page_num + 1
        
        # 提取整页文本
        full_text = page.get_text()
        text_content.append(f"--- 第 {page_num_display} 页 文本内容 ---")
        text_content.append(full_text)
        
        # 提取超链接
        links = page.get_links()
        if links:
            text_content.append(f"\n--- 第 {page_num_display} 页 超链接 ---")
            for link in links:
                if "uri" in link:
                    text_content.append(f"链接: {link['uri']}")
        
        # 提取图片及关联标注
        images = page.get_images(full=True)
        if images:
            text_content.append(f"\n--- 第 {page_num_display} 页 图片及标注 ---")
            
            # 获取页面所有带位置信息的文本块
            text_blocks = page.get_text("blocks")
            
            for img_index, img in enumerate(images):
                xref = img[0]
                base_image = doc.extract_image(xref)
                image_bytes = base_image["image"]
                image_filename = os.path.join(image_dir, f"{base_name}_page_{page_num_display}_img_{img_index + 1}.png")
                
                # 保存图片到指定目录
                with open(image_filename, "wb") as img_file:
                    img_file.write(image_bytes)
                
                # 获取图片的精确边界框
                img_rect = page.get_image_rects(xref)[0]
                img_x0, img_y0, img_x1, img_y1 = img_rect
                
                # 定义图片上下搜索区域(上下各扩展50像素,可根据PDF排版调整)
                search_top = max(0, img_y0 - 50)
                search_bottom = img_y1 + 50
                search_rect = fitz.Rect(img_x0, search_top, img_x1, search_bottom)
                
                # 筛选搜索区域内的文本块作为图片标注
                caption_text = []
                for block in text_blocks:
                    block_rect = fitz.Rect(block[:4])
                    if block_rect.intersects(search_rect):
                        caption_text.append(block[4].strip())
                
                # 合并标注文本(无标注则显示提示)
                caption = "\n".join(caption_text) if caption_text else "无关联标注"
                
                # 结构化记录图片信息
                text_content.append(f"\n图片 {img_index + 1}:")
                text_content.append(f"保存路径: {image_filename}")
                text_content.append(f"关联标注:\n{caption}")
        
        # 添加分页分隔符,便于后续解析
        text_content.append("\n==================== 分页分隔符 ====================\n")
    
    # 将结构化内容写入输出文件
    with open(output_txt, "w", encoding="utf-8") as txt_file:
        txt_file.write("\n".join(text_content))
    
    doc.close()
    print(f"处理完成: '{pdf_file}',结果保存至 '{output_txt}',图片保存至 '{image_dir}'")

关键功能说明

  1. 图片位置与搜索区域

    • 通过page.get_image_rects(xref)获取图片的精确坐标边界框
    • 以图片为中心,上下各扩展指定像素(示例为50)作为标注搜索范围,可根据不同PDF的排版密度调整数值
  2. 文本块筛选逻辑

    • 用page.get_text("blocks")获取页面所有带坐标信息的文本块
    • 通过判断文本块与搜索区域的重叠关系,精准筛选出图片附近的文本作为关联标注
  3. 结构化输出

    • 按分页、内容类别(文本/链接/图片)组织输出内容,清晰的分隔符和结构化记录方便后续AI代理解析,直接生成符合MyST Markdown规范的课件笔记

内容的提问来源于stack exchange,提问作者abdul_21

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 22:33:11