""" Crop Killer Sudoku PDF ray-casting metodou: 1. Horizontální paprsek na y_mid → najde x_left, x_right mřížky 2. Vertikální paprsek podél x_left → najde top_cut, bot_cut mřížky Výsledek: oříznuté PDF jen s mřížkou + malý bílý rámeček (MARGIN). """ import fitz from pathlib import Path MARGIN = 4 # pt bílého rámečku kolem mřížky SRC = Path(r"U:/ordinaceprojekt/SběrDatRůzné/SudokuKiller/Testy/2009-05-04 Puzzle SudokuKiller 376 [difficulty 4 of 10] [average solving time 30 min].pdf") DST = Path(r"U:/ordinaceprojekt/SběrDatRůzné/SudokuKiller/Testy/cropped_raycast.pdf") def crop_raycast(src_path: Path, dst_path: Path, margin: float = MARGIN): doc = fitz.open(str(src_path)) page = doc[0] paths = page.get_drawings() pw = page.mediabox.width ph = page.mediabox.height y_mid = ph / 2 # Krok 1: horizontální paprsek na y_mid → x_left, x_right hit_h = [p["rect"] for p in paths if p["rect"].y0 <= y_mid <= p["rect"].y1] if not hit_h: raise ValueError("Horizontální paprsek nenašel žádné kresby na y_mid") # Elementy z horizontálního paprsku jsou výhradně mřížka (nadpis/copyright # jsou daleko od y_mid) — jejich y rozsah přímo dává top/bot hranici mřížky. x_left = min(r.x0 for r in hit_h) x_right = max(r.x1 for r in hit_h) top_cut = min(r.y0 for r in hit_h) bot_cut = max(r.y1 for r in hit_h) print(f"x_left={x_left:.1f} x_right={x_right:.1f}") print(f"top_cut={top_cut:.1f} bot_cut={bot_cut:.1f}") print(f"stránka: {pw:.1f} x {ph:.1f} pt") clip = fitz.Rect( x_left - margin, top_cut - margin, x_right + margin, bot_cut + margin, ) clip_w = clip.width clip_h = clip.height doc_new = fitz.open() p = doc_new.new_page(width=clip_w, height=clip_h) p.show_pdf_page(fitz.Rect(0, 0, clip_w, clip_h), doc, 0, clip=clip) doc_new.save(str(dst_path)) doc.close() doc_new.close() print(f"Uloženo: {dst_path} ({clip_w:.1f} x {clip_h:.1f} pt)") crop_raycast(SRC, DST)