Files
pp-qa-km/tools/convert/to_image.py
LittleYellow cfd1876359 轉換工具強化:失敗診斷訊息 + 舊版格式升版 + 掃描 PDF vision fallback
- convert.py:轉換失敗改印例外型別、批次尾端彙總、--traceback 旗標;
  空白轉換結果示警(避免純圖片 docx 等假成功靜默入庫)
- from_legacy.py(B):.doc/.xls/.ppt 經本地 LibreOffice headless 升版為
  現代格式後再走既有轉換器;raw/originals 仍保存真正的舊格式原始檔
- to_image.py + from_vision.py(A):needs_ocr 的掃描/圖片型 PDF 逐頁
  render → 本地 vision 模型轉錄(--vision);:cloud/未設定防護,
  模型設定走 config/models.yaml 的 tasks.vision(預設不啟用)
- kb.ollama_chat 加 images 參數(向後相容);models.yaml 加 vision 範例
- selfcheck 補 legacy 路由、to_image 真測、from_vision 注入測、
  --vision 端到端,全數 ALL PASS

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-21 07:00:32 +08:00

49 lines
1.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""PDF 頁 → PNG 影像pymupdfdeterministic、全程本地
供 vision fallback 使用文字抽取失敗needs_ocr的掃描/圖片型 PDF 逐頁 render
成影像後,交給 from_vision.py 以本地 vision 模型判讀。render 本身不含任何 LLM
維持「deterministic 工具做結構、LLM 只做語意」的分工AGENTS.md §3 稽核原則)。
可獨立執行python tools/convert/to_image.py <file.pdf> --out DIR [--dpi 150]
"""
import argparse
import pathlib
import fitz # pymupdf
# ponytail: 預設 150 DPI 是「可讀性 vs 影像大小/推論成本」的折衷;掃描件文字偏小時
# 可調高。升級路徑:依頁面尺寸/內容自適應 DPI。
DEFAULT_DPI = 150
def render_pdf_pages(src, out_dir, dpi=DEFAULT_DPI, prefix="page"):
"""將 src 每頁 render 成 PNG回傳影像路徑列表依頁序"""
src = pathlib.Path(src)
out_dir = pathlib.Path(out_dir)
out_dir.mkdir(parents=True, exist_ok=True)
paths = []
doc = fitz.open(str(src))
try:
for i, page in enumerate(doc, 1):
pix = page.get_pixmap(dpi=dpi)
p = out_dir / f"{prefix}{i}.png"
pix.save(str(p))
paths.append(p)
finally:
doc.close()
return paths
def main(argv=None):
ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument("src")
ap.add_argument("--out", required=True, help="影像輸出目錄")
ap.add_argument("--dpi", type=int, default=DEFAULT_DPI)
a = ap.parse_args(argv)
paths = render_pdf_pages(a.src, a.out, a.dpi)
print(f"{len(paths)} 頁 → {a.out}")
if __name__ == "__main__":
main()