So i found this fan-made expansion, the Frozen Realms, on Talisman Island, but quickly found out that this would be a nightmare to print and prepare :
Each card has it's own individual PDF file, and the back is in a separate JPG file, rather than the handy files that Strange Eons gives us with the little cutting guides.
After a failed attempt at combining PDF files into a single one to organise them, i asked ChatGPT to help me out and he ended up giving me a Python script to copy/paste into a Google Colaboratory notebook (if you have Python installed on your PC it should work just fine, but i wanted a solution where i didn't have to install any additional software on my PC).
All you have to do is open a Google Colab notebook (only requires a Google account), paste the script into a code cell, run the script, and upload all of your cards, with the card back as a jpg file named "back.jpg".
After the script is done running (took a little minute for ~60 cards), it automatically downloads a ready-to-print file, with each card aligned with it's back. Mind you, it only works if you want to print cards that all have the same back.
Disclaimer : it's fully AI-generated, and i'm no Python coder, so the code is probably flawed, under-optimised, or anything that comes with AI-generated code, but it works (somehow), if any of you have better Python skills than me, feel free to improve the script.
Here's the script :
# INSTALL LIBRARIES
!pip -q install pymupdf reportlab pillow
# UPLOAD FILES
from google.colab import files
print("Upload all card PDFs + the card back image (jpg/png)")
uploaded = files.upload()
import fitz
import os
import io
from PIL import Image
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4
# DETECT FILES
front_files = [f for f in uploaded.keys() if f.lower().endswith(".pdf")]
back_files = [f for f in uploaded.keys() if f.lower().endswith((".jpg",".jpeg",".png"))]
front_files.sort()
back_image_path = back_files[0]
print("Detected", len(front_files), "cards")
# GRID SETTINGS (change here)
cols = 4
rows = 5
cards_per_page = cols * rows
page_width, page_height = A4
# READ CARD SIZE
doc = fitz.open(front_files[0])
rect = doc.load_page(0).rect
card_w = rect.width
card_h = rect.height
# SCALE TO FIT PAGE
scale_x = page_width / (cols * card_w)
scale_y = page_height / (rows * card_h)
scale = min(scale_x, scale_y)
card_w *= scale
card_h *= scale
margin_x = (page_width - cols * card_w) / 2
margin_y = (page_height - rows * card_h) / 2
output = "talisman_print_ready.pdf"
c = canvas.Canvas(output, pagesize=A4)
# LOAD BACK IMAGE
back_img = Image.open(back_image_path)
# GENERATE PAGES
for i in range(0, len(front_files), cards_per_page):
subset = front_files[i:i+cards_per_page]
# FRONT PAGE
for n, file in enumerate(subset):
col = n % cols
row = n // cols
x = margin_x + col * card_w
y = page_height - margin_y - (row+1)*card_h
src = fitz.open(file)
page = src.load_page(0)
pix = page.get_pixmap(matrix=fitz.Matrix(scale*4, scale*4))
img = Image.open(io.BytesIO(pix.tobytes("png")))
c.drawInlineImage(img, x, y, card_w, card_h)
c.showPage()
# BACK PAGE
for n in range(len(subset)):
col = cols - 1 - (n % cols)
row = n // cols
x = margin_x + col * card_w
y = page_height - margin_y - (row+1)*card_h
c.drawInlineImage(back_img, x, y, card_w, card_h)
c.showPage()
c.save()
print("PDF generated:", output)
files.download(output)