text_drawers.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. from PIL import Image, ImageDraw, ImageFont
  2. import numpy as np
  3. import cv2
  4. from utils.logging import get_logger
  5. class StdTextDrawer(object):
  6. def __init__(self, config):
  7. self.logger = get_logger()
  8. self.max_width = config["Global"]["image_width"]
  9. self.char_list = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  10. self.height = config["Global"]["image_height"]
  11. self.font_dict = {}
  12. self.load_fonts(config["TextDrawer"]["fonts"])
  13. self.support_languages = list(self.font_dict)
  14. def load_fonts(self, fonts_config):
  15. for language in fonts_config:
  16. font_path = fonts_config[language]
  17. font_height = self.get_valid_height(font_path)
  18. font = ImageFont.truetype(font_path, font_height)
  19. self.font_dict[language] = font
  20. def get_valid_height(self, font_path):
  21. font = ImageFont.truetype(font_path, self.height - 4)
  22. _, font_height = font.getsize(self.char_list)
  23. if font_height <= self.height - 4:
  24. return self.height - 4
  25. else:
  26. return int((self.height - 4)**2 / font_height)
  27. def draw_text(self,
  28. corpus,
  29. language="en",
  30. crop=True,
  31. style_input_width=None):
  32. if language not in self.support_languages:
  33. self.logger.warning(
  34. "language {} not supported, use en instead.".format(language))
  35. language = "en"
  36. if crop:
  37. width = min(self.max_width, len(corpus) * self.height) + 4
  38. else:
  39. width = len(corpus) * self.height + 4
  40. if style_input_width is not None:
  41. width = min(width, style_input_width)
  42. corpus_list = []
  43. text_input_list = []
  44. while len(corpus) != 0:
  45. bg = Image.new("RGB", (width, self.height), color=(127, 127, 127))
  46. draw = ImageDraw.Draw(bg)
  47. char_x = 2
  48. font = self.font_dict[language]
  49. i = 0
  50. while i < len(corpus):
  51. char_i = corpus[i]
  52. char_size = font.getsize(char_i)[0]
  53. # split when char_x exceeds char size and index is not 0 (at least 1 char should be wroten on the image)
  54. if char_x + char_size >= width and i != 0:
  55. text_input = np.array(bg).astype(np.uint8)
  56. text_input = text_input[:, 0:char_x, :]
  57. corpus_list.append(corpus[0:i])
  58. text_input_list.append(text_input)
  59. corpus = corpus[i:]
  60. i = 0
  61. break
  62. draw.text((char_x, 2), char_i, fill=(0, 0, 0), font=font)
  63. char_x += char_size
  64. i += 1
  65. # the whole text is shorter than style input
  66. if i == len(corpus):
  67. text_input = np.array(bg).astype(np.uint8)
  68. text_input = text_input[:, 0:char_x, :]
  69. corpus_list.append(corpus[0:i])
  70. text_input_list.append(text_input)
  71. break
  72. return corpus_list, text_input_list