from PIL import ImageDraw, Image from .Utils import get_sampler_by_name class ImageDrawArc: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "width": ("INT", { "default": 256, "min": 1, "step": 1 }), "height": ("INT", { "default": 256, "min": 1, "step": 1 }), "size": ("INT", { "default": 1, "min": 1, "step": 1 }), "start_x": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "start": ("INT", { "default": 0, "max": 360, "step": 1 }), "end": ("INT", { "default": 180, "max": 360, "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 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming, PyUnresolvedReferences def node(self, width, height, size, start_x, start_y, end_x, end_y, start, end, red, green, blue, alpha, SSAA, method): canvas = Image.new("RGBA", (width * SSAA, height * SSAA), (0, 0, 0, 0)) draw = ImageDraw.Draw(canvas) draw.arc( [ (width * start_x * SSAA, height * start_y * SSAA), (width * end_x * SSAA, height * end_y * SSAA) ], start, end, (red, green, blue, int(alpha * 255)), size * SSAA ) canvas = canvas.resize((width, height), get_sampler_by_name(method)) return (canvas.image_to_tensor().unsqueeze(0),) class ImageDrawArcByContainer: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "container": ("IMAGE",), "size": ("INT", { "default": 1, "min": 1, "step": 1 }), "start_x": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "start": ("INT", { "default": 0, "max": 360, "step": 1 }), "end": ("INT", { "default": 180, "max": 360, "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 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming def node(self, container, size, start_x, start_y, end_x, end_y, start, end, red, green, blue, alpha, SSAA, method): return ImageDrawArc().node( container[0, :, :, 0].shape[1], container[0, :, :, 0].shape[0], size, start_x, start_y, end_x, end_y, start, end, red, green, blue, alpha, SSAA, method ) class ImageDrawChord: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "width": ("INT", { "default": 256, "min": 1, "step": 1 }), "height": ("INT", { "default": 256, "min": 1, "step": 1 }), "size": ("INT", { "default": 1, "min": 1, "step": 1 }), "start_x": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "start": ("INT", { "default": 0, "max": 360, "step": 1 }), "end": ("INT", { "default": 180, "max": 360, "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 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming, PyUnresolvedReferences def node(self, width, height, size, start_x, start_y, end_x, end_y, start, end, red, green, blue, alpha, SSAA, method): canvas = Image.new("RGBA", (width * SSAA, height * SSAA), (0, 0, 0, 0)) draw = ImageDraw.Draw(canvas) draw.chord( [ (width * start_x * SSAA, height * start_y * SSAA), (width * end_x * SSAA, height * end_y * SSAA) ], start, end, (red, green, blue, int(alpha * 255)), size * SSAA ) canvas = canvas.resize((width, height), get_sampler_by_name(method)) return (canvas.image_to_tensor().unsqueeze(0),) class ImageDrawChordByContainer: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "container": ("IMAGE",), "size": ("INT", { "default": 1, "min": 1, "step": 1 }), "start_x": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "start": ("INT", { "default": 0, "max": 360, "step": 1 }), "end": ("INT", { "default": 180, "max": 360, "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 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming def node(self, container, size, start_x, start_y, end_x, end_y, start, end, red, green, blue, alpha, SSAA, method): return ImageDrawChord().node( container[0, :, :, 0].shape[1], container[0, :, :, 0].shape[0], size, start_x, start_y, end_x, end_y, start, end, red, green, blue, alpha, SSAA, method ) class ImageDrawEllipse: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "width": ("INT", { "default": 256, "min": 1, "step": 1 }), "height": ("INT", { "default": 256, "min": 1, "step": 1 }), "start_x": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "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 }), "outline_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "fill_red": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_green": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_blue": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming, PyUnresolvedReferences def node( self, width, height, start_x, start_y, end_x, end_y, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, SSAA, method ): canvas = Image.new("RGBA", (width * SSAA, height * SSAA), (0, 0, 0, 0)) draw = ImageDraw.Draw(canvas) draw.ellipse( [ (width * start_x * SSAA, height * start_y * SSAA), (width * end_x * SSAA, height * end_y * SSAA) ], (fill_red, fill_green, fill_blue, int(fill_alpha * 255)), (outline_red, outline_green, outline_blue, int(outline_alpha * 255)), outline_size * SSAA ) canvas = canvas.resize((width, height), get_sampler_by_name(method)) return (canvas.image_to_tensor().unsqueeze(0),) class ImageDrawEllipseByContainer: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "container": ("IMAGE",), "start_x": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "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 }), "outline_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "fill_red": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_green": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_blue": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming def node( self, container, start_x, start_y, end_x, end_y, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, SSAA, method ): return ImageDrawEllipse().node( container[0, :, :, 0].shape[1], container[0, :, :, 0].shape[0], start_x, start_y, end_x, end_y, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, SSAA, method ) class ImageDrawLine: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "width": ("INT", { "default": 256, "min": 1, "step": 1 }), "height": ("INT", { "default": 256, "min": 1, "step": 1 }), "size": ("INT", { "default": 1, "min": 1, "step": 1 }), "start_x": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "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 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming, PyUnresolvedReferences def node(self, width, height, size, start_x, start_y, end_x, end_y, red, green, blue, alpha, SSAA, method): canvas = Image.new("RGBA", (width * SSAA, height * SSAA), (0, 0, 0, 0)) draw = ImageDraw.Draw(canvas) draw.line( [ (width * start_x * SSAA, height * start_y * SSAA), (width * end_x * SSAA, height * end_y * SSAA) ], (red, green, blue, int(alpha * 255)), size * SSAA ) canvas = canvas.resize((width, height), get_sampler_by_name(method)) return (canvas.image_to_tensor().unsqueeze(0),) class ImageDrawLineByContainer: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "container": ("IMAGE",), "size": ("INT", { "default": 1, "min": 1, "step": 1 }), "start_x": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "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 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming def node(self, container, size, start_x, start_y, end_x, end_y, red, green, blue, alpha, SSAA, method): return ImageDrawLine().node( container[0, :, :, 0].shape[1], container[0, :, :, 0].shape[0], size, start_x, start_y, end_x, end_y, red, green, blue, alpha, SSAA, method ) class ImageDrawPieslice: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "width": ("INT", { "default": 256, "min": 1, "step": 1 }), "height": ("INT", { "default": 256, "min": 1, "step": 1 }), "start_x": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "start": ("INT", { "default": 0, "max": 360, "step": 1 }), "end": ("INT", { "default": 240, "max": 360, "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 }), "outline_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "fill_red": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_green": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_blue": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming, PyUnresolvedReferences def node( self, width, height, start_x, start_y, end_x, end_y, start, end, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, SSAA, method ): canvas = Image.new("RGBA", (width * SSAA, height * SSAA), (0, 0, 0, 0)) draw = ImageDraw.Draw(canvas) draw.pieslice( ( (width * start_x * SSAA, height * start_y * SSAA), (width * end_x * SSAA, height * end_y * SSAA) ), start, end, (fill_red, fill_green, fill_blue, int(fill_alpha * 255)), (outline_red, outline_green, outline_blue, int(outline_alpha * 255)), outline_size * SSAA ) canvas = canvas.resize((width, height), get_sampler_by_name(method)) return (canvas.image_to_tensor().unsqueeze(0),) class ImageDrawPiesliceByContainer: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "container": ("IMAGE",), "start_x": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.0, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "start": ("INT", { "default": 0, "max": 360, "step": 1 }), "end": ("INT", { "default": 240, "max": 360, "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 }), "outline_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "fill_red": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_green": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_blue": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming def node( self, container, start_x, start_y, end_x, end_y, start, end, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, SSAA, method ): return ImageDrawPieslice().node( container[0, :, :, 0].shape[1], container[0, :, :, 0].shape[0], start_x, start_y, end_x, end_y, start, end, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, SSAA, method ) class ImageDrawRectangle: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "width": ("INT", { "default": 256, "min": 1, "step": 1 }), "height": ("INT", { "default": 256, "min": 1, "step": 1 }), "start_x": ("FLOAT", { "default": 0.1, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.2, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 0.9, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 0.8, "max": 1.0, "step": 0.01 }), "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 }), "outline_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "fill_red": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_green": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_blue": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming, PyUnresolvedReferences def node( self, width, height, start_x, start_y, end_x, end_y, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, SSAA, method ): canvas = Image.new("RGBA", (width * SSAA, height * SSAA), (0, 0, 0, 0)) draw = ImageDraw.Draw(canvas) draw.rectangle( ( (width * start_x * SSAA, height * start_y * SSAA), (width * end_x * SSAA, height * end_y * SSAA) ), (fill_red, fill_green, fill_blue, int(fill_alpha * 255)), (outline_red, outline_green, outline_blue, int(outline_alpha * 255)), outline_size * SSAA ) canvas = canvas.resize((width, height), get_sampler_by_name(method)) return (canvas.image_to_tensor().unsqueeze(0),) class ImageDrawRectangleByContainer: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "container": ("IMAGE",), "start_x": ("FLOAT", { "default": 0.1, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.2, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 0.9, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 0.8, "max": 1.0, "step": 0.01 }), "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 }), "outline_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "fill_red": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_green": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_blue": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming def node( self, container, start_x, start_y, end_x, end_y, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, SSAA, method ): return ImageDrawRectangle().node( container[0, :, :, 0].shape[1], container[0, :, :, 0].shape[0], start_x, start_y, end_x, end_y, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, SSAA, method ) class ImageDrawRectangleRounded: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "width": ("INT", { "default": 256, "min": 1, "step": 1 }), "height": ("INT", { "default": 256, "min": 1, "step": 1 }), "start_x": ("FLOAT", { "default": 0.1, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.2, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 0.9, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 0.8, "max": 1.0, "step": 0.01 }), "radius": ("INT", { "default": 180, "max": 360, "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 }), "outline_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "fill_red": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_green": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_blue": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "top_left_corner": (["true", "false"],), "top_right_corner": (["true", "false"],), "bottom_right_corner": (["true", "false"],), "bottom_left_corner": (["true", "false"],), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming, PyUnresolvedReferences, PyArgumentList def node( self, width, height, start_x, start_y, end_x, end_y, radius, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, top_left_corner, top_right_corner, bottom_right_corner, bottom_left_corner, SSAA, method ): canvas = Image.new("RGBA", (width * SSAA, height * SSAA), (0, 0, 0, 0)) draw = ImageDraw.Draw(canvas) draw.rounded_rectangle( ( (width * start_x * SSAA, height * start_y * SSAA), (width * end_x * SSAA, height * end_y * SSAA) ), radius * SSAA, (fill_red, fill_green, fill_blue, int(fill_alpha * 255)), (outline_red, outline_green, outline_blue, int(outline_alpha * 255)), outline_size * SSAA, corners=( True if top_left_corner == "true" else False, True if top_right_corner == "true" else False, True if bottom_right_corner == "true" else False, True if bottom_left_corner == "true" else False ) ) canvas = canvas.resize((width, height), get_sampler_by_name(method)) return (canvas.image_to_tensor().unsqueeze(0),) class ImageDrawRectangleRoundedByContainer: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "container": ("IMAGE",), "start_x": ("FLOAT", { "default": 0.1, "max": 1.0, "step": 0.01 }), "start_y": ("FLOAT", { "default": 0.2, "max": 1.0, "step": 0.01 }), "end_x": ("FLOAT", { "default": 0.9, "max": 1.0, "step": 0.01 }), "end_y": ("FLOAT", { "default": 0.8, "max": 1.0, "step": 0.01 }), "radius": ("INT", { "default": 180, "max": 360, "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 }), "outline_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "fill_red": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_green": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_blue": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "top_left_corner": (["true", "false"],), "top_right_corner": (["true", "false"],), "bottom_right_corner": (["true", "false"],), "bottom_left_corner": (["true", "false"],), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming, PyUnresolvedReferences, PyArgumentList def node( self, container, start_x, start_y, end_x, end_y, radius, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, top_left_corner, top_right_corner, bottom_right_corner, bottom_left_corner, SSAA, method ): return ImageDrawRectangleRounded().image_draw_rounded( container[0, :, :, 0].shape[1], container[0, :, :, 0].shape[0], start_x, start_y, end_x, end_y, radius, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, top_left_corner, top_right_corner, bottom_right_corner, bottom_left_corner, SSAA, method ) class ImageDrawPolygon: def __init__(self): pass @classmethod def INPUT_TYPES(cls): return { "required": { "size": ("INT", { "default": 256, "min": 1, "step": 1 }), "sides": ("INT", { "default": 5, "min": 3, "step": 1 }), "rotation": ("INT", { "default": 0, "max": 360, "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 }), "outline_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "fill_red": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_green": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_blue": ("INT", { "default": 255, "max": 255, "step": 1 }), "fill_alpha": ("FLOAT", { "default": 1.0, "max": 1.0, "step": 0.01 }), "SSAA": ("INT", { "default": 4, "min": 1, "max": 16, "step": 1 }), "method": (["lanczos", "bicubic", "hamming", "bilinear", "box", "nearest"],), }, } RETURN_TYPES = ("IMAGE",) FUNCTION = "node" CATEGORY = "image/draw" # noinspection PyPep8Naming, PyUnresolvedReferences def node( self, size, sides, rotation, outline_size, outline_red, outline_green, outline_blue, outline_alpha, fill_red, fill_green, fill_blue, fill_alpha, SSAA, method ): canvas = Image.new("RGBA", (size * SSAA, size * SSAA), (0, 0, 0, 0)) draw = ImageDraw.Draw(canvas) draw.regular_polygon( (size * SSAA / 2, size * SSAA / 2, size * SSAA / 2), sides, rotation, (fill_red, fill_green, fill_blue, int(fill_alpha * 255)), (outline_red, outline_green, outline_blue, int(outline_alpha * 255)), # TODO: Uncomment after the release of PIL 9.6.0 # outline_size * SSAA ) canvas = canvas.resize((size, size), get_sampler_by_name(method)) return (canvas.image_to_tensor().unsqueeze(0),) NODE_CLASS_MAPPINGS = { "ImageDrawArc": ImageDrawArc, "ImageDrawArcByContainer": ImageDrawArcByContainer, "ImageDrawChord": ImageDrawChord, "ImageDrawChordByContainer": ImageDrawChordByContainer, "ImageDrawEllipse": ImageDrawEllipse, "ImageDrawEllipseByContainer": ImageDrawEllipseByContainer, "ImageDrawLine": ImageDrawLine, "ImageDrawLineByContainer": ImageDrawLineByContainer, "ImageDrawPieslice": ImageDrawPieslice, "ImageDrawPiesliceByContainer": ImageDrawPiesliceByContainer, "ImageDrawRectangle": ImageDrawRectangle, "ImageDrawRectangleByContainer": ImageDrawRectangleByContainer, "ImageDrawRectangleRounded": ImageDrawRectangleRounded, "ImageDrawRectangleRoundedByContainer": ImageDrawRectangleRoundedByContainer, "ImageDrawPolygon": ImageDrawPolygon, }