2017-11-02 21:08:17 +00:00
|
|
|
#!/usr/bin/env python3
|
2010-10-16 11:49:45 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# vi:si:et:sw=4:sts=4:ts=4
|
2010-11-30 17:29:33 +00:00
|
|
|
from __future__ import division
|
|
|
|
import os
|
|
|
|
|
2016-06-25 18:36:20 +00:00
|
|
|
from PIL import Image
|
|
|
|
from PIL import ImageDraw
|
2013-06-06 11:54:01 +00:00
|
|
|
import json
|
2010-10-16 11:49:45 +00:00
|
|
|
from optparse import OptionParser
|
2013-06-06 11:54:01 +00:00
|
|
|
import ox
|
2010-10-16 11:49:45 +00:00
|
|
|
from ox.image import drawText, wrapText
|
|
|
|
import sys
|
|
|
|
|
2017-11-02 21:08:17 +00:00
|
|
|
|
|
|
|
root_dir = os.path.normpath(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
|
2011-10-27 22:15:37 +00:00
|
|
|
static_root = os.path.join(os.path.dirname(__file__), 'data')
|
2010-10-16 11:49:45 +00:00
|
|
|
|
2013-06-06 11:54:01 +00:00
|
|
|
def render_poster(data, poster):
|
|
|
|
title = ox.decode_html(data.get('title', ''))
|
|
|
|
id = data['id']
|
2013-06-06 12:08:10 +00:00
|
|
|
frame = data.get('frame')
|
|
|
|
timeline = data.get('timeline')
|
2013-06-06 11:54:01 +00:00
|
|
|
|
2010-10-16 11:49:45 +00:00
|
|
|
poster_width = 640
|
|
|
|
poster_height = 1024
|
|
|
|
poster_ratio = poster_width / poster_height
|
|
|
|
poster_color = (255, 255, 0)
|
|
|
|
poster_image = Image.new('RGB', (poster_width, poster_height))
|
2011-10-27 23:16:43 +00:00
|
|
|
font_file = os.path.join(static_root, 'DejaVuSansCondensedBold.ttf')
|
2010-10-16 11:49:45 +00:00
|
|
|
font_size = 48
|
|
|
|
|
|
|
|
# timeline
|
|
|
|
timeline_height = 64
|
|
|
|
timeline_lines = 16
|
2011-08-13 10:03:30 +00:00
|
|
|
if timeline:
|
|
|
|
timeline_image = Image.open(timeline)
|
|
|
|
timeline_image = timeline_image.resize((10240, timeline_height), Image.ANTIALIAS)
|
|
|
|
for i in range(timeline_lines):
|
|
|
|
line_image = timeline_image.crop((i * poster_width, 0, (i + 1) * poster_width, 64))
|
|
|
|
poster_image.paste(line_image, (0, i * timeline_height))
|
2010-10-16 11:49:45 +00:00
|
|
|
|
|
|
|
# id
|
|
|
|
text = 'Pad.ma/' + id
|
|
|
|
text_image = Image.new('RGB', (1, 1))
|
|
|
|
text_size = drawText(text_image, (0, 0), text, font_file, font_size, poster_color)
|
|
|
|
text_width = poster_width
|
|
|
|
text_height = timeline_height
|
|
|
|
text_left = int((poster_width - text_width) / 2)
|
|
|
|
text_top = 14 * timeline_height
|
|
|
|
for y in range(text_top, text_top + text_height):
|
|
|
|
for x in range(text_left, text_left + text_width):
|
|
|
|
if y < text_top + 4 or y >= text_top + text_height - 4:
|
|
|
|
poster_image.putpixel((x, y), poster_color)
|
|
|
|
else:
|
|
|
|
pixel = list(poster_image.getpixel((x, y)))
|
|
|
|
for c in range(3):
|
2011-01-28 08:48:38 +00:00
|
|
|
pixel[c] = int((pixel[c] + poster_color[c]) / 4)
|
2010-10-16 11:49:45 +00:00
|
|
|
poster_image.putpixel((x, y), tuple(pixel))
|
|
|
|
drawText(poster_image, ((poster_width - text_size[0]) / 2, text_top + (text_height - text_size[1]) / 2), text, font_file, font_size, poster_color)
|
|
|
|
poster_image.save(poster)
|
|
|
|
|
2017-11-02 21:11:09 +00:00
|
|
|
|
2010-10-16 11:49:45 +00:00
|
|
|
def main():
|
|
|
|
parser = OptionParser()
|
2013-06-06 11:54:01 +00:00
|
|
|
parser.add_option('-d', '--data', dest='data', help='json file with metadata', default=None)
|
2013-06-06 16:21:49 +00:00
|
|
|
parser.add_option('-p', '--poster', dest='poster', help='Poster (image file to be written)')
|
2010-10-16 11:49:45 +00:00
|
|
|
(options, args) = parser.parse_args()
|
2013-06-06 11:54:01 +00:00
|
|
|
|
|
|
|
if None in (options.data, options.poster):
|
2010-10-16 11:49:45 +00:00
|
|
|
parser.print_help()
|
|
|
|
sys.exit()
|
|
|
|
|
2013-06-06 11:54:01 +00:00
|
|
|
if options.data == '-':
|
|
|
|
data = json.load(sys.stdin)
|
|
|
|
else:
|
|
|
|
with open(options.data) as f:
|
|
|
|
data = json.load(f)
|
2013-06-06 12:05:15 +00:00
|
|
|
render_poster(data, options.poster)
|
2010-10-16 11:49:45 +00:00
|
|
|
|
2017-11-02 21:11:09 +00:00
|
|
|
|
2010-10-16 11:49:45 +00:00
|
|
|
if __name__ == "__main__":
|
|
|
|
main()
|