from PIL import Image, ImageEnhance, ImageFont, ImageDraw import os import textwrap import qrcode import urllib.parse location = os.path.dirname(os.path.realpath(__file__)) def print_forum_label(thread): im = Image.open(location + '/label.png') width, height = im.size draw = ImageDraw.Draw(im) #logging.info('Printing forum thread: %s', thread['title']) url = 'https://forum.protospace.ca/t/{}/'.format(thread['id']) qr = qrcode.make(url, version=6, box_size=9) im.paste(qr, (840, 150)) item_size = 150 w = 9999 while w > 1200: item_size -= 5 font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', item_size) w, h = draw.textsize(url, font=font) x, y = (width - w) / 2, ((height - h) / 2) + 300 draw.text((x, y), url, font=font, fill='black') font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf', 80) draw.text((120, 150), 'Forum Thread', font=font, fill='black') text = thread['title'] MARGIN = 50 MAX_W, MAX_H, PAD = 900 - (MARGIN*2), 450 - (MARGIN*2), 5 def fit_text(text, font_size): font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', font_size) for cols in range(100, 1, -4): print('trying size', font_size, 'cols', cols) paragraph = textwrap.wrap(text, width=cols, break_long_words=False) total_h = -PAD total_w = 0 for line in paragraph: w, h = draw.textsize(line, font=font) if w > total_w: total_w = w total_h += h + PAD if total_w <= MAX_W and total_h < MAX_H: return True, paragraph, total_h return False, [], 0 font_size_range = [1, 500] # Thanks to Alex (UDIA) for the binary search algorithm while abs(font_size_range[0] - font_size_range[1]) > 1: font_size = sum(font_size_range) // 2 image_fit, check_para, check_h = fit_text(text, font_size) if image_fit: print('Does fit') font_size_range = [font_size, font_size_range[1]] good_size = font_size paragraph = check_para total_h = check_h else: print('Does not fit') font_size_range = [font_size_range[0], font_size] font = ImageFont.truetype('/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf', good_size) offset = height - MAX_H - MARGIN start_h = -100 + offset current_h = start_h for line in paragraph: w, h = draw.textsize(line, font=font) x, y = (MAX_W - w) / 2, current_h draw.text((x+MARGIN, y), line, font=font, fill='black') current_h += h + PAD im.save('tmp.png') print_forum_label(dict(id=10197, title='Pitch: A wild split-flap display appeared!'))