pdf_README.md 7.7 KB

PDF处理模块重构说明

📦 模块结构

PDF处理功能已重构为4个模块,便于维护和理解:

ocr_utils/
├── pdf_utils.py                    # 主入口 - 高级API和向后兼容包装
├── pdf_coordinate_transform.py     # 坐标转换功能
├── pdf_text_extraction.py          # 文本提取功能  
├── pdf_image_rendering.py          # 图像渲染功能
└── pdf_README.md                   # 本文档

🔧 各模块功能

1. pdf_utils.py (主入口,~400行)

作用: 高级API和统一入口,保持向后兼容性

主要类: PDFUtils

核心功能:

  • load_and_classify_document(): 加载文档(PDF/图片)并分类
  • merge_cross_page_tables(): 跨页表格合并(TODO)
  • 所有子模块函数的重新导出(向后兼容)

使用示例:

from ocr_utils.pdf_utils import PDFUtils

# 加载PDF并分类
images, pdf_type, pdf_doc, renderer = PDFUtils.load_and_classify_document(
    document_path=Path("test.pdf"),
    dpi=200,
    page_range="1-5",
    renderer="fitz"
)

2. pdf_coordinate_transform.py (~250行)

作用: PDF坐标系与图像坐标系的转换

核心函数:

  • pdf_rotation_to_image_rotation(): PDF旋转角度转换为图片旋转角度
  • transform_bbox_for_rotation_fitz(): fitz引擎的完整几何坐标变换
  • transform_bbox_for_rotation_pypdfium2(): pypdfium2引擎的坐标值交换

坐标系说明:

  • PDF坐标系: 左下角原点 (0,0),X向右,Y向上
  • 图像坐标系: 左上角原点 (0,0),X向右,Y向下

旋转定义(重要):

  • PDF rotation: 0/90/180/270度(顺时针旋转,PDF规范)
  • 图片rotation: 0/90/180/270度(逆时针旋转,图像处理标准)
  • 对外API统一返回图片rotation(逆时针定义)

旋转转换映射: | PDF Rotation (顺时针) | 图片 Rotation (逆时针) | |---------------------|---------------------| | 0° | 0° | | 90° | 270° | | 180° | 180° | | 270° | 90° |

关键区别: | 特性 | fitz | pypdfium2 | |------|------|-----------| | 输入坐标系 | PDF原始坐标系 | 已旋转的坐标系(但bbox顺序错误) | | 变换类型 | 几何空间变换 | 坐标值交换(修正min/max) | | 复杂度 | 高(涉及旋转公式) | 低(只是交换) |

使用示例:

from ocr_utils.pdf_coordinate_transform import transform_bbox_for_rotation_fitz

# fitz引擎: 完整几何变换
img_bbox = transform_bbox_for_rotation_fitz(
    bbox=[100, 50, 200, 100],
    rotation=90,
    pdf_width=595,
    pdf_height=842,
    scale=2.778
)

3. pdf_text_extraction.py (~450行)

作用: 从PDF提取文本,支持rotation处理

核心函数:

  • extract_text_from_pdf(): 从指定区域提取文本(自动检测引擎)
  • extract_all_text_blocks(): 提取页面所有文本块(自动检测引擎)
  • detect_pdf_doc_type(): 检测PDF文档类型(fitz/pypdfium2)
  • bbox_overlap(): 检查bbox重叠

支持引擎:

  • pypdfium2: MinerU标准引擎
  • fitz (PyMuPDF): 轻量级替代引擎

使用示例:

from ocr_utils.pdf_text_extraction import extract_all_text_blocks

# 提取所有文本块(自动应用rotation变换)
text_blocks, rotation = extract_all_text_blocks(
    pdf_doc=pdf_doc,
    page_idx=0,
    scale=2.778
)

# 返回格式:
# text_blocks = [
#     {'text': 'Hello', 'bbox': [x1, y1, x2, y2], 'origin_bbox': [...]},
#     ...
# ]
# rotation = 270  # 图片旋转角度:0/90/180/270(逆时针)
#                 # 注意:返回的是图片旋转定义(逆时针),不是PDF rotation(顺时针)

⚠️ 重要说明:

  • rotation 返回值采用图片旋转定义(逆时针),不是PDF rotation(顺时针)
  • PDF rotation 90° → 返回 270°(图片需要逆时针旋转270°)
  • PDF rotation 270° → 返回 90°(图片需要逆时针旋转90°)

