Upload 10 files
Browse files- Mile_High_Styler/.gitignore +1 -0
- Mile_High_Styler/LICENSE +21 -0
- Mile_High_Styler/README.md +64 -0
- Mile_High_Styler/__init__.py +3 -0
- Mile_High_Styler/__pycache__/__init__.cpython-310.pyc +0 -0
- Mile_High_Styler/__pycache__/mile_high_styler.cpython-310.pyc +0 -0
- Mile_High_Styler/__pycache__/sdxl_prompt_styler.cpython-310.pyc +0 -0
- Mile_High_Styler/examples/sdxl_prompt_styler.png +0 -0
- Mile_High_Styler/mile_high_styler.py +116 -0
- Mile_High_Styler/mile_high_styles.json +0 -0
Mile_High_Styler/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
__pycache__/
|
Mile_High_Styler/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
MIT License
|
| 2 |
+
|
| 3 |
+
Copyright (c) 2023 twri
|
| 4 |
+
|
| 5 |
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
| 6 |
+
of this software and associated documentation files (the "Software"), to deal
|
| 7 |
+
in the Software without restriction, including without limitation the rights
|
| 8 |
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
| 9 |
+
copies of the Software, and to permit persons to whom the Software is
|
| 10 |
+
furnished to do so, subject to the following conditions:
|
| 11 |
+
|
| 12 |
+
The above copyright notice and this permission notice shall be included in all
|
| 13 |
+
copies or substantial portions of the Software.
|
| 14 |
+
|
| 15 |
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
| 16 |
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
| 17 |
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
| 18 |
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
| 19 |
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
| 20 |
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
| 21 |
+
SOFTWARE.
|
Mile_High_Styler/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
SDXL Prompt Styler
|
| 2 |
+
=======
|
| 3 |
+
Custom node for ComfyUI
|
| 4 |
+
-----------
|
| 5 |
+

|
| 6 |
+
|
| 7 |
+
SDXL Prompt Styler is a node that enables you to style prompts based on predefined templates stored in a JSON file. The node specifically replaces a {prompt} placeholder in the 'prompt' field of each template with provided positive text.
|
| 8 |
+
|
| 9 |
+
The node also effectively manages negative prompts. If negative text is provided, the node combines this with the 'negative_prompt' field from the template. If no negative text is supplied, the system defaults to using the 'negative_prompt' from the JSON template. This flexibility enables the creation of a diverse and specific range of negative prompts.
|
| 10 |
+
|
| 11 |
+
### Usage Example with SDXL Prompt Styler
|
| 12 |
+
|
| 13 |
+
Template example from a JSON file:
|
| 14 |
+
|
| 15 |
+
```json
|
| 16 |
+
[
|
| 17 |
+
{
|
| 18 |
+
"name": "base",
|
| 19 |
+
"prompt": "{prompt}",
|
| 20 |
+
"negative_prompt": ""
|
| 21 |
+
},
|
| 22 |
+
{
|
| 23 |
+
"name": "enhance",
|
| 24 |
+
"prompt": "breathtaking {prompt} . award-winning, professional, highly detailed",
|
| 25 |
+
"negative_prompt": "ugly, deformed, noisy, blurry, distorted, grainy"
|
| 26 |
+
}
|
| 27 |
+
]
|
| 28 |
+
```
|
| 29 |
+
|
| 30 |
+
```python
|
| 31 |
+
style = "enhance"
|
| 32 |
+
positive_prompt = "a futuristic pop up tent in a forest"
|
| 33 |
+
negative_prompt = "dark"
|
| 34 |
+
```
|
| 35 |
+
|
| 36 |
+
This will generate the following styled prompts as outputs:
|
| 37 |
+
|
| 38 |
+
```
|
| 39 |
+
breathtaking a futuristic pop up tent in a forest . award-winning, professional, highly detailed
|
| 40 |
+
ugly, deformed, noisy, blurry, distorted, grainy, dark
|
| 41 |
+
```
|
| 42 |
+
|
| 43 |
+
### Installation
|
| 44 |
+
|
| 45 |
+
To install and use the SDXL Prompt Styler nodes, follow these steps:
|
| 46 |
+
|
| 47 |
+
1. Open a terminal or command line interface.
|
| 48 |
+
2. Navigate to the `ComfyUI/custom_nodes/` directory.
|
| 49 |
+
3. Run the following command:
|
| 50 |
+
```git clone https://github.com/twri/sdxl_prompt_styler.git```
|
| 51 |
+
4. Restart ComfyUI.
|
| 52 |
+
|
| 53 |
+
This command clones the SDXL Prompt Styler repository into your `ComfyUI/custom_nodes/` directory. You should now be able to access and use the nodes from this repository.
|
| 54 |
+
|
| 55 |
+
### Inputs
|
| 56 |
+
|
| 57 |
+
* **text_positive** - text for the positive base prompt G
|
| 58 |
+
* **text_negative** - text for the negative base prompt G
|
| 59 |
+
* **log_prompt** - print inputs and outputs to stdout
|
| 60 |
+
|
| 61 |
+
### Outputs
|
| 62 |
+
|
| 63 |
+
* **positive_prompt_text_g** - combined prompt with style for positive promt G
|
| 64 |
+
* **negative_prompt_text_g** - combined prompt with style for negative promt G
|
Mile_High_Styler/__init__.py
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from .mile_high_styler import NODE_CLASS_MAPPINGS, NODE_DISPLAY_NAME_MAPPINGS
|
| 2 |
+
|
| 3 |
+
__all__ = ['NODE_CLASS_MAPPINGS', 'NODE_DISPLAY_NAME_MAPPINGS']
|
Mile_High_Styler/__pycache__/__init__.cpython-310.pyc
ADDED
|
Binary file (362 Bytes). View file
|
|
|
Mile_High_Styler/__pycache__/mile_high_styler.cpython-310.pyc
ADDED
|
Binary file (2.97 kB). View file
|
|
|
Mile_High_Styler/__pycache__/sdxl_prompt_styler.cpython-310.pyc
ADDED
|
Binary file (2.97 kB). View file
|
|
|
Mile_High_Styler/examples/sdxl_prompt_styler.png
ADDED
|
Mile_High_Styler/mile_high_styler.py
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import json
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
def read_json_file(file_path):
|
| 5 |
+
try:
|
| 6 |
+
# Open file, load JSON content into python dictionary, and return it.
|
| 7 |
+
with open(file_path, 'r') as file:
|
| 8 |
+
json_data = json.load(file)
|
| 9 |
+
return json_data
|
| 10 |
+
except Exception as e:
|
| 11 |
+
print(f"An error occurred: {str(e)}")
|
| 12 |
+
|
| 13 |
+
|
| 14 |
+
def read_sdxl_styles(json_data):
|
| 15 |
+
# Check that data is a list
|
| 16 |
+
if not isinstance(json_data, list):
|
| 17 |
+
print("Error: input data must be a list")
|
| 18 |
+
return None
|
| 19 |
+
|
| 20 |
+
names = []
|
| 21 |
+
|
| 22 |
+
# Iterate over each item in the data list
|
| 23 |
+
for item in json_data:
|
| 24 |
+
# Check that the item is a dictionary
|
| 25 |
+
if isinstance(item, dict):
|
| 26 |
+
# Check that 'name' is a key in the dictionary
|
| 27 |
+
if 'name' in item:
|
| 28 |
+
# Append the value of 'name' to the names list
|
| 29 |
+
names.append(item['name'])
|
| 30 |
+
|
| 31 |
+
return names
|
| 32 |
+
|
| 33 |
+
def read_sdxl_templates_replace_and_combine(json_data, template_name, positive_prompt, negative_prompt):
|
| 34 |
+
try:
|
| 35 |
+
# Check if json_data is a list
|
| 36 |
+
if not isinstance(json_data, list):
|
| 37 |
+
raise ValueError("Invalid JSON data. Expected a list of templates.")
|
| 38 |
+
|
| 39 |
+
for template in json_data:
|
| 40 |
+
# Check if template contains 'name' and 'prompt' fields
|
| 41 |
+
if 'name' not in template or 'prompt' not in template:
|
| 42 |
+
raise ValueError("Invalid template. Missing 'name' or 'prompt' field.")
|
| 43 |
+
|
| 44 |
+
# Replace {prompt} in the matching template
|
| 45 |
+
if template['name'] == template_name:
|
| 46 |
+
positive_prompt = template['prompt'].replace('{prompt}', positive_prompt)
|
| 47 |
+
|
| 48 |
+
json_negative_prompt = template.get('negative_prompt', "")
|
| 49 |
+
if negative_prompt:
|
| 50 |
+
negative_prompt = f"{json_negative_prompt}, {negative_prompt}" if json_negative_prompt else negative_prompt
|
| 51 |
+
else:
|
| 52 |
+
negative_prompt = json_negative_prompt
|
| 53 |
+
|
| 54 |
+
return positive_prompt, negative_prompt
|
| 55 |
+
|
| 56 |
+
# If function hasn't returned yet, no matching template was found
|
| 57 |
+
raise ValueError(f"No template found with name '{template_name}'.")
|
| 58 |
+
|
| 59 |
+
except Exception as e:
|
| 60 |
+
print(f"An error occurred: {str(e)}")
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
class MileHighStyler:
|
| 64 |
+
|
| 65 |
+
def __init__(self):
|
| 66 |
+
pass
|
| 67 |
+
|
| 68 |
+
@classmethod
|
| 69 |
+
def INPUT_TYPES(self):
|
| 70 |
+
# Get current file's directory
|
| 71 |
+
p = os.path.dirname(os.path.realpath(__file__))
|
| 72 |
+
# Construct 'mile_high_styles.json' path
|
| 73 |
+
file_path = os.path.join(p, 'mile_high_styles.json')
|
| 74 |
+
|
| 75 |
+
# Read JSON from file
|
| 76 |
+
self.json_data = read_json_file(file_path)
|
| 77 |
+
# Retrieve styles from JSON data
|
| 78 |
+
styles = read_sdxl_styles(self.json_data)
|
| 79 |
+
|
| 80 |
+
return {
|
| 81 |
+
"required": {
|
| 82 |
+
"text_positive": ("STRING", {"default": "", "multiline": True}),
|
| 83 |
+
"text_negative": ("STRING", {"default": "", "multiline": True}),
|
| 84 |
+
"style": ((styles), ),
|
| 85 |
+
"log_prompt": (["No", "Yes"], {"default":"No"}),
|
| 86 |
+
},
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
RETURN_TYPES = ('STRING','STRING',)
|
| 90 |
+
RETURN_NAMES = ('positive_prompt_text_g','negative_prompt_text_g',)
|
| 91 |
+
FUNCTION = 'prompt_styler'
|
| 92 |
+
CATEGORY = 'utils'
|
| 93 |
+
|
| 94 |
+
def prompt_styler(self, text_positive, text_negative, style, log_prompt):
|
| 95 |
+
# Process and combine prompts in templates
|
| 96 |
+
positive_prompt, negative_prompt = read_sdxl_templates_replace_and_combine(self.json_data, style, text_positive, text_negative)
|
| 97 |
+
|
| 98 |
+
# If logging is enabled (log_prompt is set to "Yes"),
|
| 99 |
+
# print the style, positive and negative text, and positive and negative prompts to the console
|
| 100 |
+
if log_prompt == "Yes":
|
| 101 |
+
print(f"style: {style}")
|
| 102 |
+
print(f"text_positive: {text_positive}")
|
| 103 |
+
print(f"text_negative: {text_negative}")
|
| 104 |
+
print(f"positive_prompt: {positive_prompt}")
|
| 105 |
+
print(f"negative_prompt: {negative_prompt}")
|
| 106 |
+
|
| 107 |
+
return positive_prompt, negative_prompt
|
| 108 |
+
|
| 109 |
+
|
| 110 |
+
NODE_CLASS_MAPPINGS = {
|
| 111 |
+
"MileHighStyler": MileHighStyler,
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
NODE_DISPLAY_NAME_MAPPINGS = {
|
| 115 |
+
"MileHighStyler": "Mile High Styler",
|
| 116 |
+
}
|
Mile_High_Styler/mile_high_styles.json
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|