Initial commit — Copydev Imposing Tool
Outil d'imposition PDF desktop (PyQt6) remplacant Quite Imposing Plus. 9 fonctions : livret, n-up, step & repeat, imposition manuelle, jointure pages, pages blanches, numerotation, masquage, fonds perdus. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
68
app/engine/manual_impose.py
Normal file
68
app/engine/manual_impose.py
Normal file
@@ -0,0 +1,68 @@
|
||||
"""Moteur Imposition manuelle."""
|
||||
|
||||
from pypdf import PdfReader, PdfWriter, PageObject, Transformation
|
||||
from .pdf_utils import get_page_size, create_crop_marks_page
|
||||
|
||||
|
||||
def manual_impose(input_path, output_path, sheet_size, placements, crop_marks=False):
|
||||
"""Imposition manuelle : placer des pages a des positions precises.
|
||||
|
||||
sheet_size: (largeur, hauteur) en points
|
||||
placements: liste de dicts:
|
||||
{"page": int (1-based), "x": float, "y": float, "scale": float, "rotation": int}
|
||||
"""
|
||||
reader = PdfReader(input_path)
|
||||
pages = reader.pages
|
||||
sheet_w, sheet_h = sheet_size
|
||||
|
||||
writer = PdfWriter()
|
||||
sheet = PageObject.create_blank_page(width=sheet_w, height=sheet_h)
|
||||
|
||||
mark_positions = []
|
||||
|
||||
for p in placements:
|
||||
page_idx = p["page"] - 1
|
||||
if page_idx < 0 or page_idx >= len(pages):
|
||||
continue
|
||||
|
||||
page = pages[page_idx]
|
||||
page_w, page_h = get_page_size(page)
|
||||
x = p.get("x", 0)
|
||||
y = p.get("y", 0)
|
||||
scale = p.get("scale", 1.0)
|
||||
rotation = p.get("rotation", 0)
|
||||
|
||||
overlay = PageObject.create_blank_page(width=sheet_w, height=sheet_h)
|
||||
overlay.merge_page(page)
|
||||
|
||||
transform = Transformation()
|
||||
if rotation:
|
||||
# Rotation autour du centre de la page
|
||||
cx = page_w / 2
|
||||
cy = page_h / 2
|
||||
transform = transform.translate(-cx, -cy)
|
||||
transform = transform.rotate(rotation)
|
||||
transform = transform.translate(cx, cy)
|
||||
transform = transform.scale(scale, scale).translate(x, y)
|
||||
overlay.add_transformation(transform)
|
||||
sheet.merge_page(overlay)
|
||||
|
||||
if crop_marks:
|
||||
scaled_w = page_w * scale
|
||||
scaled_h = page_h * scale
|
||||
mark_positions.extend([
|
||||
(x, y),
|
||||
(x + scaled_w, y),
|
||||
(x, y + scaled_h),
|
||||
(x + scaled_w, y + scaled_h),
|
||||
])
|
||||
|
||||
if crop_marks and mark_positions:
|
||||
marks = create_crop_marks_page(sheet_w, sheet_h, mark_positions)
|
||||
sheet.merge_page(marks)
|
||||
|
||||
writer.add_page(sheet)
|
||||
|
||||
with open(output_path, "wb") as f:
|
||||
writer.write(f)
|
||||
return output_path
|
||||
Reference in New Issue
Block a user