diff --git a/image.py b/image.py index 1891e23..34e37ca 100644 --- a/image.py +++ b/image.py @@ -600,6 +600,12 @@ def INPUT_TYPES(s): def execute(self, tiles, overlap_x, overlap_y, rows, cols): tile_h, tile_w = tiles.shape[1:3] + + if rows == 1: + overlap_y = 0 + if cols == 1: + overlap_x = 0 + tile_h -= overlap_y tile_w -= overlap_x out_w = cols * tile_w @@ -632,15 +638,8 @@ def execute(self, tiles, overlap_x, overlap_y, rows, cols): # feather the overlap on top if i > 0: mask[:, :overlap_y, :] *= torch.linspace(0, 1, overlap_y, device=tiles.device, dtype=tiles.dtype).unsqueeze(1) - # feather the overlap on bottom - #if i < rows - 1: - # mask[:, -overlap_y:, :] *= torch.linspace(1, 0, overlap_y, device=tiles.device, dtype=tiles.dtype).unsqueeze(1) - # feather the overlap on left if j > 0: mask[:, :, :overlap_x] *= torch.linspace(0, 1, overlap_x, device=tiles.device, dtype=tiles.dtype).unsqueeze(0) - # feather the overlap on right - #if j < cols - 1: - # mask[:, :, -overlap_x:] *= torch.linspace(1, 0, overlap_x, device=tiles.device, dtype=tiles.dtype).unsqueeze(0) mask = mask.unsqueeze(-1).repeat(1, 1, 1, tiles.shape[3]) tile = tiles[i * cols + j] * mask diff --git a/text.py b/text.py index 132ce03..fc286ab 100644 --- a/text.py +++ b/text.py @@ -3,6 +3,57 @@ from nodes import MAX_RESOLUTION import torchvision.transforms.v2 as T +def calculate_metrics (lines, font): + # Calculate the width and height of the text + text_width = max(font.getbbox(line)[2] for line in lines) + line_height = font.getmask(lines[0]).getbbox()[3] + font.getmetrics()[1] # add descent to height + text_height = line_height * len(lines) + return text_width, text_height, line_height + +def get_fonts (): + return sorted([f for f in os.listdir(FONTS_DIR) if f.endswith('.ttf') or f.endswith('.otf')]) + +class DetectFontSize: + @classmethod + def INPUT_TYPES(s): + return { + "required": { + "text": ("STRING", { "multiline": True, "dynamicPrompts": True, "default": "Hello, World!" }), + "font": (get_fonts(), ), + "scale": ("FLOAT", { "default": 1.0, "min": 0.001, "max": 100.0, "step": 0.01 }), + "area_width": ("INT", { "default": 0, "min": 0, "max": 4096, "step": 1 }), + "area_height": ("INT", { "default": 0, "min": 0, "max": 4096, "step": 1 }), + } + } + + RETURN_TYPES = ("INT", "STRING",) + FUNCTION = "execute" + CATEGORY = "essentials/text" + + def get_text_size (self, text, font, size): + from PIL import ImageFont + font = ImageFont.truetype(os.path.join(FONTS_DIR, font), size) + text_width, text_height, line_height = calculate_metrics(text, font) + return text_width, text_height, line_height + + def execute(self, text, font, scale, area_width, area_height): + lines = text.split("\n") + font_size_a, font_size_b = 10, 20 + text_width_a, text_height_a, _ = self.get_text_size(lines, font, font_size_a) + text_width_b, text_height_b, _ = self.get_text_size(lines, font, font_size_b) + + text_aspect = text_width_a / text_height_a + area_aspect = area_width / area_height + + percent_change = 1.0 + # touching = min(area_height - text_height_a, area_width - text_width_a) + if area_aspect > text_aspect: + percent_change = (area_height - text_height_a) / (text_height_b - text_height_a) + else: percent_change = (area_width - text_width_a) / (text_width_b - text_width_a) + + font_size = round((font_size_a + (font_size_b - font_size_a) * percent_change) * scale) + return (2 if font_size <= 0 else font_size, text, ) + FONTS_DIR = os.path.join(os.path.dirname(os.path.realpath(__file__)), "fonts") class DrawText: @classmethod @@ -10,7 +61,7 @@ def INPUT_TYPES(s): return { "required": { "text": ("STRING", { "multiline": True, "dynamicPrompts": True, "default": "Hello, World!" }), - "font": (sorted([f for f in os.listdir(FONTS_DIR) if f.endswith('.ttf') or f.endswith('.otf')]), ), + "font": (get_fonts(), ), "size": ("INT", { "default": 56, "min": 1, "max": 9999, "step": 1 }), "color": ("STRING", { "multiline": False, "default": "#FFFFFF" }), "background_color": ("STRING", { "multiline": False, "default": "#00000000" }), @@ -35,13 +86,8 @@ def execute(self, text, font, size, color, background_color, shadow_distance, sh from PIL import Image, ImageDraw, ImageFont, ImageColor, ImageFilter font = ImageFont.truetype(os.path.join(FONTS_DIR, font), size) - lines = text.split("\n") - - # Calculate the width and height of the text - text_width = max(font.getbbox(line)[2] for line in lines) - line_height = font.getmask(text).getbbox()[3] + font.getmetrics()[1] # add descent to height - text_height = line_height * len(lines) + text_width, text_height, line_height = calculate_metrics(lines, font) if img_composite is not None: img_composite = T.ToPILImage()(img_composite.permute([0,3,1,2])[0]).convert('RGBA') @@ -103,8 +149,10 @@ def execute(self, text, font, size, color, background_color, shadow_distance, sh TEXT_CLASS_MAPPINGS = { "DrawText+": DrawText, + "DetectFontSize+": DetectFontSize, } TEXT_NAME_MAPPINGS = { "DrawText+": "🔧 Draw Text", + "DetectFontSize+": "🔧 Detect Font Size", } \ No newline at end of file