Last active
March 22, 2016 11:20
-
-
Save epoz/8666510 to your computer and use it in GitHub Desktop.
Planodo turn a bunch of files into a big zoomable image
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!./bin/python | |
from reportlab.pdfgen import canvas | |
from reportlab.lib.pagesizes import A4 | |
from reportlab.lib.units import cm | |
from reportlab.pdfbase import pdfmetrics | |
from reportlab.pdfbase.ttfonts import TTFont | |
from PIL import Image | |
import PIL | |
import os | |
import json | |
import sys | |
IMG_ORG = './images_org' | |
IMG_2700 = './images_2700' | |
IMG_small = './images_270' | |
BY_book = './bybook' | |
BY_rows = './rows' | |
JAREN = './jaren' | |
#maximum size of Pillow images in pixels | |
# ROW_WIDTH = 65500 | |
# ROW_HEIGHT = 2700 | |
ROW_WIDTH = 6550 | |
ROW_HEIGHT = 270 | |
def read_biblio(): | |
d = {} | |
lines = [x.split('\t') for x in open('abb.txt').read().decode('utf16').split('\r\n')] | |
for x in lines[1:]: | |
if len(x) < 6: | |
continue | |
yp, auth, title, impressum, sign = x[0], x[1], x[2], x[3], x[4] | |
tmp = yp.strip('"').split(' ') | |
if len(tmp) < 2: | |
tmp = yp.split(',') | |
if len(tmp) != 2: | |
continue | |
year, place = tmp | |
if year == '1538': | |
import pdb; pdb.set_trace() | |
d[(year.strip('",'), place.strip('",'))] = (auth, title, impressum, sign) | |
return d | |
def make_big(): | |
rowfiles = sorted([x for x in os.listdir(BY_rows) if x.endswith('.jpg')]) | |
height_needed = len(rowfiles)*ROW_HEIGHT | |
big = Image.new('RGB', (ROW_WIDTH, height_needed), color='white') | |
for row_idx, rowfile in enumerate(rowfiles): | |
print 'doing row', row_idx | |
try: | |
img = Image.open('rows/'+rowfile) | |
except IOError: | |
raise Exception('Problem with', 'rows/'+rowfile) | |
w,h = img.size | |
diff = ROW_WIDTH-w | |
big.paste(img, (diff/2, row_idx*ROW_HEIGHT)) | |
print 'Now saving big' | |
big.save('big.jpg') | |
big.thumbnail((3000,3000), PIL.Image.ANTIALIAS) | |
big.save('small.jpg') | |
def get_year_intervals_from_books(): | |
count = 0 | |
years = [] | |
books = [x for x in os.listdir(BY_book) if x.endswith('.jpg')] | |
for x in sorted(books): | |
year = int(x[:4]) | |
if count == 0: | |
years.append(year) | |
count += 1 | |
if count == 10: | |
count = 0 | |
years.append(int(books[-1][:4])) | |
return years | |
def make_rows(): | |
# Note the font for the big Jaren is 'Calibri' | |
f = [x for x in os.listdir(BY_book) if x.endswith('.jpg')] | |
f.sort() | |
row = Image.new('RGBA', (ROW_WIDTH, ROW_HEIGHT), color='white') | |
row.save(os.path.join(BY_rows, '_.jpg')) | |
row.save(os.path.join(BY_rows, 'x.jpg')) | |
row_idx = 0 | |
x = 0 | |
t_w = 0 | |
img = None | |
jaren = sorted([fj for fj in os.listdir(JAREN) if fj.startswith('jaren')]) | |
jaar = jaren.pop(0) | |
dec_year = int(jaar[5:9]) | |
book_year = 0 | |
while f: | |
if not img: | |
filename = f.pop(0) | |
book_year = int(filename[:4]) | |
if book_year >= dec_year: | |
f.insert(0, filename) | |
filename = jaar | |
img = Image.open(os.path.join(JAREN, jaar)) | |
if jaren: | |
jaar = jaren.pop(0) | |
dec_year = int(jaar[5:9]) | |
else: | |
# fake year in future | |
dec_year = 10000 | |
else: | |
img = Image.open( os.path.join(BY_book, filename)) | |
w,h = img.size | |
if (t_w + w) < (ROW_WIDTH-(ROW_WIDTH*0.02)): | |
print filename, w, x, t_w | |
if img.mode == 'RGBA': | |
row.paste(img, (x,0), img) | |
else: | |
row.paste(img, (x,0)) | |
x += w | |
t_w += w | |
img = None | |
else: | |
print 'Saving row', row_idx | |
crow = row.crop((0,0,t_w,ROW_HEIGHT)) | |
crow.save(os.path.join(BY_rows, '%.2d.jpg' % row_idx)) | |
row = Image.new('RGBA', (ROW_WIDTH, ROW_HEIGHT), color='white') | |
row_idx += 1 | |
t_w = 0 | |
x = 0 | |
crow = row.crop((0,0,t_w,ROW_HEIGHT)) | |
crow.save(os.path.join(BY_rows, '%.2d.jpg' % row_idx)) | |
def make_images_sameheight(src=IMG_ORG, dest=IMG_small, size=270): | |
if not os.path.exists(dest): | |
os.mkdir(dest) | |
count = 0 | |
for filename in os.listdir(src): | |
if not filename.endswith('.jpg') or filename.startswith('.'): | |
continue | |
img = Image.open(os.path.join(src, filename)) | |
w,h = img.size | |
if h == size: | |
continue | |
ratio = float(w)/float(h) | |
new_w = int(size*ratio) | |
new_img = img.resize((new_w, size), PIL.Image.ANTIALIAS) | |
new_img.save(os.path.join(dest, filename)) | |
count += 1 | |
sys.stderr.write('\r%s done '%count) | |
sys.stderr.write('Converted %s images to new height\n' % count) | |
def get_imgs_by_yearplace(src_dir): | |
d = {} | |
for filename in os.listdir(src_dir): | |
if filename.startswith('.'): | |
continue | |
year = filename[14:18] | |
place = filename[18:-4] | |
if place[-1] in ('D', '0', '1', '2', '3', '5', 'X'): | |
place = place[:-1] | |
d.setdefault( (year, place), []).append(filename) | |
return d | |
def make_by_book(src_dir=IMG_2700): | |
d = get_imgs_by_yearplace(src_dir) | |
for k in sorted(d.keys(), key=lambda x: int(x[0])): | |
year, place = k | |
# figure out the total width needed | |
imgs = [Image.open(os.path.join(src_dir, filename)) for filename in sorted(d[k])] | |
height = imgs[0].size[1] | |
total_needed = sum([x.size[0] for x in imgs]) | |
comp_img = Image.new('RGBA', (total_needed, height), color='white') | |
x = 0 | |
for img in imgs: | |
if img.mode == 'RGBA': | |
comp_img.paste(img, (x,0), img) | |
else: | |
comp_img.paste(img, (x,0)) | |
x += img.size[0] | |
filename = '%s_%s.jpg' % (year, place) | |
comp_img.save(os.path.join(BY_book, filename)) | |
print filename | |
def make_yearplace_pdfs(src_dir=IMG_2700): | |
# This function assumes you are running on OS X so that you can access the Truetype fonts | |
# and sips command for rendering PDF to png | |
width, height = A4 | |
pdfmetrics.registerFont(TTFont("Calibri", '/Library/Fonts/Microsoft/Calibri.ttf')) | |
pdfmetrics.registerFont(TTFont("CalibriBold", '/Library/Fonts/Microsoft/Calibri Bold.ttf')) | |
pdfmetrics.registerFont(TTFont("Impact", '/Library/Fonts/Impact.ttf')) | |
pdfmetrics.registerFont(TTFont("Futura", '/Library/Fonts/Futura.ttc')) | |
d = get_imgs_by_yearplace(src_dir) | |
# Color of big years in RGB decimal is 206 23 25 | |
biblio = read_biblio() | |
for k in sorted(d.keys(), key=lambda x: int(x[0])): | |
year, place = k | |
c = canvas.Canvas("tmp.pdf", pagesize=(width/2, height)) | |
c.setFont("CalibriBold", 72) | |
c.drawString(20, height-75, "%s" % year) | |
c.setFont("Calibri", 36) | |
c.drawString(20, height-120, place) | |
b = biblio.get(k) | |
if b: | |
auth, title, impressum, sign = b | |
c.setFont("CalibriBold", 18) | |
c.drawString(20, height-150, title) | |
c.setFont("Calibri", 18) | |
c.drawString(20, height-180, auth) | |
c.drawString(20, height-210, impressum) | |
c.drawString(20, height-240, sign) | |
c.showPage() | |
c.save() | |
os.system(r'sips -s format png tmp.pdf --resampleHeight %s --out images_270/abeautifulbook%s%sX.png' % (ROW_HEIGHT, year, place)) | |
def make_year_pdfs(): | |
width, height = A4 | |
pdfmetrics.registerFont(TTFont("Calibri", '/Library/Fonts/Microsoft/Calibri.ttf')) | |
pdfmetrics.registerFont(TTFont("CalibriBold", '/Library/Fonts/Microsoft/Calibri Bold.ttf')) | |
for y in get_year_intervals_from_books(): | |
c = canvas.Canvas("tmp.pdf", pagesize=(width/2, height)) | |
c.setFillColorRGB(206/255.0,23/255.0,25/255.0) | |
c.setFont("CalibriBold", 300) | |
c.translate(2*cm, height-cm) | |
c.rotate(270) | |
c.drawString(0, 0, '%s' % y) | |
c.showPage() | |
c.save() | |
os.system(r'sips -s format png tmp.pdf --resampleHeight %s --out jaren/jaren%s.png' % (ROW_HEIGHT, y)) | |
def clean_dirs(): | |
for folder in (BY_book, BY_rows, JAREN): | |
for filename in os.listdir(folder): | |
os.remove(os.path.join(folder, filename)) | |
if __name__ == '__main__': | |
if (len(sys.argv) > 1) and sys.argv[1] == 'go': | |
make_yearplace_pdfs() | |
make_by_book() | |
make_year_pdfs() | |
make_rows() | |
make_big() | |
else: | |
sys.stderr.write('Try %s go to generate\n' % sys.argv[0]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment