text_drawers.py 3.1 KB
Newer Older
W
weishengyu 已提交
1 2
from PIL import Image, ImageDraw, ImageFont
import numpy as np
3
import cv2
W
weishengyu 已提交
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
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)

32 33 34 35 36
    def draw_text(self,
                  corpus,
                  language="en",
                  crop=True,
                  style_input_width=None):
W
weishengyu 已提交
37 38 39 40 41 42 43 44
        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
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81

        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:]
                    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)
                corpus = corpus[i:]
W
weishengyu 已提交
82 83
                break

84
        return corpus_list, text_input_list