| 
									
										
										
										
											2020-12-15 11:26:54 +08:00
										 |  |  | from PIL import Image, ImageDraw, ImageFont | 
					
						
							|  |  |  | import numpy as np | 
					
						
							| 
									
										
										
										
											2021-02-22 11:14:13 +08:00
										 |  |  | import cv2 | 
					
						
							| 
									
										
										
										
											2020-12-15 11:26:54 +08:00
										 |  |  | 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) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-22 11:14:13 +08:00
										 |  |  |     def draw_text(self, | 
					
						
							|  |  |  |                   corpus, | 
					
						
							|  |  |  |                   language="en", | 
					
						
							|  |  |  |                   crop=True, | 
					
						
							|  |  |  |                   style_input_width=None): | 
					
						
							| 
									
										
										
										
											2020-12-15 11:26:54 +08:00
										 |  |  |         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 | 
					
						
							| 
									
										
										
										
											2021-02-22 11:14:13 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         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:] | 
					
						
							| 
									
										
										
										
											2021-07-02 10:38:04 +08:00
										 |  |  |                     i = 0 | 
					
						
							| 
									
										
										
										
											2021-02-22 11:14:13 +08:00
										 |  |  |                     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) | 
					
						
							| 
									
										
										
										
											2020-12-15 11:26:54 +08:00
										 |  |  |                 break | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-22 11:14:13 +08:00
										 |  |  |         return corpus_list, text_input_list |