Skip to content

Instantly share code, notes, and snippets.

@villares
Last active September 10, 2023 14:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save villares/0402a1c9033e6f4baf55554c16d25f4e to your computer and use it in GitHub Desktop.
Save villares/0402a1c9033e6f4baf55554c16d25f4e to your computer and use it in GitHub Desktop.
Faz a "imposição" de páginas de um zine em um A3
"""
Make a PDF A3 zine combining 8 pages from a source PDF
WIP: I'd like to have an option for the 9th page (index=8) to be a poster in the backside or not.
-------------------------------------------------------------------------------
License: GNU GPL V3
(c) 2023 Alexandre Villares
Based on https://github.com/pymupdf/PyMuPDF-Utilities/blob/master/examples/combine-pages/combine.py
(c) 2018 Jorj X. McKie
Dependencies
------------
PyMuPDF (the fitz engine)
Usage
-----
python combine.py input.pdf
|----|----|----|----|
| 0d | 7d | 6d | 5d |
|----|----|----|----|
| 1u | 2u | 3u | 4u |
|----|----|----|----|
|----|----|----|----|
| |
| 8s |
| |
|----|----|----|----|
N = page 0-based
u = normal orientation
d = upside down (rotated 180)
s = big poster (rotated 90)
Notes
-----
(1) Output file is chosen to have A3 landscape pages. Input pages are scaled
maintaining side proportions.
"""
import fitz, sys
infile = sys.argv[1]
src = fitz.open(infile)
doc = fitz.open() # empty output PDF
height, width = fitz.paper_size("a3") # A3 output page format
# define the 4 rectangles per page
r0 = fitz.Rect(0, 0, width / 4, height / 2) # top left rect
r7 = r0 + (r0.width, 0, r0.width, 0)
r6 = r7 + (r0.width, 0, r0.width, 0)
r5 = r6 + (r0.width, 0, r0.width, 0) # top right
r1 = r0 + (0, r0.height, 0, r0.height) # bottom left
r2 = r1 + (r0.width, 0, r0.width, 0)
r3 = r2 + (r0.width, 0, r0.width, 0)
r4 = r3 + (r0.width, 0, r0.width, 0)# bottom right
r8 = fitz.Rect(0, 0, width, height)
# put them in a list
r_tab = [r0, r1, r2, r3, r4, r5, r6, r7, r8]
front_and_back = False
big_poster = True
poster_offset = 0
# now copy input pages to output
for spage in src:
if (spage.number - poster_offset) % 8 == 0: # create new output page
page = doc.new_page(-1, width=width, height=height)
# WIP
# if not front_and_back:
# poster_offset += 1
# if big_poster:
# # add poster here
# continue
# insert input page into the correct rectangle
r_position = (spage.number - poster_offset) % (9 if big_poster else 8)
# imposition rotation rule
rotation = (180 if r_position in (0, 7, 6, 5)
else 90 if r_position == 8 else 0)
page.show_pdf_page(
r_tab[r_position], # select output rect
src, # input document
spage.number,
rotate=rotation
) # input page number
# by all means, save new file using garbage collection and compression
doc.save("output.pdf", garbage=4, deflate=True)
@villares
Copy link
Author

villares commented Aug 2, 2023

image

@villares
Copy link
Author

villares commented Sep 4, 2023

Este é aquele formato de zine que você corta com o estilete uma linha reta na parte de cima das páginas 2 e 3 (que as separam das páginas 6 e 7) e isso pemite dobrar de forma a virar um "livrinho".

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment