""" Změří finální puzzle, spočítá layout "2PuzzleOnA4" a uloží do layouts.json. """ import json import fitz from pathlib import Path 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") JSON_PATH = Path(r"U:/ordinaceprojekt/SběrDatRůzné/SudokuKiller/layouts.json") A4_W_PT = 595.276 A4_H_PT = 841.890 CROP_MARGIN = 2 TARGET_SCALE = 1.10 # 110 % — to co se nám líbilo def pt_to_mm(pt): return round(pt / 72 * 25.4, 2) def detect_clip(page) -> fitz.Rect: paths = page.get_drawings() y_mid = page.mediabox.height / 2 hit_h = [(p["rect"], p.get("width") or 0) for p in paths if p["rect"].y0 <= y_mid <= p["rect"].y1] rects = [r for r, _ in hit_h] x_left = min(r.x0 for r in rects) x_right = max(r.x1 for r in rects) top_cut = min(r.y0 for r in rects) bot_cut = max(r.y1 for r in rects) lw_l = next((lw for r, lw in hit_h if r.x0 == x_left), 0) lw_r = next((lw for r, lw in hit_h if r.x1 == x_right), 0) return fitz.Rect( x_left - lw_l / 2 - CROP_MARGIN, top_cut - CROP_MARGIN, x_right + lw_r / 2 + CROP_MARGIN, bot_cut + CROP_MARGIN, ) def main(): doc = fitz.open(str(SRC)) clip = detect_clip(doc[0]) doc.close() raw_w_mm = pt_to_mm(clip.width) raw_h_mm = pt_to_mm(clip.height) target_w_mm = round(pt_to_mm(clip.width * TARGET_SCALE), 2) target_h_mm = round(pt_to_mm(clip.height * TARGET_SCALE), 2) target_w_pt = clip.width * TARGET_SCALE target_h_pt = clip.height * TARGET_SCALE gap_pt = (A4_H_PT - 2 * target_h_pt) / 3 side_pt = (A4_W_PT - target_w_pt) / 2 layout = { "2PuzzleOnA4": { "description": "2 puzzle pod sebou, horizontalne vycentrovane, misto po stranach na vypocty", "page": { "format": "A4", "width_pt": A4_W_PT, "height_pt": A4_H_PT }, "count": 2, "arrangement": "vertical", "horizontal_align": "center", "vertical_distribution": "equal_gaps", "target_puzzle_width_mm": target_w_mm, "target_puzzle_height_mm": target_h_mm, "crop_margin_pt": CROP_MARGIN, "info": { "sample_raw_puzzle_mm": f"{raw_w_mm} x {raw_h_mm}", "scale_used_for_sample": TARGET_SCALE, "side_margin_mm": pt_to_mm(side_pt), "gap_between_puzzles_mm": pt_to_mm(gap_pt) } } } # Načíst existující JSON a přidat/přepsat klíč if JSON_PATH.exists(): existing = json.loads(JSON_PATH.read_text(encoding="utf-8")) existing.update(layout) layout = existing JSON_PATH.write_text(json.dumps(layout, indent=2, ensure_ascii=False), encoding="utf-8") print(f"Ulozeno: {JSON_PATH}") print(f" Surove puzzle: {raw_w_mm} x {raw_h_mm} mm") print(f" Cilova velikost: {target_w_mm} x {target_h_mm} mm") print(f" Misto po stranach: {pt_to_mm(side_pt):.1f} mm") print(f" Mezera mezi puzzle: {pt_to_mm(gap_pt):.1f} mm") if __name__ == "__main__": main()