#!/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 <pdf-files>"
	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")
