I have a large number of PDF files which have two slides to a page (for printing).
The format is A4 pages each with two slides setup like so:
-----------
Briss is "a simple cross-platform (Linux, Windows, Mac OSX) application for cropping PDF files. A simple user interface lets you define exactly the crop-region by fitting a rectangle on the visually overlaid pages." It's open source (GPL).
Works well for me. The GUI is minimal, but functional. It can also be used from the command line.
You can use a Python library called PyPDF. This function will split double pages no matter what the page orientation is:
import copy
import math
import pyPdf
def split_pages(src, dst):
src_f = file(src, 'r+b')
dst_f = file(dst, 'w+b')
input = pyPdf.PdfFileReader(src_f)
output = pyPdf.PdfFileWriter()
for i in range(input.getNumPages()):
p = input.getPage(i)
q = copy.copy(p)
q.mediaBox = copy.copy(p.mediaBox)
x1, x2 = p.mediaBox.lowerLeft
x3, x4 = p.mediaBox.upperRight
x1, x2 = math.floor(x1), math.floor(x2)
x3, x4 = math.floor(x3), math.floor(x4)
x5, x6 = math.floor(x3/2), math.floor(x4/2)
if x3 > x4:
# horizontal
p.mediaBox.upperRight = (x5, x4)
p.mediaBox.lowerLeft = (x1, x2)
q.mediaBox.upperRight = (x3, x4)
q.mediaBox.lowerLeft = (x5, x2)
else:
# vertical
p.mediaBox.upperRight = (x3, x4)
p.mediaBox.lowerLeft = (x1, x6)
q.mediaBox.upperRight = (x3, x6)
q.mediaBox.lowerLeft = (x1, x2)
output.addPage(p)
output.addPage(q)
output.write(dst_f)
src_f.close()
dst_f.close()
Try BRISS.
It lets you split each page into as many subpages as you want by defining regions with a GUI. It groups all similar pages into groups for you, so you can define regions for that group once.
It's cross-platform, free, and open-source.
(copy-pasted from https://superuser.com/a/235327/35237)
mutool
works brillantly for this. The example below will chop each page of input.pdf
into 3 horizontal and 8 vertical parts (thus creating 24 pages of output for each 1 of input):
mutool poster -x 3 -y 8 input.pdf output.pdf
To install mutool
, just install mupdf, which is probably packaged with most GNU/Linux distributions.
(Credits to marttt.)
On debian based linux systems like ubuntu, you can install it using
sudo apt install mupdf
sudo apt install mupdf-tools
Here is how I did it with pdfrw
:
import sys, os, pdfrw
writer = pdfrw.PdfWriter()
for page in pdfrw.PdfReader('input.pdf').pages:
for y in [0, 0.5]:
newpage = pdfrw.PageMerge()
newpage.add(page, viewrect=(0, y, 1, 0.5))
writer.addpages([newpage.render()])
writer.write('output.pdf')
Short and working!
If you want it rotated (example: input A4 portrait, output 2 A5 portrait and not landscape):
import sys, os, pdfrw
writer = pdfrw.PdfWriter()
for page in pdfrw.PdfReader('input.pdf').pages:
for y in [0, 0.5]:
newpage = pdfrw.PageMerge()
newpage.add(page, viewrect=(0, y, 1, 0.5))
p = newpage.render()
p.Rotate = 270
writer.addpages([p])
writer.write('output.pdf')
Thanks to moraes for that answer. In my case, the resulting PDF looked fine in Adobe Reader and Mac preview, but did not appear to have been split into separate pages at all when viewing on iOS. I used Python 2.7.8 and PyPDF 2, and modified the script as follows, which worked fine. (and reordered the pages left/right, rather than right/left).
import copy
import math
from PyPDF2 import PdfFileReader, PdfFileWriter
def split_pages(src, dst):
src_f = file(src, 'r+b')
dst_f = file(dst, 'w+b')
input = PdfFileReader(src_f)
output = PdfFileWriter()
for i in range(input.getNumPages()):
p = input.getPage(i)
q = copy.copy(p)
q.mediaBox = copy.copy(p.mediaBox)
x1, x2 = p.mediaBox.lowerLeft
x3, x4 = p.mediaBox.upperRight
x1, x2 = math.floor(x1), math.floor(x2)
x3, x4 = math.floor(x3), math.floor(x4)
x5, x6 = math.floor(x3/2), math.floor(x4/2)
if x3 > x4:
# horizontal
p.mediaBox.upperRight = (x5, x4)
p.mediaBox.lowerLeft = (x1, x2)
q.mediaBox.upperRight = (x3, x4)
q.mediaBox.lowerLeft = (x5, x2)
else:
# vertical
p.mediaBox.upperRight = (x3, x4)
p.mediaBox.lowerLeft = (x1, x6)
q.mediaBox.upperRight = (x3, x6)
q.mediaBox.lowerLeft = (x1, x2)
p.artBox = p.mediaBox
p.bleedBox = p.mediaBox
p.cropBox = p.mediaBox
q.artBox = q.mediaBox
q.bleedBox = q.mediaBox
q.cropBox = q.mediaBox
output.addPage(q)
output.addPage(p)
output.write(dst_f)
src_f.close()
dst_f.close()