Download ComfyUI-Allor/modules/ImageText.py from thisisAce/runpod_custom_nodes: direct link, hf CLI and curl.
- Browser
- Download file 10.3 kB
-
https://huggingface.co/thisisAce/runpod_custom_nodes/resolve/main/ComfyUI-Allor/modules/ImageText.py
- Command line
-
hf download hf://thisisAce/runpod_custom_nodes/ComfyUI-Allor/modules/ImageText.py
-
curl -L -o ImageText.py https://huggingface.co/thisisAce/runpod_custom_nodes/resolve/main/ComfyUI-Allor/modules/ImageText.py
10.3 kB
| from PIL import Image, ImageDraw, ImageFont | |
| import folder_paths | |
| class ImageText: | |
| def __init__(self): | |
| pass | |
| def INPUT_TYPES(cls): | |
| return { | |
| "required": { | |
| "text": ("STRING", {"multiline": False}), | |
| "font": (folder_paths.get_filename_list("fonts"),), | |
| "size": ("INT", { | |
| "default": 28, | |
| "min": 1, | |
| "step": 1 | |
| }), | |
| "red": ("INT", { | |
| "default": 255, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "green": ("INT", { | |
| "default": 255, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "blue": ("INT", { | |
| "default": 255, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "alpha": ("FLOAT", { | |
| "default": 1.0, | |
| "max": 1.0, | |
| "step": 0.01 | |
| }), | |
| "margin_x": ("INT", { | |
| "default": 0, | |
| "step": 1 | |
| }), | |
| "margin_y": ("INT", { | |
| "default": 0, | |
| "step": 1 | |
| }), | |
| }, | |
| } | |
| RETURN_TYPES = ("IMAGE",) | |
| FUNCTION = "node" | |
| CATEGORY = "image/draw" | |
| def node(self, text, font, size, red, green, blue, alpha, margin_x, margin_y): | |
| outline_size = 0 | |
| outline_red = 255 | |
| outline_green = 255 | |
| outline_blue = 255 | |
| return ImageTextOutlined().node( | |
| text, | |
| font, | |
| size, | |
| red, | |
| green, | |
| blue, | |
| outline_size, | |
| outline_red, | |
| outline_green, | |
| outline_blue, | |
| alpha, | |
| margin_x, | |
| margin_y | |
| ) | |
| class ImageTextOutlined: | |
| def __init__(self): | |
| pass | |
| def INPUT_TYPES(cls): | |
| return { | |
| "required": { | |
| "text": ("STRING", {"multiline": False}), | |
| "font": (folder_paths.get_filename_list("fonts"),), | |
| "size": ("INT", { | |
| "default": 28, | |
| "min": 1, | |
| "step": 1 | |
| }), | |
| "red": ("INT", { | |
| "default": 255, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "green": ("INT", { | |
| "default": 255, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "blue": ("INT", { | |
| "default": 255, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "outline_size": ("INT", { | |
| "default": 1, | |
| "step": 1 | |
| }), | |
| "outline_red": ("INT", { | |
| "default": 0, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "outline_green": ("INT", { | |
| "default": 0, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "outline_blue": ("INT", { | |
| "default": 0, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "alpha": ("FLOAT", { | |
| "default": 1.0, | |
| "max": 1.0, | |
| "step": 0.01 | |
| }), | |
| "margin_x": ("INT", { | |
| "default": 0, | |
| "step": 1 | |
| }), | |
| "margin_y": ("INT", { | |
| "default": 0, | |
| "step": 1 | |
| }), | |
| }, | |
| } | |
| RETURN_TYPES = ("IMAGE",) | |
| FUNCTION = "node" | |
| CATEGORY = "image/draw" | |
| def node( | |
| self, text, font, size, red, green, blue, outline_size, outline_red, outline_green, outline_blue, alpha, | |
| margin_x, margin_y | |
| ): | |
| font_path = folder_paths.get_full_path("fonts", font) | |
| font = ImageFont.truetype(font_path, size, encoding="unic") | |
| (left, top, right, bottom) = font.getbbox(text) | |
| canvas = Image.new("RGBA", ( | |
| right + (margin_x + outline_size) * 2, | |
| bottom - top + (margin_y + outline_size) * 2 | |
| ), (0, 0, 0, 0)) | |
| draw = ImageDraw.Draw(canvas) | |
| draw.text( | |
| (margin_x + outline_size, margin_y + outline_size - top), | |
| text=text, fill=(red, green, blue, int(alpha * 255)), | |
| stroke_fill=(outline_red, outline_green, outline_blue, int(alpha * 255)), | |
| stroke_width=outline_size, font=font | |
| ) | |
| return (canvas.image_to_tensor().unsqueeze(0),) | |
| class ImageTextMultiline: | |
| def __init__(self): | |
| pass | |
| def INPUT_TYPES(cls): | |
| return { | |
| "required": { | |
| "text": ("STRING", {"multiline": True}), | |
| "font": (folder_paths.get_filename_list("fonts"),), | |
| "align": (["left", "center", "right"],), | |
| "size": ("INT", { | |
| "default": 28, | |
| "min": 1, | |
| "step": 1 | |
| }), | |
| "red": ("INT", { | |
| "default": 255, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "green": ("INT", { | |
| "default": 255, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "blue": ("INT", { | |
| "default": 255, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "alpha": ("FLOAT", { | |
| "default": 1.0, | |
| "max": 1.0, | |
| "step": 0.01 | |
| }), | |
| "margin_x": ("INT", { | |
| "default": 0, | |
| "step": 1 | |
| }), | |
| "margin_y": ("INT", { | |
| "default": 0, | |
| "step": 1 | |
| }), | |
| }, | |
| } | |
| RETURN_TYPES = ("IMAGE",) | |
| FUNCTION = "node" | |
| CATEGORY = "image/draw" | |
| def node(self, text, font, align, size, red, green, blue, alpha, margin_x, margin_y): | |
| outline_size = 0 | |
| outline_red = 255 | |
| outline_green = 255 | |
| outline_blue = 255 | |
| return ImageTextMultilineOutlined().node( | |
| text, | |
| font, | |
| align, | |
| size, | |
| red, | |
| green, | |
| blue, | |
| outline_size, | |
| outline_red, | |
| outline_green, | |
| outline_blue, | |
| alpha, | |
| margin_x, | |
| margin_y | |
| ) | |
| class ImageTextMultilineOutlined: | |
| def __init__(self): | |
| pass | |
| def INPUT_TYPES(cls): | |
| return { | |
| "required": { | |
| "text": ("STRING", {"multiline": True}), | |
| "font": (folder_paths.get_filename_list("fonts"),), | |
| "align": (["left", "center", "right"],), | |
| "size": ("INT", { | |
| "default": 28, | |
| "min": 1, | |
| "step": 1 | |
| }), | |
| "red": ("INT", { | |
| "default": 255, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "green": ("INT", { | |
| "default": 255, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "blue": ("INT", { | |
| "default": 255, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "outline_size": ("INT", { | |
| "default": 1, | |
| "step": 1 | |
| }), | |
| "outline_red": ("INT", { | |
| "default": 0, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "outline_green": ("INT", { | |
| "default": 0, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "outline_blue": ("INT", { | |
| "default": 0, | |
| "max": 255, | |
| "step": 1 | |
| }), | |
| "alpha": ("FLOAT", { | |
| "default": 1.0, | |
| "max": 1.0, | |
| "step": 0.01 | |
| }), | |
| "margin_x": ("INT", { | |
| "default": 0, | |
| "step": 1 | |
| }), | |
| "margin_y": ("INT", { | |
| "default": 0, | |
| "step": 1 | |
| }), | |
| }, | |
| } | |
| RETURN_TYPES = ("IMAGE",) | |
| FUNCTION = "node" | |
| CATEGORY = "image/draw" | |
| def node( | |
| self, text, font, align, size, red, green, blue, outline_size, outline_red, outline_green, outline_blue, | |
| alpha, margin_x, margin_y | |
| ): | |
| font_path = folder_paths.get_full_path("fonts", font) | |
| font = ImageFont.truetype(font_path, size, encoding="unic") | |
| lines = text.split('\n').__len__() | |
| (_, top, _, _) = font.getbbox(text) | |
| canvas = Image.new("RGBA", (0, 0)) | |
| draw = ImageDraw.Draw(canvas) | |
| text_size = draw.multiline_textbbox((0, 0), text, font) | |
| canvas = Image.new("RGBA", ( | |
| text_size[2] + (margin_x + outline_size) * 2, | |
| text_size[3] - top + (margin_y + (outline_size * lines)) * 2 | |
| ), (0, 0, 0, 0)) | |
| draw = ImageDraw.Draw(canvas) | |
| draw.text( | |
| (margin_x + outline_size, margin_y + outline_size - top), | |
| text=text, fill=(red, green, blue, int(alpha * 255)), | |
| stroke_fill=(outline_red, outline_green, outline_blue, int(alpha * 255)), | |
| stroke_width=outline_size, font=font, align=align | |
| ) | |
| return (canvas.image_to_tensor().unsqueeze(0),) | |
| NODE_CLASS_MAPPINGS = { | |
| "ImageText": ImageText, | |
| "ImageTextOutlined": ImageTextOutlined, | |
| "ImageTextMultiline": ImageTextMultiline, | |
| "ImageTextMultilineOutlined": ImageTextMultilineOutlined | |
| } | |