Spaces:
Runtime error
Runtime error
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) | |
left, top, right, bottom = font.getbbox(self.char_list) | |
_, font_height = right - left, bottom - top | |
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 | |