🔧 Draw Text¶
Documentation¶
- Class name:
DrawText+
- Category:
essentials
- Output node:
False
The DrawText+ node is designed for rendering text onto images, allowing for customization of text appearance including font, size, color, and background. It supports text alignment and shadow effects, providing a versatile tool for image annotation and graphic design tasks.
Input types¶
Required¶
text
- The text to be rendered on the image. It's a crucial parameter as it defines the content of the annotation.
- Comfy dtype:
STRING
- Python dtype:
str
font
- Specifies the font used to render the text, affecting the style and appearance of the text on the image.
- Comfy dtype:
COMBO[STRING]
- Python dtype:
str
size
- Determines the size of the text, impacting its visibility and how it occupies space within the image.
- Comfy dtype:
INT
- Python dtype:
int
color
- The color of the text, defining its visual impact and how it contrasts with the image background.
- Comfy dtype:
STRING
- Python dtype:
str
background_color
- The color of the text background, which can enhance readability or aesthetic appeal depending on the image context.
- Comfy dtype:
STRING
- Python dtype:
str
shadow_distance
- The distance of the shadow from the text, adding depth and emphasis to the text rendering.
- Comfy dtype:
INT
- Python dtype:
int
shadow_blur
- Controls the blur intensity of the text shadow, affecting the softness and spread of the shadow effect.
- Comfy dtype:
INT
- Python dtype:
int
shadow_color
- The color of the shadow, which can add visual interest or improve text legibility.
- Comfy dtype:
STRING
- Python dtype:
str
alignment
- Determines the text alignment (left, center, right) within the specified area, influencing the layout and overall appearance.
- Comfy dtype:
COMBO[STRING]
- Python dtype:
str
width
- The width of the area where the text is to be rendered, defining the text wrapping and layout constraints.
- Comfy dtype:
INT
- Python dtype:
int
height
- The height of the area where the text is to be rendered, defining the vertical space available for the text.
- Comfy dtype:
INT
- Python dtype:
int
Output types¶
image
- Comfy dtype:
IMAGE
- The resulting image with the rendered text.
- Python dtype:
torch.Tensor
- Comfy dtype:
mask
- Comfy dtype:
MASK
- A mask indicating the areas of the image occupied by the text, useful for further processing or compositing.
- Python dtype:
torch.Tensor
- Comfy dtype:
Usage tips¶
- Infra type:
GPU
- Common nodes: unknown
Source code¶
class DrawText:
@classmethod
def INPUT_TYPES(s):
return {
"required": {
"text": ("STRING", { "multiline": True, "dynamicPrompts": True, "default": "Hello, World!" }),
"font": ([f for f in os.listdir(FONTS_DIR) if f.endswith('.ttf') or f.endswith('.otf')], ),
"size": ("INT", { "default": 56, "min": 1, "max": 9999, "step": 1 }),
"color": ("STRING", { "multiline": False, "default": "#FFFFFF" }),
"background_color": ("STRING", { "multiline": False, "default": "#00000000" }),
"shadow_distance": ("INT", { "default": 0, "min": 0, "max": 100, "step": 1 }),
"shadow_blur": ("INT", { "default": 0, "min": 0, "max": 100, "step": 1 }),
"shadow_color": ("STRING", { "multiline": False, "default": "#000000" }),
"alignment": (["left", "center", "right"],),
"width": ("INT", { "default": 0, "min": 0, "max": MAX_RESOLUTION, "step": 1 }),
"height": ("INT", { "default": 0, "min": 0, "max": MAX_RESOLUTION, "step": 1 }),
},
}
RETURN_TYPES = ("IMAGE", "MASK",)
FUNCTION = "execute"
CATEGORY = "essentials"
def execute(self, text, font, size, color, background_color, shadow_distance, shadow_blur, shadow_color, alignment, width, height):
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)
width = width if width > 0 else text_width
height = height if height > 0 else text_height
background_color = ImageColor.getrgb(background_color)
image = Image.new('RGBA', (width + shadow_distance, height + shadow_distance), color=background_color)
image_shadow = None
if shadow_distance > 0:
image_shadow = Image.new('RGBA', (width + shadow_distance, height + shadow_distance), color=background_color)
for i, line in enumerate(lines):
line_width = font.getbbox(line)[2]
#text_height =font.getbbox(line)[3]
if alignment == "left":
x = 0
elif alignment == "center":
x = (width - line_width) / 2
elif alignment == "right":
x = width - line_width
y = i * line_height
draw = ImageDraw.Draw(image)
draw.text((x, y), line, font=font, fill=color)
if image_shadow is not None:
draw = ImageDraw.Draw(image_shadow)
draw.text((x + shadow_distance, y + shadow_distance), line, font=font, fill=shadow_color)
if image_shadow is not None:
image_shadow = image_shadow.filter(ImageFilter.GaussianBlur(shadow_blur))
image = Image.alpha_composite(image_shadow, image)
image = pb(T.ToTensor()(image).unsqueeze(0))
mask = image[:, :, :, 3] if image.shape[3] == 4 else torch.ones_like(image[:, :, :, 0])
return (image[:, :, :, :3], mask,)