#!/usr/bin/python from PIL import Image, ImageDraw import sys import os import subprocess """ pdfshrink - Remove margins and pagebreaks out of a PDF file, for neater printing Requires: convert, pdftk """ # Unless your paper is A4, you'll have to change the paper size # here. # # Unit is pixels. PDFs are converted at 300 dpi # # A4: 297mm -> 11.6929134 inches -> 3507.87402 # paper_height = 3507.87402 paper_width = 2480.314962 if len(sys.argv) == 0: print "pdfshrink" print "Syntax: pdfshrink " sys.exit(0) os.mkdir("pdfshrink_work") # Convert all pages to JPG (PIL doesn't like to load PNG) print "Converting files to JPG" counter = 0 for file in sys.argv[1:]: counter += 1 subprocess.Popen(["convert", "-density", "300", file, "-trim", "pdfshrink_work/%d.jpg" % counter]).communicate() def sorter(obj): if "-" in obj: file = int(obj.split("-")[0]) page = int(obj.split("-")[1].split(".")[0]) else: page = 0 file = int(obj.split(".")[0]) return file * 10000 + page os.chdir("pdfshrink_work") imagelist = sorted(os.listdir("."), key=sorter) # Calculate height of all images print "Calculating heights" height = 0 for file in imagelist: height += Image.open(file).size[1] + 20 print "Creating temporary image" # Generate one big picture for all pages output = Image.new("RGB", (int(paper_width), height)) output.paste("#fff", (0,0,int(paper_width),height)) # Copy all images into that one used = 0 for file in imagelist: img = Image.open(file) left = max(int((paper_width - img.size[0]) / 2), 0) output.paste(img, (left, used)) used += img.size[1] + 20 # Clean up map(os.unlink, imagelist) # Create new output images print "Cropping" call = [ "pdftk" ] def check_line(img, line): data = img.load() for x in range(img.size[0]): if data[x, line] != (255, 255, 255): return False return True counter = 0 used = 0 while used + 2 < height: to = paper_height - 300 if used + to > height: to = height - used - 1 while not check_line(output, used + to): to -= 2 if to < 0: print "FAILURE" sys.exit(1) nimg = Image.new("RGB", (int(paper_width), int(to) + 300)) nimg.paste("#fff", (0, 0, int(paper_width), int(to) + 300)) nimg.paste(output.crop((0, int(used), int(paper_width), int(used + to))), (0, 150)) nimg.save("%d.jpg" % counter) call.append("%d.jpg.pdf" % counter) print " Created page #%d" % counter counter += 1 used += to print "Creating PDF output files from images" for file in os.listdir("."): subprocess.Popen(["convert", "-density", "300", file, file + ".pdf"]).communicate() os.unlink(file) print "Merging PDF files" call += [ "output", "../output.pdf" ] subprocess.Popen(call).communicate() print "Removing temporary files" for file in os.listdir("."): os.unlink(file) os.chdir("..") os.rmdir("pdfshrink_work")