123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- from PIL import Image, ImageDraw, ImageFont
- import numpy as np
- import cv2
- from utils.logging import get_logger
- class StdTextDrawer(object):
- def __init__(self, config):
- self.logger = get_logger()
- self.max_width = config["Global"]["image_width"]
- self.char_list = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
- self.height = config["Global"]["image_height"]
- self.font_dict = {}
- self.load_fonts(config["TextDrawer"]["fonts"])
- self.support_languages = list(self.font_dict)
- def load_fonts(self, fonts_config):
- for language in fonts_config:
- font_path = fonts_config[language]
- font_height = self.get_valid_height(font_path)
- font = ImageFont.truetype(font_path, font_height)
- self.font_dict[language] = font
- def get_valid_height(self, font_path):
- font = ImageFont.truetype(font_path, self.height - 4)
- _, font_height = font.getsize(self.char_list)
- if font_height <= self.height - 4:
- return self.height - 4
- else:
- return int((self.height - 4)**2 / font_height)
- def draw_text(self,
- corpus,
- language="en",
- crop=True,
- style_input_width=None):
- if language not in self.support_languages:
- self.logger.warning(
- "language {} not supported, use en instead.".format(language))
- language = "en"
- if crop:
- width = min(self.max_width, len(corpus) * self.height) + 4
- else:
- width = len(corpus) * self.height + 4
- if style_input_width is not None:
- width = min(width, style_input_width)
- corpus_list = []
- text_input_list = []
- while len(corpus) != 0:
- bg = Image.new("RGB", (width, self.height), color=(127, 127, 127))
- draw = ImageDraw.Draw(bg)
- char_x = 2
- font = self.font_dict[language]
- i = 0
- while i < len(corpus):
- char_i = corpus[i]
- char_size = font.getsize(char_i)[0]
- # split when char_x exceeds char size and index is not 0 (at least 1 char should be wroten on the image)
- if char_x + char_size >= width and i != 0:
- text_input = np.array(bg).astype(np.uint8)
- text_input = text_input[:, 0:char_x, :]
- corpus_list.append(corpus[0:i])
- text_input_list.append(text_input)
- corpus = corpus[i:]
- i = 0
- break
- draw.text((char_x, 2), char_i, fill=(0, 0, 0), font=font)
- char_x += char_size
- i += 1
- # the whole text is shorter than style input
- if i == len(corpus):
- text_input = np.array(bg).astype(np.uint8)
- text_input = text_input[:, 0:char_x, :]
- corpus_list.append(corpus[0:i])
- text_input_list.append(text_input)
- break
- return corpus_list, text_input_list
|