Skip to content

Commit 432b698

Browse files
Add files via upload
1 parent 8274796 commit 432b698

File tree

1 file changed

+110
-0
lines changed

1 file changed

+110
-0
lines changed

WESMUN Script/smushPDF.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
from pypdf import PdfReader, PdfWriter, PageObject, Transformation
2+
from reportlab.pdfgen import canvas
3+
from io import BytesIO
4+
from math import floor
5+
6+
MM_TO_PT = 72 / 25.4
7+
8+
# Target sizes
9+
CARD_W = 85.5 * MM_TO_PT
10+
CARD_H = 54 * MM_TO_PT
11+
A4_W = 210 * MM_TO_PT
12+
A4_H = 297 * MM_TO_PT
13+
14+
MARGIN = 10 * MM_TO_PT
15+
GAP = 5 * MM_TO_PT
16+
SAFETY_CUT = 0.1 # tiny buffer inside the card
17+
EDGE_WIDTH = 1.5 # more thickness for black edge than golden corners
18+
CORNER_WIDTH = 1.0
19+
20+
cards_per_row = floor((A4_W - 2 * MARGIN + GAP) / (CARD_W + GAP))
21+
cards_per_col = floor((A4_H - 2 * MARGIN + GAP) / (CARD_H + GAP))
22+
23+
reader = PdfReader("input.pdf")
24+
writer = PdfWriter()
25+
26+
def new_a4():
27+
return PageObject.create_blank_page(width=A4_W, height=A4_H)
28+
29+
def card_edge_pdf(tx, ty):
30+
"""
31+
Draws black edge exactly around the card content (inside safety cut)
32+
and golden corners at the outer card slot, constrained to the safety cut buffer
33+
"""
34+
packet = BytesIO()
35+
c = canvas.Canvas(packet, pagesize=(A4_W, A4_H))
36+
37+
# Black edge around the scaled card content
38+
c.setStrokeColorRGB(0, 0, 0) # black
39+
c.setLineWidth(EDGE_WIDTH)
40+
rect_x = tx + SAFETY_CUT
41+
rect_y = ty + SAFETY_CUT
42+
rect_w = CARD_W - 2*SAFETY_CUT
43+
rect_h = CARD_H - 2*SAFETY_CUT
44+
c.rect(rect_x, rect_y, rect_w, rect_h, stroke=1, fill=0)
45+
46+
# Golden corners constrained to the card slot (respecting safety cut)
47+
corner_len = 5
48+
c.setStrokeColorRGB(1, 0.84, 0) # gold
49+
c.setLineWidth(CORNER_WIDTH)
50+
51+
# Adjusted corner coordinates
52+
x0, y0 = tx + SAFETY_CUT, ty + SAFETY_CUT
53+
x1, y1 = tx + CARD_W - SAFETY_CUT, ty + CARD_H - SAFETY_CUT
54+
55+
# top-left
56+
c.line(x0, y1, x0, y1 - corner_len)
57+
c.line(x0, y1, x0 + corner_len, y1)
58+
# top-right
59+
c.line(x1, y1, x1, y1 - corner_len)
60+
c.line(x1, y1, x1 - corner_len, y1)
61+
# bottom-left
62+
c.line(x0, y0, x0 + corner_len, y0)
63+
c.line(x0, y0, x0, y0 + corner_len)
64+
# bottom-right
65+
c.line(x1, y0, x1 - corner_len, y0)
66+
c.line(x1, y0, x1, y0 + corner_len)
67+
68+
c.save()
69+
packet.seek(0)
70+
return PdfReader(packet).pages[0]
71+
72+
73+
a4_page = new_a4()
74+
slot = 0
75+
76+
for page in reader.pages:
77+
col = slot % cards_per_row
78+
row = slot // cards_per_row
79+
80+
if row >= cards_per_col:
81+
writer.add_page(a4_page)
82+
a4_page = new_a4()
83+
slot = 0
84+
col = 0
85+
row = 0
86+
87+
# scale page to fit card with safety cut
88+
scale_x = (CARD_W - 2*SAFETY_CUT) / page.mediabox.width
89+
scale_y = (CARD_H - 2*SAFETY_CUT) / page.mediabox.height
90+
91+
tx = MARGIN + col * (CARD_W + GAP) + SAFETY_CUT
92+
ty = A4_H - MARGIN - CARD_H - row * (CARD_H + GAP) + SAFETY_CUT
93+
94+
transform = Transformation().scale(scale_x, scale_y).translate(tx, ty)
95+
a4_page.merge_transformed_page(page, transform)
96+
97+
# draw black edge + golden corners
98+
edge_page = card_edge_pdf(
99+
MARGIN + col * (CARD_W + GAP),
100+
A4_H - MARGIN - CARD_H - row * (CARD_H + GAP)
101+
)
102+
a4_page.merge_page(edge_page)
103+
104+
slot += 1
105+
106+
if slot > 0:
107+
writer.add_page(a4_page)
108+
109+
with open("output_a4_cards.pdf", "wb") as f:
110+
writer.write(f)

0 commit comments

Comments
 (0)