Skip to content

Commit

Permalink
Multiline Text and Draw Shape
Browse files Browse the repository at this point in the history
  • Loading branch information
Suzie1 committed Dec 24, 2023
1 parent db3c36c commit 109715e
Show file tree
Hide file tree
Showing 8 changed files with 1,937 additions and 23 deletions.
27 changes: 16 additions & 11 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,25 @@
"""

from .live_node_mappings import LIVE_NODE_CLASS_MAPPINGS, LIVE_NODE_DISPLAY_NAME_MAPPINGS
NODE_CLASS_MAPPINGS = LIVE_NODE_CLASS_MAPPINGS
NODE_DISPLAY_NAME_MAPPINGS = LIVE_NODE_DISPLAY_NAME_MAPPINGS
print("-----------------------------------------------")
print("\033[34mComfyroll Custom Nodes v1.47 : \033[92m 148 Nodes Loaded\033[0m")
print("-----------------------------------------------")

INCLUDE_DEV_NODES = False

from .dev_node_mappings import DEV_NODE_CLASS_MAPPINGS, DEV_NODE_DISPLAY_NAME_MAPPINGS
if INCLUDE_DEV_NODES:
NODE_CLASS_MAPPINGS = {**DEV_NODE_CLASS_MAPPINGS, **LIVE_NODE_CLASS_MAPPINGS}
NODE_DISPLAY_NAME_MAPPINGS = {**DEV_NODE_DISPLAY_NAME_MAPPINGS, **LIVE_NODE_DISPLAY_NAME_MAPPINGS}
print("\033[92mComfyroll Dev Nodes Loaded\033[0m")
print("-----------------------------------------------")
try:
if INCLUDE_DEV_NODES:
from .dev_node_mappings import DEV_NODE_CLASS_MAPPINGS, DEV_NODE_DISPLAY_NAME_MAPPINGS
NODE_CLASS_MAPPINGS = {**DEV_NODE_CLASS_MAPPINGS, **LIVE_NODE_CLASS_MAPPINGS}
NODE_DISPLAY_NAME_MAPPINGS = {**DEV_NODE_DISPLAY_NAME_MAPPINGS, **LIVE_NODE_DISPLAY_NAME_MAPPINGS}
print("\033[34mComfyroll Custom Nodes: \033[92mDev Nodes Loaded\033[0m")
else:
NODE_CLASS_MAPPINGS = LIVE_NODE_CLASS_MAPPINGS
NODE_DISPLAY_NAME_MAPPINGS = LIVE_NODE_DISPLAY_NAME_MAPPINGS
except ImportError:
NODE_CLASS_MAPPINGS = LIVE_NODE_CLASS_MAPPINGS
NODE_DISPLAY_NAME_MAPPINGS = LIVE_NODE_DISPLAY_NAME_MAPPINGS

print("-----------------------------------------------")
print("\033[34mComfyroll Custom Nodes v1.47 : \033[92m 148 Nodes Loaded\033[0m")
print("-----------------------------------------------")

import shutil
import folder_paths
Expand Down
17 changes: 10 additions & 7 deletions live_node_mappings.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,20 @@
"CR Integer Multiple": CR_IntegerMultipleOf,
"CR Latent Batch Size": CR_LatentBatchSize,
"CR Seed": CR_Seed,
"CR Prompt Text":CR_PromptText,
"CR Split String":CR_SplitString,
"CR Prompt Text": CR_PromptText,
"CR Split String": CR_SplitString,
"CR Value": CR_Value,
"CR Conditioning Mixer":CR_ConditioningMixer,
"CR Conditioning Mixer": CR_ConditioningMixer,
"CR Select Model": CR_SelectModel,
"CR Multiline Text": CR_MultilineText,
### List Nodes
"CR Font File List": CR_FontFileList,
"CR Text List": CR_TextList,
"CR Load Image List": CR_LoadImageList,
"CR Load Image List Plus": CR_LoadImageListPlus,
### Aspect Ratio Nodes
"CR SD1.5 Aspect Ratio":CR_AspectRatioSD15,
"CR SDXL Aspect Ratio":CR_SDXLAspectRatio,
"CR SD1.5 Aspect Ratio": CR_AspectRatioSD15,
"CR SDXL Aspect Ratio": CR_SDXLAspectRatio,
"CR Aspect Ratio": CR_AspectRatio,
"CR Aspect Ratio Banners": CR_AspectRatioBanners,
### Legacy Nodes
Expand Down Expand Up @@ -101,6 +102,7 @@
"CR Starburst Colors": CR_StarburstColors,
"CR Simple Binary Pattern": CR_BinaryPatternSimple,
"CR Binary Pattern": CR_BinaryPattern,
"CR Draw Shape": CR_DrawShape,
### Graphics Text
"CR Overlay Text": CR_OverlayText,
"CR Draw Text": CR_DrawText,
Expand Down Expand Up @@ -230,6 +232,7 @@
"CR Value": "⚙️ CR Value",
"CR Conditioning Mixer": "⚙️ CR Conditioning Mixer",
"CR Select Model": "🔮 CR Select Model",
"CR Multiline Text": "⚙️ CR Multiline Text",
### List Nodes
"CR Font File List": "📜 CR Font File List",
"CR Text List": "📜 CR Text List",
Expand Down Expand Up @@ -288,17 +291,17 @@
"CR Color Gradient": "🟨 CR Color Gradient",
"CR Radial Gradient": "🟨 CR Radial Gradient",
"CR Starburst Lines": "🟧 CR Starburst Lines",
"CR Starburst Colors": "🟥 CR Starburst Colors",
"CR Starburst Colors": "🟧 CR Starburst Colors",
"CR Simple Binary Pattern": "🟥 CR Simple Binary Pattern",
"CR Binary Pattern": "🟥 CR Binary Pattern",
"CR Draw Shape": "🟥 CR Draw Shape",
### Graphics Text
"CR Overlay Text": "🔤 CR Overlay Text",
"CR Draw Text": "🔤️ CR Draw Text",
"CR Mask Text": "🔤️ CR Mask Text",
"CR Composite Text": "🔤️ CR Composite Text",
#"CR Arabic Text RTL": "🔤️ CR Arabic Text RTL",
"CR Simple Text Watermark": "🔤️ CR Simple Text Watermark",
"CR Font File List": "🔤️ CR Font File List",
### Graphics Filter
"CR Halftone Filter": "🎨 Halftone Filter",
"CR Color Tint": "🎨 CR Color Tint",
Expand Down
79 changes: 77 additions & 2 deletions nodes/nodes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import os
import sys
import io
import csv
import comfy.sd
import json
import folder_paths
Expand Down Expand Up @@ -396,7 +397,80 @@ def select_model(self, ckpt_name1, ckpt_name2, ckpt_name3, ckpt_name4, ckpt_name
show_help = "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes/wiki/Other-Nodes#cr-select-model"

return (model, clip, vae, model_name, show_help, )


#---------------------------------------------------------------------------------------------------------------------#
# based on WAS Text Multiline node
class CR_MultilineText:

def __init__(self):
pass

@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"text": ("STRING", {"default": '', "multiline": True}),
"convert_from_csv": ("BOOLEAN", {"default": False}),
"csv_quote_char": ("STRING", {"default": "'", "choices": ["'", '"']}),
"remove_chars": ("BOOLEAN", {"default": False}),
"chars_to_remove": ("STRING", {"multiline": False, "default": ""}),
"split_string": ("BOOLEAN", {"default": False}),
}
}

RETURN_TYPES = ("STRING", "STRING", )
RETURN_NAMES = ("multiline_text", "show_help", )
FUNCTION = "text_multiline"
CATEGORY = icons.get("Comfyroll/Other")

def text_multiline(self, text, chars_to_remove, split_string=False, remove_chars=False, convert_from_csv=False, csv_quote_char="'"):

new_text = []

# Remove trailing commas
text = text.rstrip(',')

if convert_from_csv:
# Convert CSV to multiline text
csv_reader = csv.reader(io.StringIO(text), quotechar=csv_quote_char)
for row in csv_reader:
new_text.extend(row)
if split_string:
if text.startswith("'") and text.endswith("'"):
text = text[1:-1] # Remove outer single quotes
values = [value.strip() for value in text.split("', '")]
new_text.extend(values)
elif text.startswith('"') and text.endswith('"'):
text = text[1:-1] # Remove outer single quotes
values = [value.strip() for value in text.split('", "')]
new_text.extend(values)
elif ',' in text and text.count("'") % 2 == 0:
# Assume it's a list-like string and split accordingly
text = text.replace("'", '') # Remove single quotes
values = [value.strip() for value in text.split(",")]
new_text.extend(values)
elif ',' in text and text.count('"') % 2 == 0:
# Assume it's a list-like string and split accordingly
text = text.replace('"', '') # Remove single quotes
values = [value.strip() for value in text.split(",")]
new_text.extend(values)
if convert_from_csv == False and split_string == False:
# Process multiline text
for line in io.StringIO(text):
if not line.strip().startswith('#'):
if not line.strip().startswith("\n"):
line = line.replace("\n", '')
if remove_chars:
# Remove quotes from each line
line = line.replace(chars_to_remove, '')
new_text.append(line)

new_text = "\n".join(new_text)

show_help = "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes/wiki/Other-Nodes#cr-multiline-text"

return (new_text, show_help,)

#---------------------------------------------------------------------------------------------------------------------#
# MAPPINGS
#---------------------------------------------------------------------------------------------------------------------#
Expand All @@ -412,7 +486,8 @@ def select_model(self, ckpt_name1, ckpt_name2, ckpt_name3, ckpt_name4, ckpt_name
"CR Split String": CR_SplitString,
"CR Value": CR_Value,
"CR Conditioning Mixer": CR_ConditioningMixer,
"CR Select Model": CR_SelectModel,
"CR Select Model": CR_SelectModel,
"CR Multiline Text": CR_MultilineText,
}
'''

1 change: 0 additions & 1 deletion nodes/nodes_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import folder_paths
import re
import comfy.sd
import piexif
from PIL import Image
from pathlib import Path
from ..categories import icons
Expand Down
98 changes: 96 additions & 2 deletions nodes/pil_pattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,22 @@
import numpy as np
import torch
import random
import os
import os
import math
from PIL import Image, ImageDraw

from .graphics_functions import get_color_values
from .shapes import (
draw_circle, draw_oval, draw_diamond, draw_square,
draw_triangle, draw_hexagon, draw_octagon,
draw_half_circle, draw_quarter_circle, draw_starburst, draw_star
)
from ..categories import icons
from ..config import color_mapping, COLORS

def tensor2pil(image):
return Image.fromarray(np.clip(255. * image.cpu().numpy().squeeze(), 0, 255).astype(np.uint8))

def pil2tensor(image):
return torch.from_numpy(np.array(image).astype(np.float32) / 255.0).unsqueeze(0)

Expand Down Expand Up @@ -144,7 +154,90 @@ def draw_pattern(self, binary_pattern, width, height,

# Convert the PIL image back to a torch tensor
return (image_out, show_help, )


#---------------------------------------------------------------------------------------------------------------------#class CR_DrawShape:
class CR_DrawShape:

@classmethod
def INPUT_TYPES(s):

shapes = ["circle","oval","square","diamond","triangle","hexagon","octagon","half circle","quarter circle","starburst","star"]

return {"required": {
"width": ("INT", {"default": 512, "min": 64, "max": 4096}),
"height": ("INT", {"default": 512, "min": 64, "max": 4096}),
"shape": (shapes,),
"shape_color": (COLORS,),
"back_color": (COLORS,),
"x_offset": ("INT", {"default": 0, "min": -2048, "max": 2048}),
"y_offset": ("INT", {"default": 0, "min": -2048, "max": 2048}),
"zoom": ("FLOAT", {"default": 1.00, "min": 0.00, "max": 10.00, "step": 0.05}),
"rotation": ("FLOAT", {"default": 0.0, "min": 0.0, "max": 3600.0, "step": 0.1}),
},
"optional": {
"shape_color_hex": ("STRING", {"multiline": False, "default": "#000000"}),
"bg_color_hex": ("STRING", {"multiline": False, "default": "#000000"}),
}
}

RETURN_TYPES = ("IMAGE", "STRING", )
RETURN_NAMES = ("IMAGE", "show_help", )
FUNCTION = "make_shape"
CATEGORY = icons.get("Comfyroll/Graphics/Filter")

def make_shape(self, width, height, rotation,
shape, shape_color, back_color,
x_offset=0, y_offset=0, zoom=1.0,
shape_color_hex='#000000', bg_color_hex='#000000'):

bg_color = get_color_values(back_color, bg_color_hex, color_mapping)
shape_color = get_color_values(shape_color, shape_color_hex, color_mapping)

back_img = Image.new("RGB", (width, height), color=bg_color)
shape_img = Image.new("RGB", (width, height), color=shape_color)
shape_mask = Image.new('L', (width, height))
draw = ImageDraw.Draw(shape_mask)

center_x = width // 2 + x_offset
center_y = height // 2 + y_offset
size = min(width - x_offset, height - y_offset) * zoom
aspect_ratio = width / height

if shape == 'circle':
draw_circle(draw, center_x, center_y, size)
elif shape == 'oval':
draw_oval(draw, center_x, center_y, size, aspect_ratio)
elif shape == 'diamond':
draw_diamond(draw, center_x, center_y, size, aspect_ratio)
elif shape == 'square':
draw_square(draw, center_x, center_y, size)
elif shape == 'triangle':
draw_triangle(draw, center_x, center_y, size)
elif shape == 'hexagon':
draw_hexagon(draw, center_x, center_y, size)
elif shape == 'octagon':
draw_octagon(draw, center_x, center_y, size)
elif shape == 'half circle':
draw_half_circle(draw, center_x, center_y, size)
elif shape == 'quarter circle':
draw_quarter_circle(draw, center_x, center_y, size)
elif shape == 'starburst':
numrays = 16
draw_starburst(draw, center_x, center_y, size, numrays)
elif shape == 'star':
draw_star(draw, center_x, center_y, size)
else:
raise ValueError("Invalid shape.")

shape_mask = shape_mask.rotate(rotation, center=(center_x, center_y))

result_image = Image.composite(shape_img, back_img, shape_mask)

image_out = pil2tensor(result_image)

show_help = "https://github.com/Suzie1/ComfyUI_Comfyroll_CustomNodes/wiki/Layout-Nodes#cr-draw-shape"

return (image_out, show_help, )
#---------------------------------------------------------------------------------------------------------------------#
# MAPPINGS
#---------------------------------------------------------------------------------------------------------------------#
Expand All @@ -153,6 +246,7 @@ def draw_pattern(self, binary_pattern, width, height,
NODE_CLASS_MAPPINGS = {
"CR Simple Binary Pattern Simple": CR Binary Pattern Simple,
"CR Binary Pattern": CR_BinaryPattern,
"CR Draw Shape": CR_DrawShape,
}
'''

Loading

0 comments on commit 109715e

Please sign in to comment.