text_drawers.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. from PIL import Image, ImageDraw, ImageFont
  2. import numpy as np
  3. from utils.logging import get_logger
  4. class StdTextDrawer(object):
  5. def __init__(self, config):
  6. self.logger = get_logger()
  7. self.max_width = config["Global"]["image_width"]
  8. self.char_list = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  9. self.height = config["Global"]["image_height"]
  10. self.font_dict = {}
  11. self.load_fonts(config["TextDrawer"]["fonts"])
  12. self.support_languages = list(self.font_dict)
  13. def load_fonts(self, fonts_config):
  14. for language in fonts_config:
  15. font_path = fonts_config[language]
  16. font_height = self.get_valid_height(font_path)
  17. font = ImageFont.truetype(font_path, font_height)
  18. self.font_dict[language] = font
  19. def get_valid_height(self, font_path):
  20. font = ImageFont.truetype(font_path, self.height - 4)
  21. _, font_height = font.getsize(self.char_list)
  22. if font_height <= self.height - 4:
  23. return self.height - 4
  24. else:
  25. return int((self.height - 4)**2 / font_height)
  26. def draw_text(self, corpus, language="en", crop=True):
  27. if language not in self.support_languages:
  28. self.logger.warning(
  29. "language {} not supported, use en instead.".format(language))
  30. language = "en"
  31. if crop:
  32. width = min(self.max_width, len(corpus) * self.height) + 4
  33. else:
  34. width = len(corpus) * self.height + 4
  35. bg = Image.new("RGB", (width, self.height), color=(127, 127, 127))
  36. draw = ImageDraw.Draw(bg)
  37. char_x = 2
  38. font = self.font_dict[language]
  39. for i, char_i in enumerate(corpus):
  40. char_size = font.getsize(char_i)[0]
  41. draw.text((char_x, 2), char_i, fill=(0, 0, 0), font=font)
  42. char_x += char_size
  43. if char_x >= width:
  44. corpus = corpus[0:i + 1]
  45. self.logger.warning("corpus length exceed limit: {}".format(
  46. corpus))
  47. break
  48. text_input = np.array(bg).astype(np.uint8)
  49. text_input = text_input[:, 0:char_x, :]
  50. return corpus, text_input