makeshot.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. from sys import stdin
  2. from textwrap import fill, shorten
  3. from ujson import loads
  4. from PIL import Image, ImageDraw, ImageFont, ImageOps
  5. from emoji import demojize
  6. COLORS = [
  7. (0xee, 0x49, 0x28),
  8. (0x41, 0xa9, 0x03),
  9. (0xe0, 0x96, 0x02),
  10. (0x0f, 0x94, 0xed),
  11. (0x8f, 0x3b, 0xf7),
  12. (0xfc, 0x43, 0x80),
  13. (0x00, 0xa1, 0xc4),
  14. (0xeb, 0x70, 0x02)
  15. ]
  16. data = loads(stdin.read())
  17. output_path = data['output_path']
  18. avatar_path = data['avatar_path']
  19. username = data['username']
  20. username_color = data['username_color']
  21. text = data['text']
  22. username = demojize(username)
  23. text = demojize(text)
  24. if len(username) >= 37:
  25. username = username[:40] + '...'
  26. text = fill(text, width=40, replace_whitespace=False)
  27. hpadding = 18
  28. vpadding = 14
  29. avatar_padding = 12
  30. avatar_dim = 64
  31. font = ImageFont.truetype('./resources/fonts/OpenSans-Regular.ttf', 24)
  32. username_font = ImageFont.truetype('./resources/fonts/OpenSans-Bold.ttf', 22)
  33. tail = Image.open('./resources/tail.png')
  34. mask = Image.new('L', (avatar_dim * 3, avatar_dim * 3), 0)
  35. draw = ImageDraw.Draw(mask)
  36. draw.ellipse((0, 0, avatar_dim * 3, avatar_dim * 3), fill=255)
  37. mask = mask.resize((avatar_dim, avatar_dim), Image.ANTIALIAS)
  38. tail_width, tail_height = tail.size
  39. avatar_width = avatar_dim + avatar_padding
  40. avatar_height = avatar_dim
  41. avatar = Image.open(avatar_path)
  42. avatar = avatar.resize((avatar_dim, avatar_dim))
  43. avatar.putalpha(mask)
  44. username_width, username_height = username_font.getsize(username)
  45. text_width, text_height = font.getsize_multiline(text)
  46. image_width = avatar_width + max(text_width, username_width) + hpadding*2
  47. image_height = text_height + username_height + vpadding*2
  48. message = Image.new('RGBA', (image_width, image_height + 8))
  49. message.paste(avatar, (0, image_height - avatar_height + 5), avatar)
  50. x1 = avatar_dim + avatar_padding
  51. y1 = 0
  52. x2 = x1 + max(text_width, username_width) + hpadding*2
  53. y2 = y1 + text_height + username_height + vpadding*2
  54. draw = ImageDraw.Draw(message)
  55. draw.rounded_rectangle((x1, y1, x2, y2), fill=(43, 43, 43), radius=7)
  56. draw.text((avatar_width + hpadding, vpadding/2), username, font=username_font, fill=COLORS[username_color])
  57. draw.multiline_text((avatar_width + hpadding, username_height + vpadding), text, font=font)
  58. message.paste(tail, (avatar_width - tail_width + 8, image_height - tail_height + 1), tail)
  59. message = ImageOps.contain(message, (512, 512))
  60. message.save(output_path)