diff --git a/adacher.py b/adacher.py index fb81edc1ed94c9fc94cc73a7b15e93533d6f6630..3ab5112ed0d2b588688ee112a2061544198d910c 100755 --- a/adacher.py +++ b/adacher.py @@ -7,53 +7,113 @@ from PIL import Image from PIL import ImageFont from PIL import ImageDraw +##### Argument parsing parser = argparse.ArgumentParser( prog='Adacher', description='Generate beautiful adachers') parser.add_argument('text') +parser.add_argument('--imgBase', type=str, default="/home/elliu/Nextcloud/Adachi_white.png") parser.add_argument('--nobox', action='store_true', default=False) +parser.add_argument('--nowrap', action='store_true', default=False) parser.add_argument('--boxtop', type=float, default=0.65) parser.add_argument('--boxheight', type=float, default=0.20) - +parser.add_argument('--textVertMargin', type=int, default=5) +parser.add_argument('--textHoriMargin', type=int, default=10) +parser.add_argument('--fontPath', type=str, default="/home/elliu/Nextcloud/COMIC.TTF") +parser.add_argument('--textCol', type=str, default="ff0000") +parser.add_argument('--boxCol', type=str, default="ffffff") +parser.add_argument('--align', type=str, default="center") args = parser.parse_args() withBox = not args.nobox -print(withBox) +withWrap = not args.nowrap + +def hexToCol(st): + return tuple(int(st[i:i+2], 16) for i in (0, 2, 4)) +textCol = hexToCol(args.textCol) +boxCol = hexToCol(args.boxCol) + + +##### Function to calculate font size and line breaks +def growFontToBox(draw, fontPath, text, width, height, wrap=False): + fontsize = 1 + font = ImageFont.truetype(fontPath, fontsize) + fontLeft, fontTop, fontRight, fontBottom = font.getbbox(text) + + if not wrap: + newSize = fontsize + while fontRight-fontLeft < width and fontBottom-fontTop < height: + # iterate until the text size is just larger than the criteria + newSize += 1 + font = ImageFont.truetype(fontPath, fontsize) + fontLeft, fontTop, fontRight, fontBottom = font.getbbox(args.text) + newText = text + else: + newText = text + while True: + print(fontsize) + fontsize += 1 + font = ImageFont.truetype(fontPath, fontsize) + + fontLeft, fontTop, fontRight, fontBottom = draw.multiline_textbbox((0,0), text, font, align=args.align) + + if fontBottom-fontTop >= height: + # Doesn't fit vertically, stop now + break + elif fontRight-fontLeft >= width: + # Doesn't fit horizontally, try to cut the line + textArray = text.split() + tmpText = textArray.pop(0) + while textArray: + fontLeft, fontTop, fontRight, fontBottom = draw.multiline_textbbox((0,0), tmpText + " " + textArray[0], font, align=args.align) + if fontRight-fontLeft > width: + tmpText += "\n" + textArray.pop(0) + else: + tmpText += " " + textArray.pop(0) -def get_offset_for_true_mm(text, draw, font): - anchor_bbox = draw.textbbox((0, 0), text, font=font, anchor='lt') - anchor_center = (anchor_bbox[0] + anchor_bbox[2]) // 2, (anchor_bbox[1] + anchor_bbox[3]) // 2 - mask_bbox = font.getmask(text).getbbox() - mask_center = (mask_bbox[0] + mask_bbox[2]) // 2, (mask_bbox[1] + mask_bbox[3]) // 2 - return anchor_center[0] - mask_center[0], anchor_center[1] - mask_center[1] + fontLeft, fontTop, fontRight, fontBottom = draw.multiline_textbbox((0,0), tmpText, font, align=args.align) + if fontRight-fontLeft <= width and fontBottom-fontTop <= height: + newText = tmpText + newSize = fontsize + else: + break + else: + newSize = fontsize + newText = text -img = Image.open("/home/elliu/Pictures/Adachi_white.png") + return newText, newSize + + +img = Image.open(args.imgBase) width,height = img.size -args.boxbot = args.boxtop + args.boxheight -if args.boxbot != 1: - args.boxbot = args.boxtop + args.boxheight - tmp = Image.new("RGB", (width, math.floor(height*args.boxbot))) + + +##### Add white box +boxTop = args.boxtop * img.size[1] +boxHeight = args.boxheight * img.size[1] +boxBot = math.floor(boxTop + boxHeight) +if args.boxtop + args.boxheight != 1: + tmp = Image.new("RGB", (width, boxBot)) tmp.paste(img, (0,0)) img = tmp draw = ImageDraw.Draw(img) +draw.rectangle([0, boxTop, width, boxBot], boxCol) -draw.rectangle([0, args.boxtop*height, width, (args.boxtop + args.boxheight)*height], (255,255,255)) - -fontsize = 1 -img_fraction = 0.20 -fontPath = "/home/elliu/Downloads/fonts/COMIC.TTF" -font = ImageFont.truetype(fontPath, fontsize) -while font.getsize(args.text)[0] < img_fraction*img.size[0]: - # iterate until the text size is just larger than the criteria - fontsize += 1 - font = ImageFont.truetype(fontPath, fontsize) - -font = ImageFont.truetype(fontPath, fontsize) +newText, fontsize = growFontToBox(draw, args.fontPath, args.text, img.size[0] - 2*args.textHoriMargin, boxHeight - 2*args.textVertMargin, withWrap) -offset = get_offset_for_true_mm(args.text, draw, font) +font = ImageFont.truetype(args.fontPath, fontsize) +fontLeft, fontTop, fontRight, fontBottom = draw.multiline_textbbox((0,0), newText, font, align=args.align) -draw.text(((1 - img_fraction)*width/2 + offset[0], height/2 + offset[1]), args.text, (255,0,0), font=font) +draw.text(( + (width - (fontRight - fontLeft))/2, + boxTop + (boxHeight - (fontBottom- fontTop))/2 - fontTop + ), + newText, + textCol, + font=font, + align=args.align +) -img.save('sample-out.png') +img.save('/tmp/sample-out.png')