Reputation: 61
I am creating a python script that can modify a pdf file to be printed in book sections. As there is no such functionality in the ubuntu printing settings.
PyPDF2 is a wonderful tool with which I have been able to do everything I wanted except adding a margin.
For example consider this book.
http://www.edwardothorp.com/sitebuildercontent/sitebuilderfiles/beatthemarket.pdf
It requires some margins so that there is some room for binding them in a book.
I have found how to shift the content a few pixels, but the size of the "canvas" doesn't change so some content is cut off.
I am able to adjust the "page size" with PyPDF2 by changing the mediabox size but I an only crop the pages, I cannot increase their size. And to add margins, I have to increase the size. I also can't shrink the content, because then for some reason the page size shrinks with it.
Here is the script if you want to print a book. http://pastebin.com/LGYhKYu1 Of course, it only works with pdfs with already some margins so you only need to shift the content.
I would be most grateful if someone could point out how to add margins to a pdf with PyPDF2 , I must be overlooking something.
Thank you!
Upvotes: 6
Views: 7242
Reputation: 595
I assume for instance you say ODD pages shall have more margin on the left side than on the right side, and EVEN pages shall have more margin on the right side than on the left side. I used primary variable for bigger side margin and secondary variable for regular side margin, top and bottom margins for to and bottom. I used this script to prepare pdf for book hardcover printing, where book starts with odd page on the right hand side (so left margin is bigger than right) and opposite goes for even pages.
import argparse
from PyPDF2 import PdfReader, PdfWriter
def to_points(x):
return x * 72 if measure == "inch" else x * 28.8
def add_margins(input_pdf, output_pdf, primary=0, secondary=0, top=0, bottom=0):
with open(input_pdf, 'rb') as f:
reader = PdfReader(f)
writer = PdfWriter()
for i, page in enumerate(reader.pages):
i = i + 1
if i % 2 == 0:
page.mediabox.lower_left = (float(page.mediabox.lower_left[0]) - secondary, float(page.mediabox.lower_left[1]) - bottom)
page.mediabox.lower_right = (float(page.mediabox.lower_right[0]) + primary, float(page.mediabox.lower_right[1]) - bottom)
page.mediabox.upper_left = (float(page.mediabox.upper_left[0]) - secondary, float(page.mediabox.upper_left[1]) + top)
page.mediabox.upper_right = (float(page.mediabox.upper_right[0]) + primary, float(page.mediabox.upper_right[1]) + top)
else:
page.mediabox.lower_left = (float(page.mediabox.lower_left[0]) - primary, float(page.mediabox.lower_left[1]) - bottom)
page.mediabox.lower_right = (float(page.mediabox.lower_right[0]) + secondary, float(page.mediabox.lower_right[1]) - bottom)
page.mediabox.upper_left = (float(page.mediabox.upper_left[0]) - primary, float(page.mediabox.upper_left[1]) + top)
page.mediabox.upper_right = (float(page.mediabox.upper_right[0]) + secondary, float(page.mediabox.upper_right[1]) + top)
writer.add_page(page)
with open(output_pdf, 'wb') as out:
writer.write(out)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Add margins to a PDF file.")
parser.add_argument('input_pdf', type=str, help="Input PDF file path")
parser.add_argument('output_pdf', type=str, help="Output PDF file path")
parser.add_argument('--side_p', type=float, default=0, help="Margin of primary side")
parser.add_argument('--side_s', type=float, default=0, help="Margin of secondary side")
parser.add_argument('--top', type=float, default=0, help="Top margin")
parser.add_argument('--bottom', type=float, default=0, help="Bottom margin")
parser.add_argument('--measure', type=str, default=0, help="cm or inch")
args = parser.parse_args()
measure = args.measure
add_margins(
args.input_pdf,
args.output_pdf,
to_points(args.side_p),
to_points(args.side_s),
to_points(args.top),
to_points(args.bottom)
)
Launch in cmd: python add-margings-pdf.py linear-algebra-printing.pdf out-linear-algebra-printing.pdf --side_p 0.75 --side_s 0.5 --top 0.5 --bottom 0.5 --measure inch
Upvotes: 0
Reputation: 11
I myself was trying to figure out this. My objective was to crop a B5 page content and fit in A4 for booklet
bind_margin = 60
for pnum in tqdm(range(numpage)):
page = inpdf.getPage(pnum)
# Trim margins from right and left
page.trimBox.lowerLeft = tuple([a+b for a, b in zip(page.trimBox.lowerLeft, (50, 0))])
page.trimBox.upperRight = tuple([a-b for a, b in zip(page.trimBox.upperRight, (50, 0))])
page.cropBox.lowerLeft = tuple([a+b for a, b in zip(page.cropBox.lowerLeft, (50, 0))])
page.cropBox.upperRight = tuple([a-b for a, b in zip(page.cropBox.upperRight, (50, 0))])
# create empty A4 size page
emptyPage = pdf.PageObject.createBlankPage(width=tarw, height=tarh)
margin_available = tarw + page.mediaBox.lowerLeft[0] - page.mediaBox.upperRight[0]
if pnum%2==0:
tx = bind_margin
else:
tx = margin_available - bind_margin
emptyPage.mergeTranslatedPage(page, tx, 180)
outpdf.addPage(emptyPage)
Upvotes: 1
Reputation: 91
It seems there is no dedicated method, but you can create an empty page of the desired size, then merge your content with the empty page
page = PageObject.createBlankPage(
yourPage.mediaBox.getWidth () + 2 * margin,
yourPage.mediaBox.getHeight() + 2 * margin)
page.mergeScaledTranslatedPage( yourPage, scale, leftMargin, bottomMargin)
...
output = PdfFileWriter()
output.addPage(page)
Upvotes: 8