diff --git a/README.md b/README.md index ca12725..b6734f1 100644 --- a/README.md +++ b/README.md @@ -9,36 +9,36 @@ based on the work by [Aitrepreneur](https://huggingface.co/Aitrepreneur) found h The **Flux Prompt Generator** utilizes a collection of JSON data files containing various categories of descriptive terms. These categories include: -- **Artform:** Photography, Digital Art, etc. -- **Photo Type:** Portrait, Landscape, etc. -- **Body Types:** Muscular, Thin, etc. -- **Default Tags:** Man, Woman, Child, etc. -- **Roles:** Knight, Wizard, etc. -- **Hairstyles:** Long, Short, Braided, etc. +- **Accessories:** Glasses, Hats, Jewelry, etc. - **Additional Details:** Clothing, Accessories, etc. -- **Photography Styles:** Cinematic, Realistic, etc. -- **Device:** Camera models, etc. -- **Photographer:** Famous photographers, etc. +- **Age Group:** Child, Teenager, Adult, etc. +- **Artform:** Photography, Digital Art, etc. - **Artist:** Famous artists, etc. -- **Digital Artform:** Pixel Art, 3D Render, etc. -- **Place:** Forest, City, etc. -- **Lighting:** Soft, Harsh, etc. +- **Background:** Plain, Detailed, etc. +- **Body Markings:** Birthmarks, Moles, Freckles, etc. +- **Body Types:** Muscular, Thin, etc. - **Clothing:** Dress, Suit, etc. - **Composition:** Rule of Thirds, Golden Ratio, etc. -- **Pose:** Standing, Sitting, etc. -- **Background:** Plain, Detailed, etc. -- **Face Features:** Sharp Jawline, High Cheekbones, etc. -- **Eye Colors:** Blue, Green, Brown, etc. -- **Facial Hair:** Beard, Mustache, etc. -- **Skin Tone:** Pale, Dark, etc. -- **Age Group:** Child, Teenager, Adult, etc. +- **Default Tags:** Man, Woman, Child, etc. +- **Device:** Camera models, etc. +- **Digital Artform:** Pixel Art, 3D Render, etc. - **Ethnicity:** Various ethnicities and cultural backgrounds. -- **Accessories:** Glasses, Hats, Jewelry, etc. - **Expression:** Smile, Frown, Surprise, etc. -- **Tattoos & Scars:** Detailed descriptions of body modifications. -- **Makeup Styles:** Natural, Glamorous, etc. +- **Eye Colors:** Blue, Green, Brown, etc. +- **Face Features:** Sharp Jawline, High Cheekbones, etc. +- **Facial Hair:** Beard, Mustache, etc. - **Hair Color:** Blonde, Brown, Black, etc. -- **Body Markings:** Birthmarks, Moles, Freckles, etc. +- **Hairstyles:** Long, Short, Braided, etc. +- **Lighting:** Soft, Harsh, etc. +- **Makeup Styles:** Natural, Glamorous, etc. +- **Photo Type:** Portrait, Landscape, etc. +- **Photographer:** Famous photographers, etc. +- **Photography Styles:** Cinematic, Realistic, etc. +- **Place:** Forest, City, etc. +- **Pose:** Standing, Sitting, etc. +- **Roles:** Knight, Wizard, etc. +- **Skin Tone:** Pale, Dark, etc. +- **Tattoos & Scars:** Detailed descriptions of body modifications. ![Flux Prompt Generator](https://i.imgur.com/0TNizfp.png "Displaying node") @@ -48,6 +48,7 @@ The node allows you to select specific terms or choose "random" to let the gener 1. **cd** to the custom_nodes folder inside of **ComfyUI** directory 2. **cmd** in the address bar, then use this command: + ``` git clone https://github.com/fairy-root/Flux-Prompt-Generator.git ``` @@ -56,11 +57,12 @@ git clone https://github.com/fairy-root/Flux-Prompt-Generator.git 1. **Add the "Flux Prompt Generator" node to your ComfyUI workflow.** 2. **Configure the desired parameters:** - - **Seed:** Controls the randomness of the generator. - - **Custom:** Add any custom text to the prompt. - - **Subject:** Specify the main subject of the image. - - **Artform:** Choose the desired art form (Photography, Digital Art, etc.). - - **... (All other parameters as described in the Overview section)** + + - **Seed:** Controls the randomness of the generator. + - **Custom:** Add any custom text to the prompt. + - **Subject:** Specify the main subject of the image. + - **Artform:** Choose the desired art form (Photography, Digital Art, etc.). + - **... (All other parameters as described in the Overview section)** 3. **Connect the output of the node to a text-to-image model (like Flux or Stable Diffusion...etc) to generate images based on the generated prompt.** @@ -97,4 +99,4 @@ This project is licensed under the MIT License. See the [LICENSE](LICENSE) file ## Contributing -Contributions are welcome! Please open an issue or submit a pull request for any improvements or features. \ No newline at end of file +Contributions are welcome! Please open an issue or submit a pull request for any improvements or features. diff --git a/flux_prompt_generator.py b/flux_prompt_generator.py index e36d4fc..2ad97ec 100644 --- a/flux_prompt_generator.py +++ b/flux_prompt_generator.py @@ -5,6 +5,7 @@ import json import os import re + def install_and_import(package): try: __import__(package) @@ -14,50 +15,53 @@ def install_and_import(package): finally: globals()[package] = __import__(package) + # Load JSON files def load_json_file(file_name): file_path = os.path.join(os.path.dirname(__file__), "data", file_name) with open(file_path, "r") as file: data = json.load(file) - + # Ensure data is a list (if your JSON structure is a list) if isinstance(data, list): # Remove duplicates by converting to a set and back to a list data = list({json.dumps(item, sort_keys=True) for item in data}) data = [json.loads(item) for item in data] - + return data + ARTFORM = load_json_file("artform.json") -PHOTO_TYPE = load_json_file("photo_type.json") -BODY_TYPES = load_json_file("body_types.json") -DEFAULT_TAGS = load_json_file("default_tags.json") -ROLES = load_json_file("roles.json") -HAIRSTYLES = load_json_file("hairstyles.json") +ACCESSORIES = load_json_file("accessories.json") ADDITIONAL_DETAILS = load_json_file("additional_details.json") -PHOTOGRAPHY_STYLES = load_json_file("photography_styles.json") -DEVICE = load_json_file("device.json") -PHOTOGRAPHER = load_json_file("photographer.json") +AGE_GROUP = load_json_file("age_group.json") ARTIST = load_json_file("artist.json") -DIGITAL_ARTFORM = load_json_file("digital_artform.json") -PLACE = load_json_file("place.json") -LIGHTING = load_json_file("lighting.json") +BACKGROUND = load_json_file("background.json") +BODY_MARKINGS = load_json_file("body_markings.json") +BODY_TYPES = load_json_file("body_types.json") CLOTHING = load_json_file("clothing.json") COMPOSITION = load_json_file("composition.json") -POSE = load_json_file("pose.json") -BACKGROUND = load_json_file("background.json") -FACE_FEATURES = load_json_file("face_features.json") -EYE_COLORS = load_json_file("eye_colors.json") -FACIAL_HAIR = load_json_file("facial_hair.json") -SKIN_TONE = load_json_file("skin_tone.json") -AGE_GROUP = load_json_file("age_group.json") +DEFAULT_TAGS = load_json_file("default_tags.json") +DEVICE = load_json_file("device.json") +DIGITAL_ARTFORM = load_json_file("digital_artform.json") ETHNICITY = load_json_file("ethnicity.json") -ACCESSORIES = load_json_file("accessories.json") EXPRESSION = load_json_file("expression.json") -TATTOOS_SCARS = load_json_file("tattoos_scars.json") -MAKEUP_STYLES = load_json_file("makeup_styles.json") +EYE_COLORS = load_json_file("eye_colors.json") +FACE_FEATURES = load_json_file("face_features.json") +FACIAL_HAIR = load_json_file("facial_hair.json") HAIR_COLOR = load_json_file("hair_color.json") -BODY_MARKINGS = load_json_file("body_markings.json") +HAIRSTYLES = load_json_file("hairstyles.json") +LIGHTING = load_json_file("lighting.json") +MAKEUP_STYLES = load_json_file("makeup_styles.json") +PHOTO_TYPE = load_json_file("photo_type.json") +PHOTOGRAPHER = load_json_file("photographer.json") +PHOTOGRAPHY_STYLES = load_json_file("photography_styles.json") +PLACE = load_json_file("place.json") +POSE = load_json_file("pose.json") +ROLES = load_json_file("roles.json") +SKIN_TONE = load_json_file("skin_tone.json") +TATTOOS_SCARS = load_json_file("tattoos_scars.json") + class PromptGenerator: def __init__(self, seed=None): @@ -78,43 +82,55 @@ class PromptGenerator: return input_str def clean_consecutive_commas(self, input_string): - cleaned_string = re.sub(r',\s*,', ',', input_string) + cleaned_string = re.sub(r",\s*,", ",", input_string) return cleaned_string def process_string(self, replaced, seed): - replaced = re.sub(r'\s*,\s*', ',', replaced) - replaced = re.sub(r',+', ',', replaced) + replaced = re.sub(r"\s*,\s*", ",", replaced) + replaced = re.sub(r",+", ",", replaced) original = replaced - + first_break_clipl_index = replaced.find("BREAK_CLIPL") - second_break_clipl_index = replaced.find("BREAK_CLIPL", first_break_clipl_index + len("BREAK_CLIPL")) - + second_break_clipl_index = replaced.find( + "BREAK_CLIPL", first_break_clipl_index + len("BREAK_CLIPL") + ) + if first_break_clipl_index != -1 and second_break_clipl_index != -1: - clip_content_l = replaced[first_break_clipl_index + len("BREAK_CLIPL"):second_break_clipl_index] - replaced = replaced[:first_break_clipl_index].strip(", ") + replaced[second_break_clipl_index + len("BREAK_CLIPL"):].strip(", ") + clip_content_l = replaced[ + first_break_clipl_index + len("BREAK_CLIPL") : second_break_clipl_index + ] + replaced = replaced[:first_break_clipl_index].strip(", ") + replaced[ + second_break_clipl_index + len("BREAK_CLIPL") : + ].strip(", ") clip_l = clip_content_l else: clip_l = "" - + first_break_clipg_index = replaced.find("BREAK_CLIPG") - second_break_clipg_index = replaced.find("BREAK_CLIPG", first_break_clipg_index + len("BREAK_CLIPG")) - + second_break_clipg_index = replaced.find( + "BREAK_CLIPG", first_break_clipg_index + len("BREAK_CLIPG") + ) + if first_break_clipg_index != -1 and second_break_clipg_index != -1: - clip_content_g = replaced[first_break_clipg_index + len("BREAK_CLIPG"):second_break_clipg_index] - replaced = replaced[:first_break_clipg_index].strip(", ") + replaced[second_break_clipg_index + len("BREAK_CLIPG"):].strip(", ") + clip_content_g = replaced[ + first_break_clipg_index + len("BREAK_CLIPG") : second_break_clipg_index + ] + replaced = replaced[:first_break_clipg_index].strip(", ") + replaced[ + second_break_clipg_index + len("BREAK_CLIPG") : + ].strip(", ") clip_g = clip_content_g else: clip_g = "" - + t5xxl = replaced - + original = original.replace("BREAK_CLIPL", "").replace("BREAK_CLIPG", "") - original = re.sub(r'\s*,\s*', ',', original) - original = re.sub(r',+', ',', original) - clip_l = re.sub(r'\s*,\s*', ',', clip_l) - clip_l = re.sub(r',+', ',', clip_l) - clip_g = re.sub(r'\s*,\s*', ',', clip_g) - clip_g = re.sub(r',+', ',', clip_g) + original = re.sub(r"\s*,\s*", ",", original) + original = re.sub(r",+", ",", original) + clip_l = re.sub(r"\s*,\s*", ",", clip_l) + clip_l = re.sub(r",+", ",", clip_l) + clip_g = re.sub(r"\s*,\s*", ",", clip_g) + clip_g = re.sub(r",+", ",", clip_g) if clip_l.startswith(","): clip_l = clip_l[1:] if clip_g.startswith(","): @@ -126,14 +142,45 @@ class PromptGenerator: return original, seed, t5xxl, clip_l, clip_g - - def generate_prompt(self, seed, custom, subject, artform, photo_type, body_types, default_tags, roles, hairstyles, - additional_details, photography_styles, device, photographer, artist, digital_artform, - place, lighting, clothing, composition, pose, background, face_features, eye_colors, facial_hair, - skin_tone, age_group, ethnicity, accessories, expression, tattoos_scars, makeup_styles, - hair_color, body_markings, *args): + def generate_prompt( + self, + seed, + custom, + subject, + artform, + photo_type, + body_types, + default_tags, + roles, + hairstyles, + additional_details, + photography_styles, + device, + photographer, + artist, + digital_artform, + place, + lighting, + clothing, + composition, + pose, + background, + face_features, + eye_colors, + facial_hair, + skin_tone, + age_group, + ethnicity, + accessories, + expression, + tattoos_scars, + makeup_styles, + hair_color, + body_markings, + *args, + ): kwargs = locals() - del kwargs['self'] + del kwargs["self"] seed = kwargs.get("seed", 0) if seed is not None: @@ -150,30 +197,46 @@ class PromptGenerator: subject = kwargs.get("subject", "") if is_photographer: - selected_photo_style = self.get_choice(kwargs.get("photography_styles", ""), PHOTOGRAPHY_STYLES) + selected_photo_style = self.get_choice( + kwargs.get("photography_styles", ""), PHOTOGRAPHY_STYLES + ) if not selected_photo_style: selected_photo_style = "photography" components.append(selected_photo_style) - if kwargs.get("photography_style", "") != "disabled" and kwargs.get("default_tags", "") != "disabled" or subject != "": + if ( + kwargs.get("photography_style", "") != "disabled" + and kwargs.get("default_tags", "") != "disabled" + or subject != "" + ): components.append(" of") - + default_tags = kwargs.get("default_tags", "random") body_type = kwargs.get("body_types", "") if not subject: if default_tags == "random": if body_type != "disabled" and body_type != "random": - selected_subject = self.get_choice(kwargs.get("default_tags", ""), DEFAULT_TAGS).replace("a ", "").replace("an ", "") + selected_subject = ( + self.get_choice(kwargs.get("default_tags", ""), DEFAULT_TAGS) + .replace("a ", "") + .replace("an ", "") + ) components.append("a ") components.append(body_type) components.append(selected_subject) elif body_type == "disabled": - selected_subject = self.get_choice(kwargs.get("default_tags", ""), DEFAULT_TAGS) + selected_subject = self.get_choice( + kwargs.get("default_tags", ""), DEFAULT_TAGS + ) components.append(selected_subject) else: body_type = self.get_choice(body_type, BODY_TYPES) components.append("a ") components.append(body_type) - selected_subject = self.get_choice(kwargs.get("default_tags", ""), DEFAULT_TAGS).replace("a ", "").replace("an ", "") + selected_subject = ( + self.get_choice(kwargs.get("default_tags", ""), DEFAULT_TAGS) + .replace("a ", "") + .replace("an ", "") + ) components.append(selected_subject) elif default_tags == "disabled": pass @@ -202,7 +265,10 @@ class PromptGenerator: if components[i] in PLACE: components[i] += "," break - if kwargs.get("clothing", "") != "disabled" and kwargs.get("clothing", "") != "random": + if ( + kwargs.get("clothing", "") != "disabled" + and kwargs.get("clothing", "") != "random" + ): components.append(", dressed in ") clothing = kwargs.get("clothing", "") components.append(clothing) @@ -211,15 +277,18 @@ class PromptGenerator: clothing = self.get_choice(kwargs.get("clothing", ""), CLOTHING) components.append(clothing) - if kwargs.get("composition", "") != "disabled" and kwargs.get("composition", "") != "random": + if ( + kwargs.get("composition", "") != "disabled" + and kwargs.get("composition", "") != "random" + ): components.append(",") composition = kwargs.get("composition", "") components.append(composition) - elif kwargs.get("composition", "") == "random": + elif kwargs.get("composition", "") == "random": components.append(",") composition = self.get_choice(kwargs.get("composition", ""), COMPOSITION) components.append(composition) - + if kwargs.get("pose", "") != "disabled" and kwargs.get("pose", "") != "random": components.append(",") pose = kwargs.get("pose", "") @@ -229,27 +298,35 @@ class PromptGenerator: pose = self.get_choice(kwargs.get("pose", ""), POSE) components.append(pose) components.append("BREAK_CLIPG") - if kwargs.get("background", "") != "disabled" and kwargs.get("background", "") != "random": + if ( + kwargs.get("background", "") != "disabled" + and kwargs.get("background", "") != "random" + ): components.append(",") background = kwargs.get("background", "") components.append(background) - elif kwargs.get("background", "") == "random": + elif kwargs.get("background", "") == "random": components.append(",") background = self.get_choice(kwargs.get("background", ""), BACKGROUND) components.append(background) - if kwargs.get("place", "") != "disabled" and kwargs.get("place", "") != "random": + if ( + kwargs.get("place", "") != "disabled" + and kwargs.get("place", "") != "random" + ): components.append(",") place = kwargs.get("place", "") components.append(place) - elif kwargs.get("place", "") == "random": + elif kwargs.get("place", "") == "random": components.append(",") place = self.get_choice(kwargs.get("place", ""), PLACE) components.append(place + ",") lighting = kwargs.get("lighting", "").lower() if lighting == "random": - selected_lighting = ", ".join(self.rng.sample(LIGHTING, self.rng.randint(2, 5))) + selected_lighting = ", ".join( + self.rng.sample(LIGHTING, self.rng.randint(2, 5)) + ) components.append(",") components.append(selected_lighting) elif lighting == "disabled": @@ -277,15 +354,25 @@ class PromptGenerator: # Conditional logic for facial_hair and makeup_styles if "man" in kwargs.get("default_tags", "").lower(): - components.append(self.get_choice(kwargs.get("facial_hair", ""), FACIAL_HAIR)) + components.append( + self.get_choice(kwargs.get("facial_hair", ""), FACIAL_HAIR) + ) if "woman" in kwargs.get("default_tags", "").lower(): - components.append(self.get_choice(kwargs.get("makeup_styles", ""), MAKEUP_STYLES)) + components.append( + self.get_choice(kwargs.get("makeup_styles", ""), MAKEUP_STYLES) + ) components.append("BREAK_CLIPL") if is_photographer: if kwargs.get("photo_type", "") != "disabled": - photo_type_choice = self.get_choice(kwargs.get("photo_type", ""), PHOTO_TYPE) - if photo_type_choice and photo_type_choice != "random" and photo_type_choice != "disabled": + photo_type_choice = self.get_choice( + kwargs.get("photo_type", ""), PHOTO_TYPE + ) + if ( + photo_type_choice + and photo_type_choice != "random" + and photo_type_choice != "disabled" + ): random_value = round(self.rng.uniform(1.1, 1.5), 1) components.append(f", ({photo_type_choice}:{random_value}), ") @@ -293,17 +380,26 @@ class PromptGenerator: ("device", DEVICE), ("photographer", PHOTOGRAPHER), ] - components.extend([self.get_choice(kwargs.get(param[0], ""), param[1]) for param in params]) + components.extend( + [ + self.get_choice(kwargs.get(param[0], ""), param[1]) + for param in params + ] + ) if kwargs.get("device", "") != "disabled": components[-2] = f", shot on {components[-2]}" if kwargs.get("photographer", "") != "disabled": components[-1] = f", photo by {components[-1]}" else: - digital_artform_choice = self.get_choice(kwargs.get("digital_artform", ""), DIGITAL_ARTFORM) + digital_artform_choice = self.get_choice( + kwargs.get("digital_artform", ""), DIGITAL_ARTFORM + ) if digital_artform_choice: components.append(f"{digital_artform_choice}") if kwargs.get("artist", "") != "disabled": - components.append(f"by {self.get_choice(kwargs.get('artist', ''), ARTIST)}") + components.append( + f"by {self.get_choice(kwargs.get('artist', ''), ARTIST)}" + ) components.append("BREAK_CLIPL") prompt = " ".join(components) @@ -319,39 +415,119 @@ class FluxPromptGenerator: def INPUT_TYPES(cls): return { "required": { - "seed": ("INT", {"default": random.randint(0, 30000), "min": 0, "max": 30000, "step": 1}), + "seed": ( + "INT", + { + "default": random.randint(0, 30000), + "min": 0, + "max": 30000, + "step": 1, + }, + ), "custom": ("STRING", {"multiline": True, "default": ""}), "subject": ("STRING", {"multiline": True, "default": ""}), + "accessories": ( + ["disabled", "random"] + ACCESSORIES, + {"default": "disabled"}, + ), + "additional_details": ( + ["disabled", "random"] + ADDITIONAL_DETAILS, + {"default": "disabled"}, + ), + "age_group": ( + ["disabled", "random"] + AGE_GROUP, + {"default": "disabled"}, + ), "artform": (["disabled", "random"] + ARTFORM, {"default": "disabled"}), - "photo_type": (["disabled", "random"] + PHOTO_TYPE, {"default": "disabled"}), - "body_types": (["disabled", "random"] + BODY_TYPES, {"default": "disabled"}), - "default_tags": (["disabled", "random"] + DEFAULT_TAGS, {"default": "disabled"}), - "roles": (["disabled", "random"] + ROLES, {"default": "disabled"}), - "hairstyles": (["disabled", "random"] + HAIRSTYLES, {"default": "disabled"}), - "additional_details": (["disabled", "random"] + ADDITIONAL_DETAILS, {"default": "disabled"}), - "photography_styles": (["disabled", "random"] + PHOTOGRAPHY_STYLES, {"default": "disabled"}), - "device": (["disabled", "random"] + DEVICE, {"default": "disabled"}), - "photographer": (["disabled", "random"] + PHOTOGRAPHER, {"default": "disabled"}), "artist": (["disabled", "random"] + ARTIST, {"default": "disabled"}), - "digital_artform": (["disabled", "random"] + DIGITAL_ARTFORM, {"default": "disabled"}), + "background": ( + ["disabled", "random"] + BACKGROUND, + {"default": "disabled"}, + ), + "body_markings": ( + ["disabled", "random"] + BODY_MARKINGS, + {"default": "disabled"}, + ), + "body_types": ( + ["disabled", "random"] + BODY_TYPES, + {"default": "disabled"}, + ), + "clothing": ( + ["disabled", "random"] + CLOTHING, + {"default": "disabled"}, + ), + "composition": ( + ["disabled", "random"] + COMPOSITION, + {"default": "disabled"}, + ), + "default_tags": ( + ["disabled", "random"] + DEFAULT_TAGS, + {"default": "disabled"}, + ), + "device": (["disabled", "random"] + DEVICE, {"default": "disabled"}), + "digital_artform": ( + ["disabled", "random"] + DIGITAL_ARTFORM, + {"default": "disabled"}, + ), + "ethnicity": ( + ["disabled", "random"] + ETHNICITY, + {"default": "disabled"}, + ), + "expression": ( + ["disabled", "random"] + EXPRESSION, + {"default": "disabled"}, + ), + "eye_colors": ( + ["disabled", "random"] + EYE_COLORS, + {"default": "disabled"}, + ), + "face_features": ( + ["disabled", "random"] + FACE_FEATURES, + {"default": "disabled"}, + ), + "facial_hair": ( + ["disabled", "random"] + FACIAL_HAIR, + {"default": "disabled"}, + ), + "hair_color": ( + ["disabled", "random"] + HAIR_COLOR, + {"default": "disabled"}, + ), + "hairstyles": ( + ["disabled", "random"] + HAIRSTYLES, + {"default": "disabled"}, + ), + "lighting": ( + ["disabled", "random"] + LIGHTING, + {"default": "disabled"}, + ), + "makeup_styles": ( + ["disabled", "random"] + MAKEUP_STYLES, + {"default": "disabled"}, + ), + "photo_type": ( + ["disabled", "random"] + PHOTO_TYPE, + {"default": "disabled"}, + ), + "photographer": ( + ["disabled", "random"] + PHOTOGRAPHER, + {"default": "disabled"}, + ), + "photography_styles": ( + ["disabled", "random"] + PHOTOGRAPHY_STYLES, + {"default": "disabled"}, + ), "place": (["disabled", "random"] + PLACE, {"default": "disabled"}), - "lighting": (["disabled", "random"] + LIGHTING, {"default": "disabled"}), - "clothing": (["disabled", "random"] + CLOTHING, {"default": "disabled"}), - "composition": (["disabled", "random"] + COMPOSITION, {"default": "disabled"}), "pose": (["disabled", "random"] + POSE, {"default": "disabled"}), - "background": (["disabled", "random"] + BACKGROUND, {"default": "disabled"}), - "face_features": (["disabled", "random"] + FACE_FEATURES, {"default": "disabled"}), - "eye_colors": (["disabled", "random"] + EYE_COLORS, {"default": "disabled"}), - "facial_hair": (["disabled", "random"] + FACIAL_HAIR, {"default": "disabled"}), - "skin_tone": (["disabled", "random"] + SKIN_TONE, {"default": "disabled"}), - "age_group": (["disabled", "random"] + AGE_GROUP, {"default": "disabled"}), - "ethnicity": (["disabled", "random"] + ETHNICITY, {"default": "disabled"}), - "accessories": (["disabled", "random"] + ACCESSORIES, {"default": "disabled"}), - "expression": (["disabled", "random"] + EXPRESSION, {"default": "disabled"}), - "tattoos_scars": (["disabled", "random"] + TATTOOS_SCARS, {"default": "disabled"}), - "makeup_styles": (["disabled", "random"] + MAKEUP_STYLES, {"default": "disabled"}), - "hair_color": (["disabled", "random"] + HAIR_COLOR, {"default": "disabled"}), - "body_markings": (["disabled", "random"] + BODY_MARKINGS, {"default": "disabled"}), + "roles": (["disabled", "random"] + ROLES, {"default": "disabled"}), + "skin_tone": ( + ["disabled", "random"] + SKIN_TONE, + {"default": "disabled"}, + ), + "tattoos_scars": ( + ["disabled", "random"] + TATTOOS_SCARS, + {"default": "disabled"}, + ), }, } @@ -359,13 +535,79 @@ class FluxPromptGenerator: FUNCTION = "execute" CATEGORY = "Prompt" - def execute(self, seed, custom, subject, artform, photo_type, body_types, default_tags, roles, hairstyles, additional_details, photography_styles, device, photographer, artist, digital_artform, place, lighting, clothing, composition, pose, background, face_features, eye_colors, facial_hair, skin_tone, age_group, ethnicity, accessories, expression, tattoos_scars, makeup_styles, hair_color, body_markings): + def execute( + self, + seed, + custom, + subject, + artform, + photo_type, + body_types, + default_tags, + roles, + hairstyles, + additional_details, + photography_styles, + device, + photographer, + artist, + digital_artform, + place, + lighting, + clothing, + composition, + pose, + background, + face_features, + eye_colors, + facial_hair, + skin_tone, + age_group, + ethnicity, + accessories, + expression, + tattoos_scars, + makeup_styles, + hair_color, + body_markings, + ): prompt_generator = PromptGenerator(seed) - prompt, seed, t5xxl_output, clip_l_output, clip_g_output = prompt_generator.generate_prompt( - seed, custom, subject, artform, photo_type, body_types, default_tags, roles, hairstyles, additional_details, - photography_styles, device, photographer, artist, digital_artform, place, lighting, clothing, composition, - pose, background, face_features, eye_colors, facial_hair, skin_tone, age_group, ethnicity, accessories, - expression, tattoos_scars, makeup_styles, hair_color, body_markings + prompt, seed, t5xxl_output, clip_l_output, clip_g_output = ( + prompt_generator.generate_prompt( + seed, + custom, + subject, + artform, + photo_type, + body_types, + default_tags, + roles, + hairstyles, + additional_details, + photography_styles, + device, + photographer, + artist, + digital_artform, + place, + lighting, + clothing, + composition, + pose, + background, + face_features, + eye_colors, + facial_hair, + skin_tone, + age_group, + ethnicity, + accessories, + expression, + tattoos_scars, + makeup_styles, + hair_color, + body_markings, + ) ) return (prompt, seed, t5xxl_output, clip_l_output, clip_g_output) @@ -373,11 +615,8 @@ class FluxPromptGenerator: def IS_CHANGED(cls, *args): return True -# Node export details -NODE_CLASS_MAPPINGS = { - "FluxPromptGenerator": FluxPromptGenerator -} -NODE_DISPLAY_NAME_MAPPINGS = { - "FluxPromptGenerator": "Flux Prompt Generator" -} \ No newline at end of file +# Node export details +NODE_CLASS_MAPPINGS = {"FluxPromptGenerator": FluxPromptGenerator} + +NODE_DISPLAY_NAME_MAPPINGS = {"FluxPromptGenerator": "Flux Prompt Generator"} diff --git a/pyproject.toml b/pyproject.toml index 2940dfe..7982b5a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,7 +1,7 @@ [project] name = "flux-prompt-generator" description = "A flexible and customizable prompt generator for generating detailed and creative prompts for image generation models for ComfyUI" -version = "1.0.1" +version = "1.0.2" license = {file = "LICENSE"} [project.urls]