"""PDF → images PNG 300 dpi avec cache par hash SHA256.""" import hashlib import os from pathlib import Path from pdf2image import convert_from_path from PIL import Image DEFAULT_DPI = 300 CACHE_ROOT = Path(".cache/images") def pdf_hash(pdf_path: str) -> str: """Hash SHA256 court du contenu PDF.""" h = hashlib.sha256() with open(pdf_path, "rb") as f: for chunk in iter(lambda: f.read(65536), b""): h.update(chunk) return h.hexdigest()[:16] def pdf_to_images(pdf_path: str, dpi: int = DEFAULT_DPI, cache_root: Path = CACHE_ROOT) -> list[Path]: """Convertit un PDF en PNG 300 dpi. Retourne la liste des chemins (1 par page). Le cache est indexé par hash du PDF : un PDF inchangé n'est jamais reconverti. """ cache_root = Path(cache_root) h = pdf_hash(pdf_path) out_dir = cache_root / h out_dir.mkdir(parents=True, exist_ok=True) existing = sorted(out_dir.glob("page_*.png")) if existing: return existing pages = convert_from_path(pdf_path, dpi) paths = [] for i, img in enumerate(pages, 1): p = out_dir / f"page_{i:02d}.png" img.save(p, "PNG", optimize=True) paths.append(p) return paths def load_image(path: Path) -> Image.Image: return Image.open(path)