4. pdf_image_rendering.py (~300行)

作用: PDF页面渲染为图像

核心函数:

  • load_images_from_pdf_unified(): 统一的PDF图像加载接口
  • load_images_pypdfium2(): 使用pypdfium2渲染
  • load_images_fitz(): 使用fitz渲染

渲染引擎对比: | 特性 | pypdfium2 | fitz | |------|-----------|------| | 渲染引擎 | Chrome PDFium | MuPDF | | 多进程加速 | ✅ (非Windows) | ❌ | | 超时控制 | ✅ | ❌ | | 尺寸限制 | 3500px | 4500px | | 超限处理 | 动态调整scale | 降到72 DPI | | MinerU标准 | ✅ | ❌ |

使用示例:

from ocr_utils.pdf_image_rendering import load_images_from_pdf_unified

# 使用pypdfium2(推荐)
images, doc = load_images_from_pdf_unified(
    pdf_bytes=pdf_bytes,
    dpi=200,
    renderer="pypdfium2",
    threads=4
)

# 使用fitz
images, doc = load_images_from_pdf_unified(
    pdf_bytes=pdf_bytes,
    dpi=200,
    renderer="fitz"
)

# 返回格式:
# images = [
#     {'img_pil': PIL.Image, 'scale': 2.778},
#     ...
# ]

🔄 向后兼容性

所有原有代码无需修改!

PDFUtils类保留了所有原有方法作为包装函数,内部调用新模块的功能:

# 旧代码继续工作
from ocr_utils.pdf_utils import PDFUtils

# 所有这些方法仍然可用:
PDFUtils.extract_text_from_pdf(...)
PDFUtils.extract_all_text_blocks(...)
PDFUtils.load_images_from_pdf_unified(...)
PDFUtils._transform_bbox_for_rotation_fitz(...)
# ... 等等

📝 最佳实践

1. 新代码: 直接导入子模块

# 推荐: 直接从子模块导入
from ocr_utils.pdf_text_extraction import extract_all_text_blocks
from ocr_utils.pdf_coordinate_transform import transform_bbox_for_rotation_fitz

text_blocks, rotation = extract_all_text_blocks(pdf_doc, 0, 2.778)

2. 旧代码: 继续使用PDFUtils

# 兼容: 通过PDFUtils类使用
from ocr_utils.pdf_utils import PDFUtils

text_blocks, rotation = PDFUtils.extract_all_text_blocks(pdf_doc, 0, 2.778)

3. 渲染引擎选择

# 生产环境推荐: pypdfium2 (MinerU标准)
renderer = "pypdfium2"  # 多进程加速,更好的细节保留

# 开发/测试: fitz (简单轻量)
renderer = "fitz"  # 无需额外依赖,单进程

🎯 重构优势

  1. 代码组织: 从单个984行文件 → 4个模块,每个200-450行
  2. 职责清晰: 坐标变换、文本提取、图像渲染各自独立
  3. 易于测试: 各模块可独立测试
  4. 向后兼容: 现有代码无需修改
  5. 易于扩展: 新功能可加入对应模块,不影响其他部分

✅ 测试验证

重构后通过完整测试验证:

  • ✅ 所有8个rotation测试通过 (4种rotation × 2种引擎)
  • ✅ fitz引擎: rotation 0°/90°/180°/270° 全部正确
  • ✅ pypdfium2引擎: rotation 0°/90°/180°/270° 全部正确
  • ✅ 坐标都在图像边界内
  • ✅ 向后兼容性验证通过

测试命令:

cd ocr_tools/universal_doc_parser/tests
python test_pdf_rotation.py

📚 相关文档

🔧 维护指南

添加新功能

根据功能类型选择合适的模块:

  1. 坐标转换相关pdf_coordinate_transform.py
  2. 文本提取相关pdf_text_extraction.py
  3. 图像渲染相关pdf_image_rendering.py
  4. 高级API/工作流pdf_utils.py

修改现有功能

  1. 在对应子模块中修改实现
  2. 如果改变了函数签名,需在pdf_utils.py中更新包装函数
  3. 运行测试验证: python test_pdf_rotation.py

重构日期: 2026-01-05
重构原因: pdf_utils.py文件过大(984行),难以维护
重构目标: 按功能层次拆分,提高可维护性,保持向后兼容性