Spaces:
Running
on
Zero
Running
on
Zero
Upload 43 files
Browse files- README.md +4 -2
- app.py +310 -70
- data/additional_details.json +250 -0
- data/artform.json +4 -0
- data/artist.json +713 -0
- data/background.json +270 -0
- data/body_types.json +44 -0
- data/clothing.json +344 -0
- data/composition.json +344 -0
- data/default_tags.json +10 -0
- data/device.json +48 -0
- data/digital_artform.json +70 -0
- data/hairstyles.json +84 -0
- data/lighting.json +124 -0
- data/photo_framing.json +12 -0
- data/photo_type.json +21 -0
- data/photographer.json +74 -0
- data/photography_styles.json +11 -0
- data/place.json +94 -0
- data/pose.json +344 -0
- data/roles.json +206 -0
- env.py +40 -0
- flux.py +327 -0
- loras.json +115 -115
- mod.py +89 -7
- modutils.py +1224 -0
- packages.txt +1 -0
- pre-requirements.txt +1 -0
- prompt.py +554 -0
- prompts/A close-up movie still of a young woman with a mix.txt +1 -0
- prompts/A surreal movie still featuring a vibrant green tr.txt +1 -0
- prompts/prompt_20240804_001736.txt +1 -0
- requirements.txt +7 -6
- tagger/character_series_dict.csv +0 -0
- tagger/danbooru_e621.csv +0 -0
- tagger/fl2cog.py +71 -0
- tagger/fl2flux.py +79 -0
- tagger/output.py +16 -0
- tagger/tag_group.csv +0 -0
- tagger/tagger.py +552 -0
- tagger/utils.py +50 -0
- tagger/v2.py +260 -0
README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1 |
---
|
2 |
title: FLUX LoRA the Explorer Mod
|
3 |
-
emoji:
|
4 |
colorFrom: red
|
5 |
colorTo: pink
|
6 |
sdk: gradio
|
@@ -8,7 +8,9 @@ sdk_version: 4.41.0
|
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
license: mit
|
11 |
-
duplicated_from:
|
|
|
|
|
12 |
models:
|
13 |
- black-forest-labs/FLUX.1-dev
|
14 |
- alvdansen/frosting_lane_flux
|
|
|
1 |
---
|
2 |
title: FLUX LoRA the Explorer Mod
|
3 |
+
emoji: 🏆😻
|
4 |
colorFrom: red
|
5 |
colorTo: pink
|
6 |
sdk: gradio
|
|
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
license: mit
|
11 |
+
duplicated_from:
|
12 |
+
- multimodalart/flux-lora-the-explorer
|
13 |
+
- gokaygokay/FLUX-Prompt-Generator
|
14 |
models:
|
15 |
- black-forest-labs/FLUX.1-dev
|
16 |
- alvdansen/frosting_lane_flux
|
app.py
CHANGED
@@ -8,7 +8,15 @@ from diffusers import DiffusionPipeline
|
|
8 |
import copy
|
9 |
import random
|
10 |
import time
|
11 |
-
from mod import models, clear_cache, get_repo_safetensors, change_base_model
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
|
13 |
# Load LoRAs from JSON file
|
14 |
with open('loras.json', 'r') as f:
|
@@ -76,30 +84,25 @@ def generate_image(prompt, trigger_word, steps, seed, cfg_scale, width, height,
|
|
76 |
return image
|
77 |
|
78 |
def run_lora(prompt, cfg_scale, steps, selected_index, randomize_seed, seed, width, height,
|
79 |
-
lora_scale,
|
80 |
-
if selected_index is None and not
|
81 |
gr.Info("LoRA isn't selected.")
|
82 |
# raise gr.Error("You must select a LoRA before proceeding.")
|
83 |
|
84 |
-
if
|
|
|
|
|
|
|
|
|
85 |
selected_lora = loras[selected_index]
|
86 |
lora_path = selected_lora["repo"]
|
87 |
trigger_word = selected_lora["trigger_word"]
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
with calculateDuration(f"Loading LoRA weights for {selected_lora['title']}"):
|
95 |
-
if selected_index is None and not lora_repo: # override
|
96 |
-
pass
|
97 |
-
elif lora_weights: # override
|
98 |
-
pipe.load_lora_weights(lora_path, weight_name=lora_weights)
|
99 |
-
elif "weights" in selected_lora:
|
100 |
-
pipe.load_lora_weights(lora_path, weight_name=selected_lora["weights"])
|
101 |
-
else:
|
102 |
-
pipe.load_lora_weights(lora_path)
|
103 |
|
104 |
# Set random seed for reproducibility
|
105 |
with calculateDuration("Randomizing seed"):
|
@@ -108,14 +111,12 @@ def run_lora(prompt, cfg_scale, steps, selected_index, randomize_seed, seed, wid
|
|
108 |
|
109 |
image = generate_image(prompt, trigger_word, steps, seed, cfg_scale, width, height, lora_scale, progress)
|
110 |
pipe.to("cpu")
|
111 |
-
if selected_index is not None or
|
112 |
clear_cache()
|
113 |
return image, seed
|
114 |
|
115 |
run_lora.zerogpu = True
|
116 |
|
117 |
-
|
118 |
-
|
119 |
css = '''
|
120 |
#gen_btn{height: 100%}
|
121 |
#title{text-align: center}
|
@@ -123,55 +124,95 @@ css = '''
|
|
123 |
#title img{width: 100px; margin-right: 0.5em}
|
124 |
#gallery .grid-wrap{height: 10vh}
|
125 |
'''
|
126 |
-
with gr.Blocks(theme=gr.themes.Soft(), css=css) as app:
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
with gr.
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
|
153 |
-
|
154 |
-
|
155 |
-
|
156 |
-
|
157 |
-
|
158 |
-
|
159 |
-
|
160 |
-
width = gr.Slider(label="Width", minimum=256, maximum=1536, step=64, value=1024)
|
161 |
-
height = gr.Slider(label="Height", minimum=256, maximum=1536, step=64, value=1024)
|
162 |
|
163 |
-
|
164 |
-
|
165 |
-
seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0, randomize=True)
|
166 |
|
167 |
-
|
168 |
-
|
169 |
-
|
170 |
-
|
171 |
-
|
172 |
|
173 |
-
|
174 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
175 |
|
176 |
gallery.select(
|
177 |
update_selection,
|
@@ -183,13 +224,212 @@ with gr.Blocks(theme=gr.themes.Soft(), css=css) as app:
|
|
183 |
triggers=[generate_button.click, prompt.submit],
|
184 |
fn=run_lora,
|
185 |
inputs=[prompt, cfg_scale, steps, selected_index, randomize_seed, seed, width, height,
|
186 |
-
lora_scale,
|
187 |
outputs=[result, seed]
|
188 |
)
|
189 |
|
190 |
-
lora_repo.change(get_repo_safetensors, [lora_repo], [lora_weights])
|
191 |
model_name.change(change_base_model, [model_name], None)
|
192 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
193 |
|
194 |
app.queue()
|
195 |
app.launch()
|
|
|
8 |
import copy
|
9 |
import random
|
10 |
import time
|
11 |
+
from mod import (models, clear_cache, get_repo_safetensors, change_base_model,
|
12 |
+
description_ui, num_loras, compose_lora_json, is_valid_lora, fuse_loras, get_trigger_word)
|
13 |
+
from flux import (search_civitai_lora, select_civitai_lora, search_civitai_lora_json,
|
14 |
+
download_my_lora, get_all_lora_tupled_list, apply_lora_prompt,
|
15 |
+
update_loras)
|
16 |
+
from tagger.tagger import predict_tags_wd, compose_prompt_to_copy
|
17 |
+
from tagger.fl2cog import predict_tags_fl2_cog
|
18 |
+
from tagger.fl2flux import predict_tags_fl2_flux
|
19 |
+
|
20 |
|
21 |
# Load LoRAs from JSON file
|
22 |
with open('loras.json', 'r') as f:
|
|
|
84 |
return image
|
85 |
|
86 |
def run_lora(prompt, cfg_scale, steps, selected_index, randomize_seed, seed, width, height,
|
87 |
+
lora_scale, lora_json, progress=gr.Progress(track_tqdm=True)):
|
88 |
+
if selected_index is None and not is_valid_lora(lora_json):
|
89 |
gr.Info("LoRA isn't selected.")
|
90 |
# raise gr.Error("You must select a LoRA before proceeding.")
|
91 |
|
92 |
+
if is_valid_lora(lora_json):
|
93 |
+
with calculateDuration("Loading LoRA weights"):
|
94 |
+
fuse_loras(pipe, lora_json)
|
95 |
+
trigger_word = get_trigger_word(lora_json)
|
96 |
+
elif selected_index is not None:
|
97 |
selected_lora = loras[selected_index]
|
98 |
lora_path = selected_lora["repo"]
|
99 |
trigger_word = selected_lora["trigger_word"]
|
100 |
+
# Load LoRA weights
|
101 |
+
with calculateDuration(f"Loading LoRA weights for {selected_lora['title']}"):
|
102 |
+
if "weights" in selected_lora:
|
103 |
+
pipe.load_lora_weights(lora_path, weight_name=selected_lora["weights"])
|
104 |
+
else:
|
105 |
+
pipe.load_lora_weights(lora_path)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
|
107 |
# Set random seed for reproducibility
|
108 |
with calculateDuration("Randomizing seed"):
|
|
|
111 |
|
112 |
image = generate_image(prompt, trigger_word, steps, seed, cfg_scale, width, height, lora_scale, progress)
|
113 |
pipe.to("cpu")
|
114 |
+
if selected_index is not None or is_valid_lora(lora_json): pipe.unload_lora_weights()
|
115 |
clear_cache()
|
116 |
return image, seed
|
117 |
|
118 |
run_lora.zerogpu = True
|
119 |
|
|
|
|
|
120 |
css = '''
|
121 |
#gen_btn{height: 100%}
|
122 |
#title{text-align: center}
|
|
|
124 |
#title img{width: 100px; margin-right: 0.5em}
|
125 |
#gallery .grid-wrap{height: 10vh}
|
126 |
'''
|
127 |
+
with gr.Blocks(theme=gr.themes.Soft(), fill_width=True, css=css) as app:
|
128 |
+
with gr.Tab("FLUX LoRA the Explorer"):
|
129 |
+
title = gr.HTML(
|
130 |
+
"""<h1><img src="https://huggingface.co/spaces/multimodalart/flux-lora-the-explorer/resolve/main/flux_lora.png" alt="LoRA">FLUX LoRA the Explorer Mod</h1>""",
|
131 |
+
elem_id="title",
|
132 |
+
)
|
133 |
+
selected_index = gr.State(None)
|
134 |
+
with gr.Row():
|
135 |
+
with gr.Column(scale=3):
|
136 |
+
with gr.Group():
|
137 |
+
with gr.Accordion("Generate Prompt from Image", open=False):
|
138 |
+
tagger_image = gr.Image(label="Input image", type="pil", sources=["upload", "clipboard"], height=256)
|
139 |
+
with gr.Accordion(label="Advanced options", open=False):
|
140 |
+
tagger_general_threshold = gr.Slider(label="Threshold", minimum=0.0, maximum=1.0, value=0.3, step=0.01, interactive=True)
|
141 |
+
tagger_character_threshold = gr.Slider(label="Character threshold", minimum=0.0, maximum=1.0, value=0.8, step=0.01, interactive=True)
|
142 |
+
neg_prompt = gr.Text(label="Negative Prompt", lines=1, max_lines=8, placeholder="", visible=False)
|
143 |
+
v2_character = gr.Textbox(label="Character", placeholder="hatsune miku", scale=2, visible=False)
|
144 |
+
v2_series = gr.Textbox(label="Series", placeholder="vocaloid", scale=2, visible=False)
|
145 |
+
v2_copy = gr.Button(value="Copy to clipboard", size="sm", interactive=False, visible=False)
|
146 |
+
tagger_algorithms = gr.CheckboxGroup(["Use WD Tagger", "Use CogFlorence-2.1-Large", "Use Florence-2-Flux"], label="Algorithms", value=["Use WD Tagger"])
|
147 |
+
tagger_generate_from_image = gr.Button(value="Generate Prompt from Image")
|
148 |
+
prompt = gr.Textbox(label="Prompt", lines=1, placeholder="Type a prompt after selecting a LoRA")
|
149 |
+
with gr.Column(scale=1, elem_id="gen_column"):
|
150 |
+
generate_button = gr.Button("Generate", variant="primary", elem_id="gen_btn")
|
151 |
+
with gr.Row():
|
152 |
+
with gr.Column(scale=3):
|
153 |
+
selected_info = gr.Markdown("")
|
154 |
+
gallery = gr.Gallery(
|
155 |
+
[(item["image"], item["title"]) for item in loras],
|
156 |
+
label="LoRA Gallery",
|
157 |
+
allow_preview=False,
|
158 |
+
columns=3,
|
159 |
+
elem_id="gallery"
|
160 |
+
)
|
|
|
|
|
161 |
|
162 |
+
with gr.Column(scale=4):
|
163 |
+
result = gr.Image(label="Generated Image")
|
|
|
164 |
|
165 |
+
with gr.Row():
|
166 |
+
with gr.Accordion("Advanced Settings", open=False):
|
167 |
+
with gr.Column():
|
168 |
+
with gr.Row():
|
169 |
+
model_name = gr.Dropdown(label="Base Model", choices=models, value=models[0], allow_custom_value=True)
|
170 |
|
171 |
+
with gr.Row():
|
172 |
+
cfg_scale = gr.Slider(label="CFG Scale", minimum=1, maximum=20, step=0.5, value=3.5)
|
173 |
+
steps = gr.Slider(label="Steps", minimum=1, maximum=50, step=1, value=28)
|
174 |
+
|
175 |
+
with gr.Row():
|
176 |
+
width = gr.Slider(label="Width", minimum=256, maximum=1536, step=64, value=1024)
|
177 |
+
height = gr.Slider(label="Height", minimum=256, maximum=1536, step=64, value=1024)
|
178 |
+
|
179 |
+
with gr.Row():
|
180 |
+
randomize_seed = gr.Checkbox(True, label="Randomize seed")
|
181 |
+
seed = gr.Slider(label="Seed", minimum=0, maximum=MAX_SEED, step=1, value=0, randomize=True)
|
182 |
+
lora_scale = gr.Slider(label="LoRA Scale", minimum=0, maximum=1, step=0.01, value=0.95)
|
183 |
+
|
184 |
+
with gr.Column():
|
185 |
+
lora_repo_json = gr.JSON(value=[{}] * num_loras, visible=False)
|
186 |
+
lora_repo = [None] * num_loras
|
187 |
+
lora_weights = [None] * num_loras
|
188 |
+
lora_trigger = [None] * num_loras
|
189 |
+
lora_wt = [None] * num_loras
|
190 |
+
lora_info = [None] * num_loras
|
191 |
+
lora_copy = [None] * num_loras
|
192 |
+
lora_md = [None] * num_loras
|
193 |
+
lora_num = [None] * num_loras
|
194 |
+
for i in range(num_loras):
|
195 |
+
with gr.Group():
|
196 |
+
with gr.Row():
|
197 |
+
lora_repo[i] = gr.Dropdown(label=f"LoRA {int(i+1)} Repo", choices=get_all_lora_tupled_list(), info="Input LoRA Repo ID", value="", allow_custom_value=True)
|
198 |
+
lora_weights[i] = gr.Dropdown(label=f"LoRA {int(i+1)} Filename", choices=[], info="Optional", value="", allow_custom_value=True)
|
199 |
+
lora_trigger[i] = gr.Textbox(label=f"LoRA {int(i+1)} Trigger Prompt", value="")
|
200 |
+
lora_wt[i] = gr.Slider(label=f"LoRA {int(i+1)} Scale", minimum=-2, maximum=2, step=0.01, value=1.00)
|
201 |
+
with gr.Row():
|
202 |
+
lora_info[i] = gr.Textbox(label="", info="Example of prompt:", value="", show_copy_button=True, interactive=False, visible=False)
|
203 |
+
lora_copy[i] = gr.Button(value="Copy example to prompt", visible=False)
|
204 |
+
lora_md[i] = gr.Markdown(value="", visible=False)
|
205 |
+
lora_num[i] = gr.Number(i, visible=False)
|
206 |
+
with gr.Accordion("From URL", open=True, visible=True):
|
207 |
+
with gr.Row():
|
208 |
+
lora_search_civitai_query = gr.Textbox(label="Query", placeholder="flux", lines=1)
|
209 |
+
lora_search_civitai_basemodel = gr.CheckboxGroup(label="Search LoRA for", choices=["Flux.1 D", "Flux.1 S"], value=["Flux.1 D", "Flux.1 S"])
|
210 |
+
lora_search_civitai_submit = gr.Button("Search on Civitai")
|
211 |
+
lora_search_civitai_result = gr.Dropdown(label="Search Results", choices=[("", "")], value="", allow_custom_value=True, visible=False)
|
212 |
+
lora_search_civitai_json = gr.JSON(value={}, visible=False)
|
213 |
+
lora_search_civitai_desc = gr.Markdown(value="", visible=False)
|
214 |
+
lora_download_url = gr.Textbox(label="URL", placeholder="http://...my_lora_url.safetensors", lines=1)
|
215 |
+
lora_download = gr.Button("Get and set LoRA")
|
216 |
|
217 |
gallery.select(
|
218 |
update_selection,
|
|
|
224 |
triggers=[generate_button.click, prompt.submit],
|
225 |
fn=run_lora,
|
226 |
inputs=[prompt, cfg_scale, steps, selected_index, randomize_seed, seed, width, height,
|
227 |
+
lora_scale, lora_repo_json], #
|
228 |
outputs=[result, seed]
|
229 |
)
|
230 |
|
|
|
231 |
model_name.change(change_base_model, [model_name], None)
|
232 |
|
233 |
+
gr.on(
|
234 |
+
triggers=[lora_search_civitai_submit.click, lora_search_civitai_query.submit],
|
235 |
+
fn=search_civitai_lora,
|
236 |
+
inputs=[lora_search_civitai_query, lora_search_civitai_basemodel],
|
237 |
+
outputs=[lora_search_civitai_result, lora_search_civitai_desc, lora_search_civitai_submit, lora_search_civitai_query],
|
238 |
+
scroll_to_output=True,
|
239 |
+
queue=True,
|
240 |
+
show_api=False,
|
241 |
+
)
|
242 |
+
lora_search_civitai_json.change(search_civitai_lora_json, [lora_search_civitai_query, lora_search_civitai_basemodel], [lora_search_civitai_json], queue=True, show_api=True) # fn for api
|
243 |
+
lora_search_civitai_result.change(select_civitai_lora, [lora_search_civitai_result], [lora_download_url, lora_search_civitai_desc], scroll_to_output=True, queue=False, show_api=False)
|
244 |
+
gr.on(
|
245 |
+
triggers=[lora_download.click, lora_download_url.submit],
|
246 |
+
fn=download_my_lora,
|
247 |
+
inputs=[lora_download_url, lora_repo[0]],
|
248 |
+
outputs=[lora_repo[0]],
|
249 |
+
scroll_to_output=True,
|
250 |
+
queue=True,
|
251 |
+
show_api=False,
|
252 |
+
)
|
253 |
+
|
254 |
+
for i, l in enumerate(lora_repo):
|
255 |
+
gr.on(
|
256 |
+
triggers=[lora_repo[i].change, lora_wt[i].change],
|
257 |
+
fn=update_loras,
|
258 |
+
inputs=[prompt, lora_repo[i], lora_wt[i]],
|
259 |
+
outputs=[prompt, lora_repo[i], lora_wt[i], lora_info[i], lora_copy[i], lora_md[i]],
|
260 |
+
queue=False,
|
261 |
+
trigger_mode="once",
|
262 |
+
show_api=False,
|
263 |
+
).success(get_repo_safetensors, [lora_repo[i]], [lora_weights[i]], queue=False, show_api=False
|
264 |
+
).success(apply_lora_prompt, [lora_info[i]], [lora_trigger[i]], queue=False, show_api=False
|
265 |
+
).success(compose_lora_json, [lora_repo_json, lora_num[i], lora_repo[i], lora_wt[i], lora_weights[i], lora_trigger[i]], [lora_repo_json], queue=False, show_api=False)
|
266 |
+
|
267 |
+
tagger_generate_from_image.click(
|
268 |
+
lambda: ("", "", ""), None, [v2_series, v2_character, prompt], queue=False, show_api=False,
|
269 |
+
).success(
|
270 |
+
predict_tags_wd,
|
271 |
+
[tagger_image, prompt, tagger_algorithms, tagger_general_threshold, tagger_character_threshold],
|
272 |
+
[v2_series, v2_character, prompt, v2_copy],
|
273 |
+
show_api=False,
|
274 |
+
).success(
|
275 |
+
predict_tags_fl2_flux, [tagger_image, prompt, tagger_algorithms], [prompt], show_api=False,
|
276 |
+
).success(
|
277 |
+
predict_tags_fl2_cog, [tagger_image, prompt, tagger_algorithms], [prompt], show_api=False,
|
278 |
+
).success(
|
279 |
+
compose_prompt_to_copy, [v2_character, v2_series, prompt], [prompt], queue=False, show_api=False,
|
280 |
+
)
|
281 |
+
|
282 |
+
with gr.Tab("FLUX Prompt Generator"):
|
283 |
+
from prompt import (PromptGenerator, HuggingFaceInferenceNode, florence_caption,
|
284 |
+
ARTFORM, PHOTO_TYPE, BODY_TYPES, DEFAULT_TAGS, ROLES, HAIRSTYLES, ADDITIONAL_DETAILS,
|
285 |
+
PHOTOGRAPHY_STYLES, DEVICE, PHOTOGRAPHER, ARTIST, DIGITAL_ARTFORM, PLACE,
|
286 |
+
LIGHTING, CLOTHING, COMPOSITION, POSE, BACKGROUND, pg_title)
|
287 |
+
|
288 |
+
prompt_generator = PromptGenerator()
|
289 |
+
huggingface_node = HuggingFaceInferenceNode()
|
290 |
+
|
291 |
+
gr.HTML(pg_title)
|
292 |
+
|
293 |
+
with gr.Row():
|
294 |
+
with gr.Column(scale=2):
|
295 |
+
with gr.Accordion("Basic Settings"):
|
296 |
+
pg_seed = gr.Slider(0, 30000, label='Seed', step=1, value=random.randint(0,30000))
|
297 |
+
pg_custom = gr.Textbox(label="Custom Input Prompt (optional)")
|
298 |
+
pg_subject = gr.Textbox(label="Subject (optional)")
|
299 |
+
|
300 |
+
# Add the radio button for global option selection
|
301 |
+
pg_global_option = gr.Radio(
|
302 |
+
["Disabled", "Random", "No Figure Rand"],
|
303 |
+
label="Set all options to:",
|
304 |
+
value="Disabled"
|
305 |
+
)
|
306 |
+
|
307 |
+
with gr.Accordion("Artform and Photo Type", open=False):
|
308 |
+
pg_artform = gr.Dropdown(["disabled", "random"] + ARTFORM, label="Artform", value="disabled")
|
309 |
+
pg_photo_type = gr.Dropdown(["disabled", "random"] + PHOTO_TYPE, label="Photo Type", value="disabled")
|
310 |
+
|
311 |
+
with gr.Accordion("Character Details", open=False):
|
312 |
+
pg_body_types = gr.Dropdown(["disabled", "random"] + BODY_TYPES, label="Body Types", value="disabled")
|
313 |
+
pg_default_tags = gr.Dropdown(["disabled", "random"] + DEFAULT_TAGS, label="Default Tags", value="disabled")
|
314 |
+
pg_roles = gr.Dropdown(["disabled", "random"] + ROLES, label="Roles", value="disabled")
|
315 |
+
pg_hairstyles = gr.Dropdown(["disabled", "random"] + HAIRSTYLES, label="Hairstyles", value="disabled")
|
316 |
+
pg_clothing = gr.Dropdown(["disabled", "random"] + CLOTHING, label="Clothing", value="disabled")
|
317 |
+
|
318 |
+
with gr.Accordion("Scene Details", open=False):
|
319 |
+
pg_place = gr.Dropdown(["disabled", "random"] + PLACE, label="Place", value="disabled")
|
320 |
+
pg_lighting = gr.Dropdown(["disabled", "random"] + LIGHTING, label="Lighting", value="disabled")
|
321 |
+
pg_composition = gr.Dropdown(["disabled", "random"] + COMPOSITION, label="Composition", value="disabled")
|
322 |
+
pg_pose = gr.Dropdown(["disabled", "random"] + POSE, label="Pose", value="disabled")
|
323 |
+
pg_background = gr.Dropdown(["disabled", "random"] + BACKGROUND, label="Background", value="disabled")
|
324 |
+
|
325 |
+
with gr.Accordion("Style and Artist", open=False):
|
326 |
+
pg_additional_details = gr.Dropdown(["disabled", "random"] + ADDITIONAL_DETAILS, label="Additional Details", value="disabled")
|
327 |
+
pg_photography_styles = gr.Dropdown(["disabled", "random"] + PHOTOGRAPHY_STYLES, label="Photography Styles", value="disabled")
|
328 |
+
pg_device = gr.Dropdown(["disabled", "random"] + DEVICE, label="Device", value="disabled")
|
329 |
+
pg_photographer = gr.Dropdown(["disabled", "random"] + PHOTOGRAPHER, label="Photographer", value="disabled")
|
330 |
+
pg_artist = gr.Dropdown(["disabled", "random"] + ARTIST, label="Artist", value="disabled")
|
331 |
+
pg_digital_artform = gr.Dropdown(["disabled", "random"] + DIGITAL_ARTFORM, label="Digital Artform", value="disabled")
|
332 |
+
|
333 |
+
pg_generate_button = gr.Button("Generate Prompt")
|
334 |
+
|
335 |
+
with gr.Column(scale=2):
|
336 |
+
with gr.Accordion("Image and Caption", open=False):
|
337 |
+
pg_input_image = gr.Image(label="Input Image (optional)")
|
338 |
+
pg_caption_output = gr.Textbox(label="Generated Caption", lines=3)
|
339 |
+
pg_create_caption_button = gr.Button("Create Caption")
|
340 |
+
pg_add_caption_button = gr.Button("Add Caption to Prompt")
|
341 |
+
|
342 |
+
with gr.Accordion("Prompt Generation", open=True):
|
343 |
+
pg_output = gr.Textbox(label="Generated Prompt / Input Text", lines=4)
|
344 |
+
pg_t5xxl_output = gr.Textbox(label="T5XXL Output", visible=True)
|
345 |
+
pg_clip_l_output = gr.Textbox(label="CLIP L Output", visible=True)
|
346 |
+
pg_clip_g_output = gr.Textbox(label="CLIP G Output", visible=True)
|
347 |
+
|
348 |
+
with gr.Column(scale=2):
|
349 |
+
with gr.Accordion("Prompt Generation with LLM", open=False):
|
350 |
+
pg_model = gr.Dropdown(["Mixtral", "Mistral", "Llama 3", "Mistral-Nemo"], label="Model", value="Llama 3")
|
351 |
+
pg_happy_talk = gr.Checkbox(label="Happy Talk", value=True)
|
352 |
+
pg_compress = gr.Checkbox(label="Compress", value=True)
|
353 |
+
pg_compression_level = gr.Radio(["soft", "medium", "hard"], label="Compression Level", value="hard")
|
354 |
+
pg_poster = gr.Checkbox(label="Poster", value=False)
|
355 |
+
pg_custom_base_prompt = gr.Textbox(label="Custom Base Prompt", lines=5)
|
356 |
+
pg_generate_text_button = gr.Button("Generate Prompt with LLM")
|
357 |
+
pg_text_output = gr.Textbox(label="Generated Text", lines=10)
|
358 |
+
|
359 |
+
description_ui()
|
360 |
+
|
361 |
+
def create_caption(image):
|
362 |
+
if image is not None:
|
363 |
+
return florence_caption(image)
|
364 |
+
return ""
|
365 |
+
|
366 |
+
pg_create_caption_button.click(
|
367 |
+
create_caption,
|
368 |
+
inputs=[pg_input_image],
|
369 |
+
outputs=[pg_caption_output]
|
370 |
+
)
|
371 |
+
|
372 |
+
pg_generate_button.click(
|
373 |
+
prompt_generator.generate_prompt,
|
374 |
+
inputs=[pg_seed, pg_custom, pg_subject, pg_artform, pg_photo_type, pg_body_types,
|
375 |
+
pg_default_tags, pg_roles, pg_hairstyles,
|
376 |
+
pg_additional_details, pg_photography_styles, pg_device, pg_photographer,
|
377 |
+
pg_artist, pg_digital_artform,
|
378 |
+
pg_place, pg_lighting, pg_clothing, pg_composition, pg_pose, pg_background],
|
379 |
+
outputs=[pg_output, gr.Number(visible=False), pg_t5xxl_output, pg_clip_l_output, pg_clip_g_output]
|
380 |
+
)
|
381 |
+
|
382 |
+
pg_add_caption_button.click(
|
383 |
+
prompt_generator.add_caption_to_prompt,
|
384 |
+
inputs=[pg_output, pg_caption_output],
|
385 |
+
outputs=[pg_output]
|
386 |
+
)
|
387 |
+
|
388 |
+
pg_generate_text_button.click(
|
389 |
+
huggingface_node.generate,
|
390 |
+
inputs=[pg_model, pg_output, pg_happy_talk, pg_compress, pg_compression_level,
|
391 |
+
pg_poster, pg_custom_base_prompt],
|
392 |
+
outputs=pg_text_output
|
393 |
+
)
|
394 |
+
|
395 |
+
def update_all_options(choice):
|
396 |
+
updates = {}
|
397 |
+
if choice == "Disabled":
|
398 |
+
for dropdown in [
|
399 |
+
pg_artform, pg_photo_type, pg_body_types, pg_default_tags,
|
400 |
+
pg_roles, pg_hairstyles, pg_clothing,
|
401 |
+
pg_place, pg_lighting, pg_composition, pg_pose, pg_background, pg_additional_details,
|
402 |
+
pg_photography_styles, pg_device, pg_photographer, pg_artist, pg_digital_artform
|
403 |
+
]:
|
404 |
+
updates[dropdown] = gr.update(value="disabled")
|
405 |
+
elif choice == "Random":
|
406 |
+
for dropdown in [
|
407 |
+
pg_artform, pg_photo_type, pg_body_types, pg_default_tags,
|
408 |
+
pg_roles, pg_hairstyles, pg_clothing,
|
409 |
+
pg_place, pg_lighting, pg_composition, pg_pose, pg_background, pg_additional_details,
|
410 |
+
pg_photography_styles, pg_device, pg_photographer, pg_artist, pg_digital_artform
|
411 |
+
]:
|
412 |
+
updates[dropdown] = gr.update(value="random")
|
413 |
+
else: # No Figure Random
|
414 |
+
for dropdown in [pg_photo_type, pg_body_types, pg_default_tags,
|
415 |
+
pg_roles, pg_hairstyles, pg_clothing, pg_pose, pg_additional_details]:
|
416 |
+
updates[dropdown] = gr.update(value="disabled")
|
417 |
+
for dropdown in [pg_artform, pg_place, pg_lighting, pg_composition,
|
418 |
+
pg_background, pg_photography_styles, pg_device, pg_photographer,
|
419 |
+
pg_artist, pg_digital_artform]:
|
420 |
+
updates[dropdown] = gr.update(value="random")
|
421 |
+
return updates
|
422 |
+
|
423 |
+
pg_global_option.change(
|
424 |
+
update_all_options,
|
425 |
+
inputs=[pg_global_option],
|
426 |
+
outputs=[
|
427 |
+
pg_artform, pg_photo_type, pg_body_types, pg_default_tags,
|
428 |
+
pg_roles, pg_hairstyles, pg_clothing,
|
429 |
+
pg_place, pg_lighting, pg_composition, pg_pose, pg_background, pg_additional_details,
|
430 |
+
pg_photography_styles, pg_device, pg_photographer, pg_artist, pg_digital_artform
|
431 |
+
]
|
432 |
+
)
|
433 |
|
434 |
app.queue()
|
435 |
app.launch()
|
data/additional_details.json
ADDED
@@ -0,0 +1,250 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"a purple iridescent suit",
|
3 |
+
"wearing a (necklace)",
|
4 |
+
"wearing ((earrings))",
|
5 |
+
"wearing a (bracelet)",
|
6 |
+
"wearing one or multiple (rings)",
|
7 |
+
"wearing a (brooch)",
|
8 |
+
"wearing (eyeglasses)",
|
9 |
+
"wearing (sunglasses)",
|
10 |
+
"wearing a (hat)",
|
11 |
+
"wearing a (scarf)",
|
12 |
+
"wearing a (headband)",
|
13 |
+
"wearing a (nose ring)",
|
14 |
+
"wearing a (lip ring)",
|
15 |
+
"wearing a (tongue ring)",
|
16 |
+
"wearing an (eyebrow ring)",
|
17 |
+
"wearing (face tattoos)",
|
18 |
+
"wearing a (wreath)",
|
19 |
+
"wearing a (crown)",
|
20 |
+
"wearing a (tiara)",
|
21 |
+
"wearing a (crown of thorns)",
|
22 |
+
"wearing a (crown of jewels)",
|
23 |
+
"wearing (bohemian clothes)",
|
24 |
+
"wearing (chic clothes)",
|
25 |
+
"wearing (glamorous clothes)",
|
26 |
+
"wearing (grunge clothes)",
|
27 |
+
"wearing (preppy clothes)",
|
28 |
+
"wearing (punk clothes)",
|
29 |
+
"wearing (retro clothes)",
|
30 |
+
"wearing (rockabilly clothes)",
|
31 |
+
"wearing (romantic clothes)",
|
32 |
+
"wearing (tomboy clothes)",
|
33 |
+
"wearing (urban clothes)",
|
34 |
+
"wearing (camo clothes)",
|
35 |
+
"wearing (robes)",
|
36 |
+
"wearing (excessive amount of jewellery)",
|
37 |
+
"wearing (vintage clothes)",
|
38 |
+
"wearing (western clothes)",
|
39 |
+
"wearing (minimalist clothes)",
|
40 |
+
"wearing (sportswear clothes)",
|
41 |
+
"wearing (flapper clothes)",
|
42 |
+
"wearing (pin-up clothes)",
|
43 |
+
"wearing (mid-century modern clothes)",
|
44 |
+
"wearing (art deco clothes)",
|
45 |
+
"wearing (victorian clothes)",
|
46 |
+
"wearing (edwardian clothes)",
|
47 |
+
"wearing (elizabethan clothes)",
|
48 |
+
"wearing (retro 70s clothes)",
|
49 |
+
"wearing (retro 80s clothes)",
|
50 |
+
"wearing (retro 90s clothes)",
|
51 |
+
"wearing (retro 00s clothes)",
|
52 |
+
"wearing (musical equipment)",
|
53 |
+
"wearing (leather)",
|
54 |
+
"wearing (bdsm leather)",
|
55 |
+
"wearing (shiny latex)",
|
56 |
+
"wearing (shiny latex suit)",
|
57 |
+
"wearing (silk)",
|
58 |
+
"wearing (full tweed set)",
|
59 |
+
"wearing (clothes made entirely of feathers)",
|
60 |
+
"wearing (clothes made entirely of fur)",
|
61 |
+
"wearing (clothes made entirely of leather)",
|
62 |
+
"wearing (clothes made entirely of metal)",
|
63 |
+
"wearing (clothes made entirely of plastic)",
|
64 |
+
"wearing (clothes adorned with shimmering jewels or crystals)",
|
65 |
+
"waring (clothes adorned with sequins)",
|
66 |
+
"wearing (clothes with exaggerated or extreme silhouettes)",
|
67 |
+
"wearing (clothes with exaggerated or extreme footwear)",
|
68 |
+
"wearing (clothes with exaggerated or extreme headwear)",
|
69 |
+
"wearing (clothes with exaggerated or extreme facial or body piercings or tattoos)",
|
70 |
+
"wearing (clothes with multiple layers or tiers)",
|
71 |
+
"wearing (clothes with exaggerated or extreme colors)",
|
72 |
+
"wearing (clothes with exaggerated or extreme patterns)",
|
73 |
+
"wearing (cloak)",
|
74 |
+
"wearing an astronaut armor",
|
75 |
+
"wearing a bio mechanical suit",
|
76 |
+
"wearing a bio hazard suit",
|
77 |
+
"(( working with laptop))",
|
78 |
+
"with Heat deformation",
|
79 |
+
"(((future soldier, full body armor, futuristic football, shoulder pads, guns, grenades, weapons, bullet proof vest, high tech, straps, belts, camouflage)))",
|
80 |
+
"((full body, zoomed out)) long slender legs 80mm",
|
81 |
+
"(((sci-fi, future war, cyberpunk, cyborg, future fashion, beautiful face, glowing tattoos)))",
|
82 |
+
"((angry expression, pretty face))",
|
83 |
+
"(((full body, athletic body, action pose, detailed black soldier outfit, slender long legs)))",
|
84 |
+
"playing epic electric guitar solo in front of a huge crowd",
|
85 |
+
"singing epic solo into a microphone in front of a huge crowd",
|
86 |
+
"as a ((gelatinous horror dripping alien creature))",
|
87 |
+
"in a tie or bowtie, lending a touch of formal elegance or quirky charm, knotted around the collar to elevate the outfit",
|
88 |
+
"with anklets, delicate chains or beads that gracefully encircle the ankle, adding a touch of femininity with every step",
|
89 |
+
"donning a belt, functional yet fashionable, cinching the waist or sitting low on the hips, often with a statement buckle",
|
90 |
+
"wearing gloves, either elegant satin for formal events or rugged leather for a tougher look, complementing the attire and mood",
|
91 |
+
"with a choker, snugly encircling the neck, often made of lace, velvet, or leather, exuding a mix of elegance and edge",
|
92 |
+
"in stockings or tights, sheer or opaque, enhancing the legs while adding a touch of sophistication or playful patterns",
|
93 |
+
"with a satchel or bag, a functional accessory that speaks volumes about personal style, be it a minimalist tote or an embellished clutch",
|
94 |
+
"wearing cufflinks, subtle symbols of elegance, adorning the sleeves of a formal shirt, showcasing attention to detail",
|
95 |
+
"with a pendant, a piece of jewelry that dangles gracefully from a necklace, often holding sentimental or symbolic value",
|
96 |
+
"in layered necklaces, a blend of chains of varying lengths, creating depth and showcasing multiple pendants or charms",
|
97 |
+
"sporting a watch, a timeless accessory that blends functionality with style, either minimalist or grand, reflecting personal tastes",
|
98 |
+
"wearing a veil, a delicate piece of fabric that adds mystery and allure, often seen in bridal or ceremonial attire",
|
99 |
+
"donning a cape or cloak, adding drama to the ensemble, flowing gracefully with every movement, evoking a sense of fantasy or regality",
|
100 |
+
"with a tiara or diadem, a jeweled headpiece that signifies royalty or celebration, resting gracefully atop the head",
|
101 |
+
"Adorned with a crown, symbolizing royalty and authority with gemstones and metals.",
|
102 |
+
"With a sparkling tiara, reminiscent of princesses or beauty queens.",
|
103 |
+
"With a poignant crown of thorns, symbolizing sacrifice and resilience.",
|
104 |
+
"With a jewel-encrusted crown, reflecting affluence and grandeur.",
|
105 |
+
"In bohemian attire, embodying the free spirits with patterns and fringes.",
|
106 |
+
"Dressed in chic fashion, blending comfort with high style.",
|
107 |
+
"In glamorous attire, shiny or sequined, perfect for red-carpet events.",
|
108 |
+
"Donning grunge wear, with flannels and combat boots, reflecting rebellion.",
|
109 |
+
"In preppy attire, sophisticated with collared shirts and blazers.",
|
110 |
+
"Wearing punk fashion, with studded accessories and band tees.",
|
111 |
+
"In retro attire, drawing from various iconic decades.",
|
112 |
+
"In rockabilly style, mixing rock 'n' roll with polka dots and swing dresses.",
|
113 |
+
"In romantic wear, with lace, ruffles, and pastel shades.",
|
114 |
+
"In tomboy attire, masculine pieces with a feminine flair.",
|
115 |
+
"Wearing urban fashion, blending street style with graphic tees and chunky sneakers.",
|
116 |
+
"In camo wear, military-inspired, blending in yet standing out.",
|
117 |
+
"Draped in mystic robes, evoking scholars or wizards.",
|
118 |
+
"Adorned in abundant jewelry, each piece showcasing unique style.",
|
119 |
+
"In vintage attire, echoing past eras with intricate designs.",
|
120 |
+
"In western wear, with cowboy hats and fringed jackets.",
|
121 |
+
"In minimalist fashion, elegant with clean lines and neutral tones.",
|
122 |
+
"Wearing sportswear, functional with athletic shoes.",
|
123 |
+
"In flapper style, evoking the lively 1920s jazz scene.",
|
124 |
+
"In pin-up attire, oozing sensuality with high-waists and red lipstick.",
|
125 |
+
"In mid-century modern fashion, reflecting post-war optimism.",
|
126 |
+
"In art deco style, fusing modern with lavish 20s embellishments.",
|
127 |
+
"Dressed in Victorian elegance, with corsets and intricate lacework.",
|
128 |
+
"In Edwardian attire, showcasing lighter fabrics, empire waistlines, and large hats.",
|
129 |
+
"Dressed in Elizabethan style, with ruffled collars, velvet gowns, and detailed embroidery.",
|
130 |
+
"In 70s retro, featuring psychedelic patterns, bell-bottoms, and platform shoes.",
|
131 |
+
"Wearing 80s retro, marked by neon colors, shoulder pads, and oversized tops.",
|
132 |
+
"In 90s attire, blending grunge, minimalism, and sportswear, with baggy jeans and crop tops.",
|
133 |
+
"Donning 00s style, with low-rise jeans, bedazzled tops, and chunky belts.",
|
134 |
+
"Adorned with musical accessories, like a harmonica necklace or drumstick earrings.",
|
135 |
+
"In leather, symbolizing toughness with studs or zippers.",
|
136 |
+
"In bold BDSM leather, featuring harnesses, chokers, and lace-up details.",
|
137 |
+
"In reflective latex, often seen in avant-garde fashion.",
|
138 |
+
"In a glossy latex suit, paired with high heels or boots.",
|
139 |
+
"Draped in luxurious silk, synonymous with opulence and elegance.",
|
140 |
+
"In a tweed ensemble, reflecting academia or British countryside charm.",
|
141 |
+
"Clothed in feathers, creating drama with each step.",
|
142 |
+
"In fur, a symbol of luxury and grandeur.",
|
143 |
+
"In metallic attire, with futuristic chains or mesh details.",
|
144 |
+
"In vibrant plastic wear, modern and edgy.",
|
145 |
+
"Adorned in dazzling jewels or crystals.",
|
146 |
+
"In sequined attire, perfect for parties or performances.",
|
147 |
+
"In exaggerated silhouettes, challenging fashion norms.",
|
148 |
+
"In layered clothing, adding depth and dimension.",
|
149 |
+
"In astronaut armor, representing space exploration.",
|
150 |
+
"In a bio-mechanical suit, blending organic and synthetic elements.",
|
151 |
+
"Wearing a protective biohazard suit.",
|
152 |
+
"Engaged with a laptop, reflecting a tech-savvy nature.",
|
153 |
+
"Surrounded by heat deformation or mirage effects.",
|
154 |
+
"As a futuristic soldier, equipped for dystopian warfare.",
|
155 |
+
"A translucent, amorphous alien creature, often found in horror or sci-fi.",
|
156 |
+
"Wearing a cloak, suggesting mystery, fantasy, or protection.",
|
157 |
+
"Playing a gripping electric guitar solo, immersed in the audience's energy.",
|
158 |
+
"Singing intensely, with the crowd hanging on every word.",
|
159 |
+
"A pulsating, translucent horror, invoking fear and intrigue.",
|
160 |
+
"Full-body view highlighting slender legs and distinctive footwear.",
|
161 |
+
"Futuristic, with glowing tattoos and cybernetic features.",
|
162 |
+
"Angry expression on a strikingly beautiful face.",
|
163 |
+
"In an action pose, dressed in a detailed black soldier outfit.",
|
164 |
+
"Lost in an electric guitar solo, resonating with listeners.",
|
165 |
+
"Singing powerfully, captivating the audience with deep emotion.",
|
166 |
+
"A shifting, glistening alien horror from the universe's dark corners.",
|
167 |
+
"Full body, focusing on 80mm slender legs emphasizing height.",
|
168 |
+
"Blending sci-fi, cyberpunk, and glowing tattoos with futuristic weapons.",
|
169 |
+
"Attire shimmering due to heat, creating a mirage effect.",
|
170 |
+
"A future soldier with body armor, high-tech gear, and camouflaged straps.",
|
171 |
+
"Guitar solo with a crowd backdrop, producing electrifying sounds.",
|
172 |
+
"Singing with passion, surrounded by lights and a massive audience's energy.",
|
173 |
+
"A shifting, oozing alien creature, invoking dread and curiosity.",
|
174 |
+
"Full-body focus on remarkable 80mm slender legs.",
|
175 |
+
"A future soldier with cyberpunk aesthetics and glowing tattoos.",
|
176 |
+
"Intense expression on a stunning face, showing raw emotion.",
|
177 |
+
"Athletic pose in a detailed black soldier outfit, emphasizing a fit physique.",
|
178 |
+
"Electrifying guitar solo before a massive cheering crowd.",
|
179 |
+
"Singing with raw emotion, captivating a vast audience.",
|
180 |
+
"A gelatinous, glowing alien creature; both feared and intriguing.",
|
181 |
+
"Full-body shot highlighting exaggerated 80mm slender legs.",
|
182 |
+
"Adorned in sci-fi, cyberpunk attire with glowing tattoos.",
|
183 |
+
"Heated demeanor causing mirage-like distortions around them.",
|
184 |
+
"Future soldier in body armor with high-tech gear.",
|
185 |
+
"Zoomed-out shot emphasizing 80mm long slender legs.",
|
186 |
+
"Sci-fi and cyberpunk blend with glowing tattoos.",
|
187 |
+
"Epic guitar solo captivating a vast audience.",
|
188 |
+
"Intense solo performance with a powerful voice.",
|
189 |
+
"Ever-changing gelatinous alien of horror.",
|
190 |
+
"Full-body shot, 80mm slender legs in focus.",
|
191 |
+
"Futuristic, cyberpunk with glow-emitting tattoos.",
|
192 |
+
"Heat-induced warping surroundings like a mirage.",
|
193 |
+
"Tech-equipped future soldier ready for battle.",
|
194 |
+
"Full-body view, 80mm legs as highlight.",
|
195 |
+
"Sci-fi blend with glow-in-the-dark tattoos.",
|
196 |
+
"Swift guitar solo resonating with a huge crowd.",
|
197 |
+
"Passionate vocal solo captivating listeners.",
|
198 |
+
"Dripping, amorphous alien creature.",
|
199 |
+
"Full-body stance, 80mm slender legs showcased.",
|
200 |
+
"a shimmering sequin dress",
|
201 |
+
"wearing studded (ankle boots)",
|
202 |
+
"donning a (velvet cape)",
|
203 |
+
"wearing a (choker)",
|
204 |
+
"sporting (platform shoes)",
|
205 |
+
"adorned with a (body chain)",
|
206 |
+
"wearing a (fringed jacket)",
|
207 |
+
"donning (fingerless gloves)",
|
208 |
+
"wearing (fishnet stockings)",
|
209 |
+
"draped in a (kimono)",
|
210 |
+
"wearing (combat boots)",
|
211 |
+
"adorned with a (belly chain)",
|
212 |
+
"wearing a (biker jacket)",
|
213 |
+
"donning (thigh-high boots)",
|
214 |
+
"wearing (steampunk goggles)",
|
215 |
+
"adorned with (arm cuffs)",
|
216 |
+
"wearing a (corset belt)",
|
217 |
+
"donning a (turban)",
|
218 |
+
"sporting a (feathered headdress)",
|
219 |
+
"wearing (holo sneakers)",
|
220 |
+
"adorned with (toe rings)",
|
221 |
+
"draped in a (sari)",
|
222 |
+
"wearing (futuristic visor)",
|
223 |
+
"sporting (peep-toe heels)",
|
224 |
+
"adorned with (upper arm bracelets)",
|
225 |
+
"wearing a (poncho)",
|
226 |
+
"donning (knee-high socks)",
|
227 |
+
"draped in a (toga)",
|
228 |
+
"wearing a (flapper dress)",
|
229 |
+
"sporting (winged shoes)",
|
230 |
+
"wearing a (ruffled blouse)",
|
231 |
+
"adorned with a (leg chain)",
|
232 |
+
"wearing (gladiator sandals)",
|
233 |
+
"draped in a (cloak)",
|
234 |
+
"sporting (suspenders)",
|
235 |
+
"donning a (beret)",
|
236 |
+
"wearing (cufflinks)",
|
237 |
+
"adorned with a (medallion)",
|
238 |
+
"wearing (spats)",
|
239 |
+
"sporting (elbow-length gloves)",
|
240 |
+
"donning (denim overalls)",
|
241 |
+
"wearing a (mesh top)",
|
242 |
+
"adorned with (ear cuffs)",
|
243 |
+
"draped in a (shawl)",
|
244 |
+
"wearing a (trilby hat)",
|
245 |
+
"sporting (stiletto heels)",
|
246 |
+
"wearing a (vest)",
|
247 |
+
"adorned with (hairpins)",
|
248 |
+
"wearing (espadrilles)",
|
249 |
+
"draped in a (trench coat)"
|
250 |
+
]
|
data/artform.json
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"photography",
|
3 |
+
"art"
|
4 |
+
]
|
data/artist.json
ADDED
@@ -0,0 +1,713 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"Akihito Tsukushi",
|
3 |
+
"Al Hirschfeld",
|
4 |
+
"Alan Lee",
|
5 |
+
"Albert Bierstadt",
|
6 |
+
"Albert Uderzo",
|
7 |
+
"Alberto Giacometti",
|
8 |
+
"Alberto Vargas",
|
9 |
+
"Albrecht Durer",
|
10 |
+
"Alejandro Burdisio",
|
11 |
+
"Aleksi Briclot",
|
12 |
+
"Alessio Albi",
|
13 |
+
"Alena Aenami",
|
14 |
+
"Alex Gard",
|
15 |
+
"Alex Grey",
|
16 |
+
"Alex Maleev",
|
17 |
+
"Alexander Jansson",
|
18 |
+
"Alexander Milne Calder",
|
19 |
+
"Alexandre Cabanel",
|
20 |
+
"Alexei Savrasov",
|
21 |
+
"Alexej von Jawlensky",
|
22 |
+
"Alfred Kubin",
|
23 |
+
"Alfredo Volpi",
|
24 |
+
"Alice Neel",
|
25 |
+
"Alice Rahon",
|
26 |
+
"Alphonse Mucha",
|
27 |
+
"Alyssa Monks",
|
28 |
+
"Amanda Clark",
|
29 |
+
"Amanda Sage",
|
30 |
+
"Amedeo Modigliani",
|
31 |
+
"Amelie Bernard",
|
32 |
+
"Anders Zorn",
|
33 |
+
"Andreas Achenbach",
|
34 |
+
"Andrew Wyeth",
|
35 |
+
"Andr\u00e9 Kert\u00e9sz",
|
36 |
+
"Andr\u00e9 Masson",
|
37 |
+
"Andy Fairhurst",
|
38 |
+
"Andy Singer",
|
39 |
+
"Andy Warhol",
|
40 |
+
"Anita Malfatti",
|
41 |
+
"Anna Dittmann",
|
42 |
+
"Anne Geddes",
|
43 |
+
"Anne Stokes",
|
44 |
+
"Anne-Louis Girodet",
|
45 |
+
"Annibale Carracci",
|
46 |
+
"Annie Leibovitz",
|
47 |
+
"Ansel Adams",
|
48 |
+
"Anthony van Dyck",
|
49 |
+
"Anton Fadeev",
|
50 |
+
"Anton Otto",
|
51 |
+
"Apollonia Saintclair",
|
52 |
+
"Arkhip Kuindzhi",
|
53 |
+
"Arnold B\u00f6cklin",
|
54 |
+
"Arshile Gorky",
|
55 |
+
"Art Spiegelman",
|
56 |
+
"Artemisia Gentileschi",
|
57 |
+
"Arthur Dove",
|
58 |
+
"Asaf Hanuka",
|
59 |
+
"Asher Brown Durand",
|
60 |
+
"Ashley Wood",
|
61 |
+
"Audrey Kawasaki",
|
62 |
+
"Austin Briggs",
|
63 |
+
"Balthus",
|
64 |
+
"Banksy",
|
65 |
+
"Barclay Shaw",
|
66 |
+
"Barry Blitt",
|
67 |
+
"Bastien Lecouffe Deharme",
|
68 |
+
"Beatrix Potter",
|
69 |
+
"Beauford Delaney",
|
70 |
+
"Beeple",
|
71 |
+
"Ben Shahn",
|
72 |
+
"Benoit B. Mandelbrot",
|
73 |
+
"Bernard Buffet",
|
74 |
+
"Bernd and Hilla Becher",
|
75 |
+
"Bernie Wrightson",
|
76 |
+
"Berthe Morisot",
|
77 |
+
"Bill Plympton",
|
78 |
+
"Bjarke Ingels",
|
79 |
+
"Bob Byerley",
|
80 |
+
"Bob Eggleton",
|
81 |
+
"Bob Ross",
|
82 |
+
"Boris Vallejo",
|
83 |
+
"Brandon Woelfel",
|
84 |
+
"Brian Despain",
|
85 |
+
"Brian Kesinger",
|
86 |
+
"Brothers Hildebrandt",
|
87 |
+
"Bruce Nauman",
|
88 |
+
"Bruce Pennington",
|
89 |
+
"Bruno Taut",
|
90 |
+
"Camille Claudel",
|
91 |
+
"Camille Corot",
|
92 |
+
"Camille Pissarro",
|
93 |
+
"Canaletto",
|
94 |
+
"Candido Portinari",
|
95 |
+
"Caravaggio",
|
96 |
+
"Carl Holsoe",
|
97 |
+
"Carl Larsson",
|
98 |
+
"Carne Griffiths",
|
99 |
+
"Caspar David Friedrich",
|
100 |
+
"Chaim Soutine",
|
101 |
+
"Charles Blackman",
|
102 |
+
"Charles Demuth",
|
103 |
+
"Charles E. Burchfield",
|
104 |
+
"Charles Eames",
|
105 |
+
"Charles Rennie Mackintosh",
|
106 |
+
"Chesley Bonestell",
|
107 |
+
"Chiharu Shiota",
|
108 |
+
"Childe Hassam",
|
109 |
+
"Chris Foss",
|
110 |
+
"Chris Mars",
|
111 |
+
"Chris Menges",
|
112 |
+
"Chris Moore",
|
113 |
+
"Christopher Doyle",
|
114 |
+
"Cindy Sherman",
|
115 |
+
"Clarence Holbrook Carter",
|
116 |
+
"Claude Cahun",
|
117 |
+
"Claude Lorrain",
|
118 |
+
"Claude Monet",
|
119 |
+
"Clive Barker",
|
120 |
+
"Clive Madgwick",
|
121 |
+
"Clovis Trouille",
|
122 |
+
"Clyde Caldwell",
|
123 |
+
"Coby Whitmore",
|
124 |
+
"Codex Seraphinianus",
|
125 |
+
"Coles Phillips",
|
126 |
+
"Conrad Roset",
|
127 |
+
"Craig Mullins",
|
128 |
+
"Cuno Amiet",
|
129 |
+
"Dale Chihuly",
|
130 |
+
"Damien Hirst",
|
131 |
+
"Dan Flavin",
|
132 |
+
"Dan Mumford",
|
133 |
+
"Daniel Gerhartz",
|
134 |
+
"Daniel Merriam",
|
135 |
+
"Daniel Ridgway Knight",
|
136 |
+
"Dave Gibbons",
|
137 |
+
"Dave McKean",
|
138 |
+
"David Alfaro Siqueiros",
|
139 |
+
"David B. Mattingly",
|
140 |
+
"David Burliuk",
|
141 |
+
"David Hockney",
|
142 |
+
"David Park",
|
143 |
+
"Dean Ellis",
|
144 |
+
"Dennis Stock",
|
145 |
+
"Di Cavalcanti",
|
146 |
+
"Diane Arbus",
|
147 |
+
"Diego Velazquez",
|
148 |
+
"Dion Beebe",
|
149 |
+
"Don Bluth",
|
150 |
+
"Don Maitz",
|
151 |
+
"Donato Giancola",
|
152 |
+
"Dora Maar",
|
153 |
+
"Dorothea Lange",
|
154 |
+
"Dorothea Tanning",
|
155 |
+
"Dorothy Lathrop",
|
156 |
+
"Doug Chiang",
|
157 |
+
"Dustin Nguyen",
|
158 |
+
"E.H. Shepard",
|
159 |
+
"Earl Norem",
|
160 |
+
"Ed Binkley",
|
161 |
+
"Ed Emshwiller",
|
162 |
+
"Ed Mell",
|
163 |
+
"Edgar Degas",
|
164 |
+
"Edmund Leighton",
|
165 |
+
"\u00c9douard Manet",
|
166 |
+
"Edvard Munch",
|
167 |
+
"Edward Weston",
|
168 |
+
"Edwin Austen Abbey",
|
169 |
+
"Edward Hopper",
|
170 |
+
"Egon Schiele",
|
171 |
+
"Eikoh Hosoe",
|
172 |
+
"El Greco",
|
173 |
+
"Elaine de Kooning",
|
174 |
+
"Ellen Jewett",
|
175 |
+
"Elliott Erwitt",
|
176 |
+
"Elsa Beskow",
|
177 |
+
"Emil Melmoth",
|
178 |
+
"Emil Nolde",
|
179 |
+
"Emily Carr",
|
180 |
+
"Emmanuel Lubezki",
|
181 |
+
"Enki Bilal",
|
182 |
+
"Eric Gill",
|
183 |
+
"Eric Lacombe",
|
184 |
+
"Erich Heckel",
|
185 |
+
"Erich Ludwig Kirchner",
|
186 |
+
"Ernst Fuchs",
|
187 |
+
"Ernst Haeckel",
|
188 |
+
"Esao Andrews",
|
189 |
+
"Eug\u00e8ne Delacroix",
|
190 |
+
"Eva Hesse",
|
191 |
+
"Evelyn De Morgan",
|
192 |
+
"Eyvind Earle",
|
193 |
+
"Fairfield Porter",
|
194 |
+
"Farel Dalrymple",
|
195 |
+
"Fernand L\u00e9ger",
|
196 |
+
"Fernando Botero",
|
197 |
+
"Filippo Lippi",
|
198 |
+
"Francis Bacon",
|
199 |
+
"Francis Picabia",
|
200 |
+
"Francisco Goya",
|
201 |
+
"Frank Auerbach",
|
202 |
+
"Frank Frazetta",
|
203 |
+
"Frank Lloyd Wright",
|
204 |
+
"Frank Miller",
|
205 |
+
"Frank Schoonover",
|
206 |
+
"Franklin Booth",
|
207 |
+
"Franz Kline",
|
208 |
+
"Franz Marc",
|
209 |
+
"Franz Sedlacek",
|
210 |
+
"Franz Xaver Winterhalter",
|
211 |
+
"Fred Tomaselli",
|
212 |
+
"Frederick Lord Leighton",
|
213 |
+
"Frida Kahlo",
|
214 |
+
"Friedensreich Regentag Dunkelbunt Hundertwasser",
|
215 |
+
"Frits Van den Berghe",
|
216 |
+
"F\u00e9lix Vallotton",
|
217 |
+
"Gabriel Pacheco",
|
218 |
+
"Garry Trudeau",
|
219 |
+
"Gary Larson",
|
220 |
+
"Gaston Bussiere",
|
221 |
+
"Gediminas Pranckevicius",
|
222 |
+
"Geof Darrow",
|
223 |
+
"George Cruikshank",
|
224 |
+
"George Frederic Watts",
|
225 |
+
"George Grosz",
|
226 |
+
"George Inness",
|
227 |
+
"George Luks",
|
228 |
+
"Georges Rouault",
|
229 |
+
"Georges Seurat",
|
230 |
+
"Georgia O'Keeffe",
|
231 |
+
"Gerald Brom",
|
232 |
+
"Gerhard Munthe",
|
233 |
+
"Gerhard Richter",
|
234 |
+
"Gertrude Abercrombie",
|
235 |
+
"Giacomo Balla",
|
236 |
+
"Giorgio de Chirico",
|
237 |
+
"Giuseppe Arcimboldo",
|
238 |
+
"Glenn Fabry",
|
239 |
+
"Go Nagai",
|
240 |
+
"Gottfried Helnwein",
|
241 |
+
"Graciela Iturbide",
|
242 |
+
"Grandma Moses",
|
243 |
+
"Greg Hildebrandt",
|
244 |
+
"Greg Rutkowski",
|
245 |
+
"Gregory Crewdson",
|
246 |
+
"Grzegorz Domaradzki",
|
247 |
+
"Guido Borelli da Caluso",
|
248 |
+
"Guillermo del Toro",
|
249 |
+
"Gustav Klimt",
|
250 |
+
"Gustav Vigeland",
|
251 |
+
"Gustave Caillebotte",
|
252 |
+
"Gustave Courbet",
|
253 |
+
"Gustave Dore",
|
254 |
+
"Gustave Moreau",
|
255 |
+
"H. R. Giger",
|
256 |
+
"Hal Foster",
|
257 |
+
"Hannah H\u00f6ch",
|
258 |
+
"Hans Baldung",
|
259 |
+
"Hans Bellmer",
|
260 |
+
"Harold Elliott",
|
261 |
+
"Harriet Backer",
|
262 |
+
"Harry Clarke",
|
263 |
+
"Harry Gruyaert",
|
264 |
+
"Heinrich Kley",
|
265 |
+
"Hendrik Kerstens",
|
266 |
+
"Henri Harpignies",
|
267 |
+
"Henri Matisse",
|
268 |
+
"Henri Rousseau",
|
269 |
+
"Henri de Toulouse-Lautrec",
|
270 |
+
"Henri-Edmond Cross",
|
271 |
+
"Henry Fuseli",
|
272 |
+
"Henry Ossawa Tanner",
|
273 |
+
"Herg\u00e9",
|
274 |
+
"Hieronymus Bosch",
|
275 |
+
"Hilma af Klint",
|
276 |
+
"Hirohiko Araki",
|
277 |
+
"Hiromu Arakawa",
|
278 |
+
"Hiroshi Nagai",
|
279 |
+
"Hiroshi Yoshida",
|
280 |
+
"Hokusai",
|
281 |
+
"Honor\u00e9 Daumier",
|
282 |
+
"Hope Gangloff",
|
283 |
+
"Howard Finster",
|
284 |
+
"Howard Hodgkin",
|
285 |
+
"Hubert Robert",
|
286 |
+
"Hugh Ferriss",
|
287 |
+
"Hugh Kretschmer",
|
288 |
+
"Hundertwasser",
|
289 |
+
"Ian McQue",
|
290 |
+
"Ian Miller",
|
291 |
+
"Igor Morski",
|
292 |
+
"Ilkka Uimonen",
|
293 |
+
"Ilya Repin",
|
294 |
+
"Irma Stern",
|
295 |
+
"Isaac Levitan",
|
296 |
+
"Isamu Noguchi",
|
297 |
+
"Ivan Aivazovsky",
|
298 |
+
"Ivan Albright",
|
299 |
+
"Ivan Bilibin",
|
300 |
+
"Ivan Generalic",
|
301 |
+
"Ivan Shishkin",
|
302 |
+
"J. J. Grandville",
|
303 |
+
"J.C. Leyendecker",
|
304 |
+
"J.M.W. Turner",
|
305 |
+
"Jacek Yerka",
|
306 |
+
"Jack Butler Yeats",
|
307 |
+
"Jack Davis",
|
308 |
+
"Jack Gaughan",
|
309 |
+
"Jack Kirby",
|
310 |
+
"Jackson Pollock",
|
311 |
+
"Jacob Lawrence",
|
312 |
+
"Jacob Riis",
|
313 |
+
"Jacques-Laurent Agasse",
|
314 |
+
"Jakub Rozalski",
|
315 |
+
"James Abbott McNeill Whistler",
|
316 |
+
"James C. Christensen",
|
317 |
+
"James Ensor",
|
318 |
+
"James Jean",
|
319 |
+
"James Turrell",
|
320 |
+
"Jamie Hewlett",
|
321 |
+
"Jan van Goyen",
|
322 |
+
"Jaroslaw Jasnikowski",
|
323 |
+
"Jasmine Becket-Griffith",
|
324 |
+
"Jason Edmiston",
|
325 |
+
"Jason Limon",
|
326 |
+
"Jean Arp",
|
327 |
+
"Jean Delville",
|
328 |
+
"Jean Giraud (Moebius)",
|
329 |
+
"Jean Leon Gerome",
|
330 |
+
"Jean Metzinger",
|
331 |
+
"Jean-Auguste-Dominique Ingres",
|
332 |
+
"Jean-Baptiste Carpeaux",
|
333 |
+
"Jean-Baptiste-Sim\u00e9on Chardin",
|
334 |
+
"Jean-Honore Fragonard",
|
335 |
+
"Jean-Michel Basquiat",
|
336 |
+
"Jean-Pierre Vasarely (Yvaral)",
|
337 |
+
"Jeff Easley",
|
338 |
+
"Jeff Koons",
|
339 |
+
"Jeff Lemire",
|
340 |
+
"Jeffrey Catherine Jones",
|
341 |
+
"Jeffrey Smith",
|
342 |
+
"Jeffrey T. Larson",
|
343 |
+
"Jeremy Geddes",
|
344 |
+
"Jeremy Lipking",
|
345 |
+
"Jeremy Mann",
|
346 |
+
"Jesper Ejsing",
|
347 |
+
"Jim Burns",
|
348 |
+
"Jim Fitzpatrick",
|
349 |
+
"Jim Lee",
|
350 |
+
"Jim Steranko",
|
351 |
+
"Jithesh",
|
352 |
+
"Joan Mir\u00f3",
|
353 |
+
"Joaquin Sorolla",
|
354 |
+
"Johan Christian Dahl",
|
355 |
+
"Johannes Vermeer",
|
356 |
+
"Johfra Bosschart",
|
357 |
+
"John Atkinson Grimshaw",
|
358 |
+
"John Bauer",
|
359 |
+
"John Berkey",
|
360 |
+
"John Blanche",
|
361 |
+
"John Carpenter",
|
362 |
+
"John Constable",
|
363 |
+
"John Duncan",
|
364 |
+
"John Frederick Kensett",
|
365 |
+
"John Harris",
|
366 |
+
"John Hoyland",
|
367 |
+
"John James Audubon",
|
368 |
+
"John Kenn Mortensen",
|
369 |
+
"John Kricfalusi",
|
370 |
+
"John Martin",
|
371 |
+
"John Perceval",
|
372 |
+
"John Philip Falter",
|
373 |
+
"John Romita Jr",
|
374 |
+
"John Singer Sargent",
|
375 |
+
"John Stephens",
|
376 |
+
"John William Waterhouse",
|
377 |
+
"Jonas Bendiksen",
|
378 |
+
"Josan Gonzalez",
|
379 |
+
"Joseph Cornell",
|
380 |
+
"Joseph Ducreux",
|
381 |
+
"Joseph Stella",
|
382 |
+
"Josephine Wall",
|
383 |
+
"Jules Bastien-Lepage",
|
384 |
+
"Jules Feiffer",
|
385 |
+
"Jules Pascin",
|
386 |
+
"Junji Ito",
|
387 |
+
"Justin Gerard",
|
388 |
+
"Kaethe Butcher",
|
389 |
+
"Kaja Foglio",
|
390 |
+
"Karel Thole",
|
391 |
+
"Karl Blossfeldt",
|
392 |
+
"Karl Schmidt-Rottluff",
|
393 |
+
"Karol Bak",
|
394 |
+
"Kate Greenaway",
|
395 |
+
"Kathe Kollwitz",
|
396 |
+
"Katsuhiro Otomo",
|
397 |
+
"Katsushika Hokusai",
|
398 |
+
"Kay Nielsen",
|
399 |
+
"Kay Sage",
|
400 |
+
"Kazimir Malevich",
|
401 |
+
"Kehinde Wiley",
|
402 |
+
"Kelly Freas",
|
403 |
+
"Kelly McKernan",
|
404 |
+
"Ken Sugimori",
|
405 |
+
"Kenojuak Ashevak",
|
406 |
+
"Kent Monkman",
|
407 |
+
"Kentaro Miura",
|
408 |
+
"Kilian Eng",
|
409 |
+
"Kim Jung Gi",
|
410 |
+
"Kuang Hong",
|
411 |
+
"Larry Elmore",
|
412 |
+
"Lasar Segall",
|
413 |
+
"Laurel Burch",
|
414 |
+
"Laurie Greasley",
|
415 |
+
"Laurie Lipton",
|
416 |
+
"Lawren Harris",
|
417 |
+
"Le caravaggesque",
|
418 |
+
"Lee Krasner",
|
419 |
+
"Lee Madgwick",
|
420 |
+
"Leiji Matsumoto",
|
421 |
+
"Leon Bankst",
|
422 |
+
"Leonardo da Vinci",
|
423 |
+
"Leonid Afremov",
|
424 |
+
"Liam Wong",
|
425 |
+
"Liniers",
|
426 |
+
"Lisa Frank",
|
427 |
+
"Louis Comfort Tiffany",
|
428 |
+
"Louis Wain",
|
429 |
+
"Lovis Corinth",
|
430 |
+
"Luc Schuiten",
|
431 |
+
"Lucian Freud",
|
432 |
+
"Luis Royo",
|
433 |
+
"Lyonel Feininger",
|
434 |
+
"Lyubov Popova",
|
435 |
+
"M.C. Escher",
|
436 |
+
"M.W. Kaluta",
|
437 |
+
"Mab Graves",
|
438 |
+
"Makoto Shinkai",
|
439 |
+
"Malcolm Liepke",
|
440 |
+
"Man Ray",
|
441 |
+
"Marc Chagall",
|
442 |
+
"Mark Lague",
|
443 |
+
"Marc Simonetti",
|
444 |
+
"Marco Mazzoni",
|
445 |
+
"Marek Okon",
|
446 |
+
"Margaret Boden",
|
447 |
+
"Margaret Bruce Wells",
|
448 |
+
"Margaret Brundage",
|
449 |
+
"Margaret Garland",
|
450 |
+
"Margaret Geddes",
|
451 |
+
"Margaret Graeme Niven",
|
452 |
+
"Margaret Keane",
|
453 |
+
"Margaret Macdonald Mackintosh",
|
454 |
+
"Maria Prymachenko",
|
455 |
+
"Maria Sibylla Merian",
|
456 |
+
"Marianne von Werefkin",
|
457 |
+
"Mario Testino",
|
458 |
+
"Marjorie Strider",
|
459 |
+
"Mark Brooks",
|
460 |
+
"Mark Catesby",
|
461 |
+
"Mark Rothko",
|
462 |
+
"Mark Ryden",
|
463 |
+
"Marsden Hartley",
|
464 |
+
"Martin Parr",
|
465 |
+
"Martin Johnson Heade",
|
466 |
+
"Martiros Saryan",
|
467 |
+
"Mary Blair",
|
468 |
+
"Mary Cassatt",
|
469 |
+
"Masamune Shirow",
|
470 |
+
"Masashi Kishimoto",
|
471 |
+
"Mat Collishaw",
|
472 |
+
"Mati Klarwein",
|
473 |
+
"Matt Groening",
|
474 |
+
"Matthias Grunewald",
|
475 |
+
"Matti Suuronen",
|
476 |
+
"Maurice Sendak",
|
477 |
+
"Max Beckmann",
|
478 |
+
"Max Ernst",
|
479 |
+
"Max Pechstein",
|
480 |
+
"Max Weber",
|
481 |
+
"Maxfield Parrish",
|
482 |
+
"Meret Oppenheim",
|
483 |
+
"Michael Deforge",
|
484 |
+
"Michael Whelan",
|
485 |
+
"Michelangelo",
|
486 |
+
"Mike Mignola",
|
487 |
+
"Mikhail Vrubel",
|
488 |
+
"Miles Aldridge",
|
489 |
+
"Milton Avery",
|
490 |
+
"Milton Glaser",
|
491 |
+
"Moebius (Jean Giraud)",
|
492 |
+
"Mort Drucker",
|
493 |
+
"Nan Goldin",
|
494 |
+
"Nao Emoto",
|
495 |
+
"Naoto Hattori",
|
496 |
+
"Natalia Goncharova",
|
497 |
+
"Neil Welliver",
|
498 |
+
"Nele Zirnite",
|
499 |
+
"Nell Dorr",
|
500 |
+
"Nicholas Roerich",
|
501 |
+
"Nick Knight",
|
502 |
+
"Nikos Economopoulos",
|
503 |
+
"Nobuyoshi Araki",
|
504 |
+
"Noriyoshi Ohrai",
|
505 |
+
"Norman Rockwell",
|
506 |
+
"Nychos",
|
507 |
+
"Odd Nerdrum",
|
508 |
+
"Odilon Redon",
|
509 |
+
"Oliver Jeffers",
|
510 |
+
"Oskar Kokoschka",
|
511 |
+
"Oskar Schlemmer",
|
512 |
+
"Otto Dix",
|
513 |
+
"Otto Marseus van Schrieck",
|
514 |
+
"Pablo Picasso",
|
515 |
+
"Pascal Campion",
|
516 |
+
"Patrick Henry Bruce",
|
517 |
+
"Patrick Heron",
|
518 |
+
"Patrick Nagel",
|
519 |
+
"Patrick Woodroffe",
|
520 |
+
"Paul Cezanne",
|
521 |
+
"Paul Delvaux",
|
522 |
+
"Paul Gauguin",
|
523 |
+
"Paul Gustav Fischer",
|
524 |
+
"Paul Klee",
|
525 |
+
"Paul Rand",
|
526 |
+
"Paula Modersohn-Becker",
|
527 |
+
"Pendleton Ward",
|
528 |
+
"Peter Bagge",
|
529 |
+
"Peter Elson",
|
530 |
+
"Peter Gric",
|
531 |
+
"Peter Kemp",
|
532 |
+
"Peter Max",
|
533 |
+
"Peter Paul Rubens",
|
534 |
+
"Phil Foglio",
|
535 |
+
"Philip Guston",
|
536 |
+
"Philip Pearlstein",
|
537 |
+
"Philip-Lorca diCorcia",
|
538 |
+
"Pierre Bonnard",
|
539 |
+
"Pierre-Auguste Renoir",
|
540 |
+
"Piet Mondrian",
|
541 |
+
"Pieter Claesz",
|
542 |
+
"Platon",
|
543 |
+
"Quentin Blake",
|
544 |
+
"Rachel Ignotofsky",
|
545 |
+
"Rafal Olbinski",
|
546 |
+
"Ralph McQuarrie",
|
547 |
+
"Ralph Steadman",
|
548 |
+
"Ram\u00f3n Casas",
|
549 |
+
"Randolph Caldecott",
|
550 |
+
"Raphael Lacoste",
|
551 |
+
"Raphaelite",
|
552 |
+
"Ray Caesar",
|
553 |
+
"Ray Earnes",
|
554 |
+
"Raymond Briggs",
|
555 |
+
"Raymond Swanland",
|
556 |
+
"Rebeca Saray",
|
557 |
+
"Rebecca Guay",
|
558 |
+
"Reginald Marsh",
|
559 |
+
"Remedios Varo",
|
560 |
+
"Ren\u00e9 Magritte",
|
561 |
+
"Richard Corben",
|
562 |
+
"Richard Dadd",
|
563 |
+
"Richard Diebenkorn",
|
564 |
+
"Richard Doyle",
|
565 |
+
"Richard Scarry",
|
566 |
+
"Ridley Scott",
|
567 |
+
"Rineke Dijkstra",
|
568 |
+
"Rob Gonsalves",
|
569 |
+
"Rob Liefeld",
|
570 |
+
"Robert Bechtle",
|
571 |
+
"Robert Capa",
|
572 |
+
"Robert Crumb",
|
573 |
+
"Robert Delaunay",
|
574 |
+
"Robert McCall",
|
575 |
+
"Robert McGinnis",
|
576 |
+
"Robert Motherwell",
|
577 |
+
"Robert Rauschenberg",
|
578 |
+
"Robert Williams",
|
579 |
+
"Roberto Ferri",
|
580 |
+
"Roberto Matta",
|
581 |
+
"Rockwell Kent",
|
582 |
+
"Rodney Matthews",
|
583 |
+
"Rodrigo Prieto",
|
584 |
+
"Roger Dean",
|
585 |
+
"Romare Bearden",
|
586 |
+
"Romero Britto",
|
587 |
+
"Ron Walotsky",
|
588 |
+
"Rosa Bonheur",
|
589 |
+
"Roy Lichtenstein",
|
590 |
+
"Rudolf Hausner",
|
591 |
+
"Rufino Tamayo",
|
592 |
+
"Russ Mills",
|
593 |
+
"Ruth Bernhard",
|
594 |
+
"Ryan Hewett",
|
595 |
+
"Ryo Takemasa",
|
596 |
+
"Ryohei Hase",
|
597 |
+
"Sally Mann",
|
598 |
+
"Salvador Dali",
|
599 |
+
"Sam Bosma",
|
600 |
+
"Sam Francis",
|
601 |
+
"Sam Guay",
|
602 |
+
"Sam Toft",
|
603 |
+
"Santiago Caruso",
|
604 |
+
"Satoshi Kon",
|
605 |
+
"Sebastian Kr\u00fcger",
|
606 |
+
"Sebasti\u00e3o Salgado",
|
607 |
+
"Sergio Toppi",
|
608 |
+
"Shaun Tan",
|
609 |
+
"Shepard Fairey",
|
610 |
+
"Shiki",
|
611 |
+
"Shinji Aramaki",
|
612 |
+
"Shotaro Ishinomori",
|
613 |
+
"Sidney Nolan",
|
614 |
+
"Sidney Prior Hall",
|
615 |
+
"Simon Bisley",
|
616 |
+
"Simon St\u00e5lenhag",
|
617 |
+
"Simone Martini",
|
618 |
+
"Sir James Guthrie",
|
619 |
+
"Sir Max Beerbohm",
|
620 |
+
"Sonia Delaunay",
|
621 |
+
"Stanley Donwood",
|
622 |
+
"Stefan Gesell",
|
623 |
+
"Stephanie Law",
|
624 |
+
"Stephen Gammell",
|
625 |
+
"Steve Argyle",
|
626 |
+
"Steve Dillon",
|
627 |
+
"Steve Ditko",
|
628 |
+
"Steve McCurry",
|
629 |
+
"Storm Thorgerson",
|
630 |
+
"Stuart Davis",
|
631 |
+
"Syd Mead",
|
632 |
+
"Sylvain Chomet",
|
633 |
+
"Taiyo Matsumoto",
|
634 |
+
"Takashi Murakami",
|
635 |
+
"Takato Yamamoto",
|
636 |
+
"Takehiko Inoue",
|
637 |
+
"Taro Okamoto",
|
638 |
+
"Tarsila do Amaral",
|
639 |
+
"Tatsuro Kiuchi",
|
640 |
+
"Ted Nasmith",
|
641 |
+
"Terry Oakes",
|
642 |
+
"Tex Avery",
|
643 |
+
"Theodor Seuss Geisel",
|
644 |
+
"Thomas Cole",
|
645 |
+
"Thomas Gainsborough",
|
646 |
+
"Thomas Kinkade",
|
647 |
+
"Tibor Nagy",
|
648 |
+
"Tillie Walden",
|
649 |
+
"Tim Burton",
|
650 |
+
"Tim Doyle",
|
651 |
+
"Tim Hildebrandt",
|
652 |
+
"Tim White",
|
653 |
+
"Tivadar Csontvary Kosztka",
|
654 |
+
"Todd McFarlane",
|
655 |
+
"Tom Bagshaw",
|
656 |
+
"Tom Lovell",
|
657 |
+
"Tom Thomson",
|
658 |
+
"Tom Whalen",
|
659 |
+
"Tomasz Alen Kopera",
|
660 |
+
"Tomasz Jedruszek",
|
661 |
+
"Tomek Setowski",
|
662 |
+
"Tomer Hanuka",
|
663 |
+
"Tomi Ungerer",
|
664 |
+
"Tomioka Tessai",
|
665 |
+
"Tommaso Dolabella",
|
666 |
+
"Tommaso Masaccio",
|
667 |
+
"Tommaso Redi",
|
668 |
+
"Tomokazu Matsuyama",
|
669 |
+
"Tom\u00e0s Barcel\u00f3",
|
670 |
+
"Tony DiTerlizzi",
|
671 |
+
"Tove Jansson",
|
672 |
+
"Tsutomu Nihei",
|
673 |
+
"Ub Iwerks",
|
674 |
+
"Van Herpen",
|
675 |
+
"Victo Ngai",
|
676 |
+
"Victor Brauner",
|
677 |
+
"Victor Moscoso",
|
678 |
+
"Victor Ngai",
|
679 |
+
"Victor Vasarely",
|
680 |
+
"Viktor Vasnetsov",
|
681 |
+
"Vilhelm Hammershoi",
|
682 |
+
"Vilmos Zsigmond",
|
683 |
+
"Vincent van Gogh",
|
684 |
+
"Virgil Finlay",
|
685 |
+
"Walter Crane",
|
686 |
+
"Walt Disney",
|
687 |
+
"Wassily Kandinsky",
|
688 |
+
"Wayne Barlowe",
|
689 |
+
"Weegee",
|
690 |
+
"Wes Anderson",
|
691 |
+
"Will Simpson",
|
692 |
+
"Wifredo Lam",
|
693 |
+
"William Blake",
|
694 |
+
"William Gropper",
|
695 |
+
"William Henry Hunt",
|
696 |
+
"William Hogarth",
|
697 |
+
"William Morris",
|
698 |
+
"William S Burroughs",
|
699 |
+
"William Stout",
|
700 |
+
"William-Adolphe Bouguereau",
|
701 |
+
"Winslow Homer",
|
702 |
+
"Wong Kar-Wai",
|
703 |
+
"Yaacov Agam",
|
704 |
+
"Yayoi Kusama",
|
705 |
+
"Yoshitaka Amano",
|
706 |
+
"Yousuf Karsh",
|
707 |
+
"Yuumei",
|
708 |
+
"Yves Klein",
|
709 |
+
"Yves Tanguy",
|
710 |
+
"Zack Snyder",
|
711 |
+
"Zaha Hadid",
|
712 |
+
"Zdzislaw Beksinski"
|
713 |
+
]
|
data/background.json
ADDED
@@ -0,0 +1,270 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"Eye-level shot, centered subject, direct perspective",
|
3 |
+
"Eye-level shot, centered subject, natural daylight",
|
4 |
+
"Eye-level shot, central framing, natural lighting",
|
5 |
+
"Eye-level shot, direct perspective, clear focus",
|
6 |
+
"Eye-level shot, shallow focus, soft lighting",
|
7 |
+
"Eye-level shot, straight angle, centered subject",
|
8 |
+
"Eye-level shot, straight angle, medium shot",
|
9 |
+
"Natural daylight, eye-level shot, soft focus",
|
10 |
+
"Rule of thirds, eye-level shot, straight angle, soft lighting",
|
11 |
+
"Soft focus, shallow depth of field, natural lighting",
|
12 |
+
"Vertical orientation, Eye-level shot, Straight angle, Centered subject",
|
13 |
+
"center focus, eye-level shot, shallow depth of field",
|
14 |
+
"center framed, eye-level shot, balanced perspective",
|
15 |
+
"center-focused, eye-level angle, shallow depth of field",
|
16 |
+
"centered subject, close-up shot, straight angle, eye-level perspective",
|
17 |
+
"centered subject, eye-level angle, frontal perspective",
|
18 |
+
"centered subject, eye-level angle, neutral perspective",
|
19 |
+
"centered subject, eye-level angle, tight framing",
|
20 |
+
"centered subject, eye-level shot, balanced framing",
|
21 |
+
"centered subject, eye-level shot, direct angle",
|
22 |
+
"centered subject, eye-level shot, direct angle, full body view",
|
23 |
+
"centered subject, eye-level shot, direct perspective",
|
24 |
+
"centered subject, eye-level shot, medium close-up",
|
25 |
+
"centered subject, eye-level shot, natural light",
|
26 |
+
"centered subject, eye-level shot, neutral perspective",
|
27 |
+
"centered subject, eye-level shot, portrait orientation",
|
28 |
+
"centered subject, eye-level shot, shallow depth of field",
|
29 |
+
"centered subject, eye-level shot, shallow depth of field, natural lighting",
|
30 |
+
"centered subject, eye-level shot, shallow depth-of-field",
|
31 |
+
"centered subject, eye-level shot, soft focus background",
|
32 |
+
"centered subject, eye-level shot, soft lighting",
|
33 |
+
"centered subject, eye-level shot, straight angle",
|
34 |
+
"centered subject, eye-level shot, straight angle, clear perspective",
|
35 |
+
"centered subject, eye-level shot, straight-on angle",
|
36 |
+
"centered subject, eye-level shot, straight-on angle, shallow depth of field",
|
37 |
+
"centered subject, eye-level shot, straightforward angle, natural lighting",
|
38 |
+
"centered subject, low camera angle, shallow depth of field",
|
39 |
+
"centered subject, low camera angle, studio lighting",
|
40 |
+
"centered subject, medium close-up, frontal angle, eye-level perspective",
|
41 |
+
"centered subject, medium shot, eye-level angle",
|
42 |
+
"centered subject, medium shot, natural light, shallow depth of field",
|
43 |
+
"centered subject, medium shot, straight angle",
|
44 |
+
"centered subject, natural lighting, eye-level angle",
|
45 |
+
"centered subject, natural lighting, eye-level shot",
|
46 |
+
"centered subject, shallow depth of field, eye-level shot",
|
47 |
+
"centered subject, shallow depth of field, natural light",
|
48 |
+
"centered subject, straight angle, eye-level perspective",
|
49 |
+
"centered subject, straight angle, neutral perspective",
|
50 |
+
"centered subject, straight-on angle, eye-level perspective",
|
51 |
+
"centered subject, straight-on angle, full-body shot",
|
52 |
+
"close-up shot, angled perspective, off-center framing",
|
53 |
+
"close-up shot, centered subject, eye-level angle",
|
54 |
+
"close-up shot, direct angle, eye-level perspective",
|
55 |
+
"close-up shot, direct angle, high perspective",
|
56 |
+
"close-up shot, direct angle, selfie perspective",
|
57 |
+
"close-up shot, eye-level angle, candid perspective",
|
58 |
+
"close-up shot, eye-level angle, center framed, natural daylight",
|
59 |
+
"close-up shot, eye-level angle, centered framing",
|
60 |
+
"close-up shot, eye-level angle, centered subject",
|
61 |
+
"close-up shot, eye-level angle, centered subject, natural lighting",
|
62 |
+
"close-up shot, eye-level angle, centered subject, portrait orientation",
|
63 |
+
"close-up shot, eye-level angle, centered subject, shallow depth of field",
|
64 |
+
"close-up shot, eye-level angle, centered subject, soft lighting",
|
65 |
+
"close-up shot, eye-level angle, centered subject, soft natural lighting",
|
66 |
+
"close-up shot, eye-level angle, central framing",
|
67 |
+
"close-up shot, eye-level angle, direct perspective",
|
68 |
+
"close-up shot, eye-level angle, direct perspective, centered framing",
|
69 |
+
"close-up shot, eye-level angle, direct perspective, soft lighting",
|
70 |
+
"close-up shot, eye-level angle, frontal perspective",
|
71 |
+
"close-up shot, eye-level angle, natural lighting",
|
72 |
+
"close-up shot, eye-level angle, outdoor lighting",
|
73 |
+
"close-up shot, eye-level angle, shallow depth of field",
|
74 |
+
"close-up shot, eye-level angle, soft lighting",
|
75 |
+
"close-up shot, eye-level angle, soft lighting, centered framing",
|
76 |
+
"close-up shot, eye-level angle, studio lighting",
|
77 |
+
"close-up shot, eye-level camera, direct angle, centered subject",
|
78 |
+
"close-up shot, front view, eye-level angle",
|
79 |
+
"close-up shot, front-facing camera, high angle",
|
80 |
+
"close-up shot, high angle, centered subject",
|
81 |
+
"close-up shot, high angle, direct perspective",
|
82 |
+
"close-up shot, high angle, direct perspective, selfie",
|
83 |
+
"close-up shot, high resolution, natural light, shallow depth of field",
|
84 |
+
"close-up shot, low angle, direct perspective",
|
85 |
+
"close-up shot, low angle, direct perspective, shallow depth of field",
|
86 |
+
"close-up shot, low angle, dramatic lighting",
|
87 |
+
"close-up shot, low camera angle, direct perspective",
|
88 |
+
"close-up shot, low camera angle, dynamic perspective",
|
89 |
+
"close-up shot, low camera angle, eye-level perspective, outdoor lighting",
|
90 |
+
"close-up shot, low camera angle, natural light",
|
91 |
+
"close-up shot, low camera angle, shallow depth of field",
|
92 |
+
"close-up shot, natural lighting, direct angle, eye-level perspective",
|
93 |
+
"close-up shot, natural lighting, shallow depth of field, three-quarter angle",
|
94 |
+
"close-up shot, off-center framing, natural light",
|
95 |
+
"close-up shot, selfie angle, natural light",
|
96 |
+
"close-up shot, selfie perspective, eye-level angle",
|
97 |
+
"close-up shot, selfie perspective, natural lighting",
|
98 |
+
"close-up shot, shallow depth of field, eye-level angle",
|
99 |
+
"close-up shot, shallow focus, eye-level angle",
|
100 |
+
"close-up shot, slight high angle, direct perspective",
|
101 |
+
"close-up shot, slightly angled view, eye-level perspective",
|
102 |
+
"close-up shot, soft lighting, shallow depth of field",
|
103 |
+
"close-up shot, straight angle, centered subject",
|
104 |
+
"close-up shot, straight angle, eye-level perspective",
|
105 |
+
"close-up shot, three-quarter view, shallow depth of field",
|
106 |
+
"close-up shot, warm lighting, direct angle",
|
107 |
+
"close-up, eye level, centered subject",
|
108 |
+
"close-up, eye-level shot, frontal perspective",
|
109 |
+
"close-up, eye-level, centered, shallow depth of field",
|
110 |
+
"close-up, eye-level, central framing",
|
111 |
+
"close-up, eye-level, frontal view",
|
112 |
+
"close-up, eye-level, shallow depth of field",
|
113 |
+
"close-up, eye-level, shallow focus",
|
114 |
+
"close-up, eye-level, soft light",
|
115 |
+
"close-up, eye-level, soft lighting",
|
116 |
+
"close-up, eye-level, studio lighting",
|
117 |
+
"close-up, selfie angle, eye-level perspective",
|
118 |
+
"close-up, selfie angle, high perspective",
|
119 |
+
"daylight shot, eye-level angle, centered framing",
|
120 |
+
"direct lighting, eye-level shot, centered subject",
|
121 |
+
"direct view, medium shot, neutral angle",
|
122 |
+
"eye-level shot, balanced framing, centered subject",
|
123 |
+
"eye-level shot, center frame, shallow depth of field",
|
124 |
+
"eye-level shot, center framed, clear focus",
|
125 |
+
"eye-level shot, center framed, natural light",
|
126 |
+
"eye-level shot, center framed, natural light, shallow depth of field, urban setting",
|
127 |
+
"eye-level shot, center framed, natural lighting",
|
128 |
+
"eye-level shot, center framing, soft lighting, shallow depth of field",
|
129 |
+
"eye-level shot, center-framed subject, soft lighting",
|
130 |
+
"eye-level shot, center-framed subject, soft natural lighting",
|
131 |
+
"eye-level shot, center-framed, natural daylight",
|
132 |
+
"eye-level shot, center-framed, natural lighting",
|
133 |
+
"eye-level shot, centered composition, natural light",
|
134 |
+
"eye-level shot, centered framing, natural light",
|
135 |
+
"eye-level shot, centered framing, shallow depth of field",
|
136 |
+
"eye-level shot, centered framing, shallow focus",
|
137 |
+
"eye-level shot, centered subject, direct gaze",
|
138 |
+
"eye-level shot, centered subject, direct perspective",
|
139 |
+
"eye-level shot, centered subject, natural daylight",
|
140 |
+
"eye-level shot, centered subject, natural light",
|
141 |
+
"eye-level shot, centered subject, natural light, shallow depth of field",
|
142 |
+
"eye-level shot, centered subject, natural lighting",
|
143 |
+
"eye-level shot, centered subject, natural lighting, shallow depth of field",
|
144 |
+
"eye-level shot, centered subject, neutral perspective",
|
145 |
+
"eye-level shot, centered subject, portrait orientation",
|
146 |
+
"eye-level shot, centered subject, shallow depth of field",
|
147 |
+
"eye-level shot, centered subject, shallow depth of field, natural lighting",
|
148 |
+
"eye-level shot, centered subject, shallow depth of field, soft lighting",
|
149 |
+
"eye-level shot, centered subject, soft background",
|
150 |
+
"eye-level shot, centered subject, soft focus",
|
151 |
+
"eye-level shot, centered subject, soft focus, natural lighting",
|
152 |
+
"eye-level shot, centered subject, soft lighting",
|
153 |
+
"eye-level shot, centered subject, straight angle",
|
154 |
+
"eye-level shot, centered subject, vivid colors",
|
155 |
+
"eye-level shot, centered subjects, shallow depth of field",
|
156 |
+
"eye-level shot, centered subjects, soft lighting",
|
157 |
+
"eye-level shot, central framing, natural lighting",
|
158 |
+
"eye-level shot, central framing, soft lighting",
|
159 |
+
"eye-level shot, central subject focus, natural lighting",
|
160 |
+
"eye-level shot, close-up framing, natural lighting",
|
161 |
+
"eye-level shot, close-up, soft lighting, centered subject",
|
162 |
+
"eye-level shot, direct angle, centered subject",
|
163 |
+
"eye-level shot, direct perspective, balanced framing",
|
164 |
+
"eye-level shot, medium close-up, centred subject",
|
165 |
+
"eye-level shot, medium close-up, direct perspective",
|
166 |
+
"eye-level shot, medium close-up, soft focus",
|
167 |
+
"eye-level shot, medium close-up, soft natural lighting",
|
168 |
+
"eye-level shot, medium shot, natural lighting",
|
169 |
+
"eye-level shot, natural lighting, center-framed subject",
|
170 |
+
"eye-level shot, natural lighting, centered subject",
|
171 |
+
"eye-level shot, natural lighting, clear focus",
|
172 |
+
"eye-level shot, natural lighting, shallow depth of field",
|
173 |
+
"eye-level shot, natural lighting, shallow depth of field, three-quarter view, centered subject",
|
174 |
+
"eye-level shot, natural lighting, soft focus background",
|
175 |
+
"eye-level shot, off-center framing, soft lighting",
|
176 |
+
"eye-level shot, portrait orientation, shallow depth of field",
|
177 |
+
"eye-level shot, portrait orientation, soft lighting",
|
178 |
+
"eye-level shot, shallow depth of field, blurred background",
|
179 |
+
"eye-level shot, shallow depth of field, natural lighting",
|
180 |
+
"eye-level shot, shallow depth of field, natural lighting, indoor setting",
|
181 |
+
"eye-level shot, shallow depth of field, soft lighting",
|
182 |
+
"eye-level shot, soft natural lighting, shallow depth of field",
|
183 |
+
"eye-level shot, straight angle, balanced framing",
|
184 |
+
"eye-level shot, straight angle, balanced symmetry, foreground focus",
|
185 |
+
"eye-level shot, straight angle, centered subject",
|
186 |
+
"eye-level shot, straight-on angle, centered subject",
|
187 |
+
"eye-level shot, straight-on angle, centered subject, shallow depth of field",
|
188 |
+
"eye-level shot, straight-on angle, shallow depth of field",
|
189 |
+
"eye-level shot, three-quarter view, natural lighting",
|
190 |
+
"eye-level view, natural daylight, shallow depth of field",
|
191 |
+
"frontal shot, eye-level angle, centered subject",
|
192 |
+
"frontal view, eye-level angle, centered subject",
|
193 |
+
"frontal view, eye-level angle, natural lighting",
|
194 |
+
"frontal view, eye-level angle, portrait orientation",
|
195 |
+
"frontal view, eye-level shot, center-framed",
|
196 |
+
"frontal view, eye-level shot, centered subject",
|
197 |
+
"frontal view, eye-level shot, centered subjects, close-up",
|
198 |
+
"frontal view, eye-level shot, soft focus",
|
199 |
+
"frontal view, eye-level shot, symmetrical stance",
|
200 |
+
"frontal view, eye-level, centered subject",
|
201 |
+
"frontal view, eye-level, centered subjects",
|
202 |
+
"frontal view, waist-up shot, soft lighting",
|
203 |
+
"high angle, close-up shot, central framing, soft lighting",
|
204 |
+
"high saturation, direct sunlight, eye-level shot",
|
205 |
+
"indoor lighting, eye-level shot, straight angle",
|
206 |
+
"indoor lighting, mirror reflection, eye-level shot, shallow depth of field",
|
207 |
+
"indoor lighting, selfie angle, close-up shot",
|
208 |
+
"indoor setting, eye-level shot, straight angle, centered subject, natural lighting",
|
209 |
+
"indoors, close-up, selfie perspective",
|
210 |
+
"low angle shot, sharp focus, bokeh effect",
|
211 |
+
"low angle, close-up, shallow depth of field",
|
212 |
+
"low angle, wide shot, diagonal lines",
|
213 |
+
"low angle, wide shot, dynamic perspective",
|
214 |
+
"medium close-up, eye-level angle, centered subject",
|
215 |
+
"medium close-up, eye-level shot, clear focus",
|
216 |
+
"medium shot, eye-level angle, centered subject, soft focus",
|
217 |
+
"medium shot, eye-level angle, natural lighting",
|
218 |
+
"medium shot, eye-level angle, soft focus background",
|
219 |
+
"medium shot, eye-level, direct perspective",
|
220 |
+
"medium shot, indoor lighting, eye-level angle, shallow depth of field",
|
221 |
+
"medium shot, off-center framing, shallow depth of field, natural light",
|
222 |
+
"mid-shot, street level, natural light, shallow depth of field",
|
223 |
+
"natural light, centered subject, shallow depth of field",
|
224 |
+
"natural light, close-up shot, eye-level angle",
|
225 |
+
"natural light, eye-level shot, shallow depth of field",
|
226 |
+
"natural lighting, close-up shot, eye-level angle",
|
227 |
+
"natural lighting, eye level shot, soft focus background",
|
228 |
+
"natural lighting, eye-level shot, centered subject",
|
229 |
+
"natural lighting, eye-level shot, medium shot",
|
230 |
+
"natural lighting, eye-level shot, soft focus background",
|
231 |
+
"natural lighting, medium close-up, eye-level angle",
|
232 |
+
"natural lighting, medium shot, shallow depth of field",
|
233 |
+
"natural lighting, mid shot, soft focus",
|
234 |
+
"natural lighting, shallow depth of field, eye-level angle, centered subject",
|
235 |
+
"natural lighting, shallow depth of field, eye-level shot",
|
236 |
+
"natural lighting, soft focus, eye-level shot",
|
237 |
+
"natural lighting, soft shadows, close-up shot, waist-up framing, eye-level angle, direct perspective",
|
238 |
+
"natural lighting, waist-up shot, blurred foreground",
|
239 |
+
"night shot, street lighting, sharp focus",
|
240 |
+
"outdoor lighting, close-up shot, low camera angle",
|
241 |
+
"outdoor lighting, eye-level shot, direct perspective",
|
242 |
+
"outdoor lighting, eye-level shot, natural background",
|
243 |
+
"outdoor lighting, eye-level shot, shallow depth of field, central framing",
|
244 |
+
"outdoor lighting, rear view, low angle, centered subject",
|
245 |
+
"outdoor shot, eye-level angle, centered framing",
|
246 |
+
"outdoor shot, eye-level angle, soft lighting",
|
247 |
+
"portrait orientation, eye-level shot, centered subject, natural lighting",
|
248 |
+
"portrait orientation, eye-level shot, close-up, frontal perspective",
|
249 |
+
"shallow depth of field, eye-level shot, background blur, centered subject",
|
250 |
+
"shallow depth of field, eye-level shot, natural lighting",
|
251 |
+
"shallow depth of field, eye-level shot, soft focus background",
|
252 |
+
"shallow depth of field, eye-level shot, soft natural lighting",
|
253 |
+
"shallow focus, eye-level shot, centered subject",
|
254 |
+
"shallow focus, eye-level shot, diagonal orientation",
|
255 |
+
"sharp focus, eye-level shot, direct perspective",
|
256 |
+
"soft backlighting, shallow depth of field, eye-level angle",
|
257 |
+
"soft backlighting, shallow depth of field, eye-level shot",
|
258 |
+
"soft lighting, eye-level shot, center-framed",
|
259 |
+
"soft lighting, indoor setting, eye-level shot, three-quarter framing",
|
260 |
+
"soft lighting, shallow depth of field, eye-level shot",
|
261 |
+
"soft lighting, shallow depth of field, three-quarter rear view",
|
262 |
+
"soft lighting, shallow focus, three-quarter shot",
|
263 |
+
"straight shot, medium close-up, eye-level perspective",
|
264 |
+
"street-level shot, medium close-up, eye-level angle",
|
265 |
+
"tight framing, eye-level angle, soft lighting",
|
266 |
+
"vertical orientation, eye-level shot, direct perspective",
|
267 |
+
"vertical orientation, eye-level shot, straightforward perspective",
|
268 |
+
"vertical orientation, natural lighting, eye-level shot",
|
269 |
+
"warm lighting, close-up shot, low angle"
|
270 |
+
]
|
data/body_types.json
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"pretty",
|
3 |
+
"chubby",
|
4 |
+
"midweight",
|
5 |
+
"overweight",
|
6 |
+
"fat",
|
7 |
+
"flabby",
|
8 |
+
"buxom",
|
9 |
+
"voluptuous",
|
10 |
+
"hefty",
|
11 |
+
"pudgy",
|
12 |
+
"plump",
|
13 |
+
"obese",
|
14 |
+
"morbidly obese",
|
15 |
+
"stout",
|
16 |
+
"rotund",
|
17 |
+
"thick-bodied",
|
18 |
+
"thicc",
|
19 |
+
"thick",
|
20 |
+
"beefy",
|
21 |
+
"portly",
|
22 |
+
"tubby",
|
23 |
+
"overweight",
|
24 |
+
"(slightly overweight)",
|
25 |
+
"buff",
|
26 |
+
"burly",
|
27 |
+
"fit",
|
28 |
+
"well-built",
|
29 |
+
"well-endowed",
|
30 |
+
"muscular",
|
31 |
+
"stocky",
|
32 |
+
"big-boned",
|
33 |
+
"curvy",
|
34 |
+
"flabby",
|
35 |
+
"flyweight",
|
36 |
+
"skinny",
|
37 |
+
"too skinny",
|
38 |
+
"anorexic",
|
39 |
+
"not skinny",
|
40 |
+
"slender",
|
41 |
+
"lanky",
|
42 |
+
"slim",
|
43 |
+
"slight"
|
44 |
+
]
|
data/clothing.json
ADDED
@@ -0,0 +1,344 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"white crop top, denim shorts,silver bracelet,white texture,denim texture",
|
3 |
+
"white top, sleeveless, button-up, white bottoms, ribbed texture",
|
4 |
+
"white crop top, blue jeans, silver belt, textured fabric, denim texture",
|
5 |
+
"white tank top, black pants, pink and blue goalie pads, black belt, white skates",
|
6 |
+
"black long-sleeve dress, fishnet stockings",
|
7 |
+
"black bikini top, black bikini bottom, hoop earrings",
|
8 |
+
"white towel, white head wrap",
|
9 |
+
"gray crop top, black skirt, ribbed texture, v-neckline",
|
10 |
+
"black bodysuit, sheer texture, light wash jeans, golden bangles",
|
11 |
+
"pink dress, spaghetti straps, form-fitting, floor-length",
|
12 |
+
"black sports bra, black leggings, textured fabric, small white logo",
|
13 |
+
"black bikini, knit texture, gold accessories, aviator sunglasses",
|
14 |
+
"patterned crop top, green leather pants, silver necklaces, red bracelet, hoop earrings",
|
15 |
+
"black bikini top, striped pants, beige textures, open white shirt",
|
16 |
+
"pink dress, orange sash, gold heels, floral headpiece",
|
17 |
+
"pastel pink tank top, blue ripped jeans, black platform heels, neutral shoulder bag",
|
18 |
+
"white sleeveless top, ribbed texture, high-cut white bottoms",
|
19 |
+
"black dress, plunging neckline, satin texture, brown handbag, chain strap, diamond necklace, wristwatch, silver bracelet",
|
20 |
+
"brown crop top, brown skirt, smooth texture",
|
21 |
+
"black sports bra, black leggings, white sneakers, textured fabric",
|
22 |
+
"blue dress, bodycon fit, sleeveless, zipper detail, V-neckline, subtle sheen",
|
23 |
+
"beige tank top, black denim shorts, smooth fabric, ripped texture",
|
24 |
+
"black tube top, gold necklace, gold arm cuff, red headwrap",
|
25 |
+
"black jumpsuit, zipper detail, form-fitting, long-sleeved",
|
26 |
+
"white crop top, blue jeans, silver necklace",
|
27 |
+
"light blue crop top, ribbed texture, long sleeves, denim jeans",
|
28 |
+
"black swimsuit, plunging neckline, sleeveless",
|
29 |
+
"blue dress, strap sleeves, high slit, textured fabric, hoop earrings, wristwatch, bracelet",
|
30 |
+
"black sleeveless top, black leather pants, gold necklace",
|
31 |
+
"black tank top, chain belt, black shorts, patterned boots",
|
32 |
+
"pink hoodie, pink shorts, textured fabric",
|
33 |
+
"black bikini top, denim shorts, frayed hems",
|
34 |
+
"blue bikini, tie-up detail, vibrant prints, double-strap top, high-cut bottoms, textured fabric",
|
35 |
+
"tan crop top, tan high-waisted pants, ripped knee, checked shirt tied, white sneakers",
|
36 |
+
"brown tank top, plaid skirt, smooth texture, fitted top, flared skirt",
|
37 |
+
"white dress, black sandals, dark sunglasses, textured fabric, sheer sleeves, leather bag",
|
38 |
+
"black sports bra, black shorts, black arm band, dark wrist watch, clear eyeglasses",
|
39 |
+
"beige hoodie, matching pants, textured fabric",
|
40 |
+
"red satin dress, off-shoulder style, knotted front",
|
41 |
+
"white crop top, lace details, high-waisted skirt, pleated texture",
|
42 |
+
"black dress, sleeveless top, plunging neckline, white cross necklace, textured handbag, silver bracelet",
|
43 |
+
"pink halter-neck dress, ribbed texture, form-fitting",
|
44 |
+
"yellow lace-up top, white lace bralette, blue denim shorts, green handbag",
|
45 |
+
"white crop top, white jeans, glasses",
|
46 |
+
"red dress, sleeveless, v-neckline",
|
47 |
+
"white blouse, intricate lace, sheer sleeves",
|
48 |
+
"white bikini top, white mesh cover-up, white skirt, silver necklace",
|
49 |
+
"black oversized t-shirt, white sport socks",
|
50 |
+
"black strap top, lace trim, glossy texture",
|
51 |
+
"white crop top, ribbed texture, short sleeves, high-waisted shorts, elastic waistband",
|
52 |
+
"pink blazer, white top, pink trousers, silky fabric",
|
53 |
+
"green sports bra, green shorts, white sneakers, textured fabric",
|
54 |
+
"blue crop top, blue shorts, white sneakers, texture appears smooth",
|
55 |
+
"black tank top, denim shorts, textured fabric, light blue, frayed hems",
|
56 |
+
"green sports bra, green shorts, white socks, multicolored sneakers",
|
57 |
+
"straw hat, fringe bikini top, bikini bottom, earth tones",
|
58 |
+
"black dress, strap details, sheer textures",
|
59 |
+
"grey sweatshirt, soft texture, round neckline",
|
60 |
+
"white bikini top, ruffled edges, light fabric, headscarf with print, necklace",
|
61 |
+
"red bikini top, snakeskin pattern, textured fabric",
|
62 |
+
"white tank top, form-fitting, sleeveless",
|
63 |
+
"pink shiny dress, plunging neckline, sleeveless, textured fabric",
|
64 |
+
"strawberry-print top, white with red, matching shorts, silver loop earrings",
|
65 |
+
"pink crop-top, blue denim shorts, smooth texture, subtle sheen",
|
66 |
+
"textured fabric",
|
67 |
+
"white top, off-shoulder design, ruffled texture",
|
68 |
+
"beige strapless top, golden necklace",
|
69 |
+
"pink bikini top, shiny fabric, thin straps, pendant necklace, aviator sunglasses",
|
70 |
+
"white top, blue headband, black headphones",
|
71 |
+
"dark blue top, v-neckline, smooth texture, necklace with pendant",
|
72 |
+
"white top, black accents, mesh details, logo text",
|
73 |
+
"yellow crop top, yellow skirt, white high heels, gold necklace",
|
74 |
+
"white floral dress, off-shoulder design, sheer fabric",
|
75 |
+
"colorful bikini top, gold chain necklace, gold hoop earrings",
|
76 |
+
"denim jumpsuit, blue color, zipper front, sleeveless",
|
77 |
+
"white halter top, smooth texture",
|
78 |
+
"beige fedora, black bikini top, patterned cover-up, light-colored textures",
|
79 |
+
"green bikini top, white necklace",
|
80 |
+
"black halter top, glossy texture",
|
81 |
+
"black jacket, black crop top, black pants, various textures",
|
82 |
+
"black strapless top, golden necklace, golden bracelet",
|
83 |
+
"tie-dye bikini, blue-green-black hues, sports shorts, black with green and blue patterns",
|
84 |
+
"grey turtleneck, sleeveless, soft texture",
|
85 |
+
"beige tracksuit, zipper hoodie, matching pants, soft fabric",
|
86 |
+
"white tank top, blue jeans, black hair tie, gold necklace, blonde hair",
|
87 |
+
"satin top, silver color, strapless design, necklace, bracelet",
|
88 |
+
"red dress, plunging neckline, sleeveless, smooth texture, large hoop earrings",
|
89 |
+
"white floral dress, puff sleeves, low-cut neckline, butterfly pendant necklace",
|
90 |
+
"white fluffy robe, gold chain necklace, red lipstick",
|
91 |
+
"blue dress, sleeveless, plunging neckline, cinched waist, flowy texture",
|
92 |
+
"black jacket, purple shirt, denim overalls, white hair accessory, cream cardigan, simple necklace",
|
93 |
+
"sleeveless top, beige color, ribbed texture, high-waisted pants, black color, button details",
|
94 |
+
"white halter top, knotted center, sleeveless, smooth texture",
|
95 |
+
"cream crop top, beige striped shirt, blue ripped jeans",
|
96 |
+
"patterned white hat, large black glasses, denim jacket, red top, gold ring, white manicure",
|
97 |
+
"black rimmed glasses, beige blazer, black top, gold necklace",
|
98 |
+
"brown blouse, shoulder strap, gold necklace, stud earrings, eyeglasses, white manicure, gold rings",
|
99 |
+
"light green tank top, white drawstrings, ribbed texture, light green bottoms, fitted waistband, casual style",
|
100 |
+
"white strapless top, satin texture",
|
101 |
+
"white lace top, denim bottoms",
|
102 |
+
"camouflage crop top, camouflage shorts, brown boots, silver bracelets, sunglasses, hoop earrings",
|
103 |
+
"black top, sheer sleeves, black skirt, black boots, glasses",
|
104 |
+
"white ribbed top, plunging neckline, long sleeves, drawstring front, black jeans, distressed details",
|
105 |
+
"sleeveless top, beige color, snug fit, shorts, sitting",
|
106 |
+
"red dress, textured fabric, thin straps",
|
107 |
+
"yellow shirt, lace bralette, hoop earrings",
|
108 |
+
"white top, sheer sleeves, lace details, pastel pink bralette",
|
109 |
+
"black bodysuit, sheer gloves, patterned scarf, hoop earrings",
|
110 |
+
"black corset top, plaid skirt, glossy texture, lace details",
|
111 |
+
"beige bikini top, gold chain necklace",
|
112 |
+
"blue lace top, cleavage-revealing, long sleeves",
|
113 |
+
"black tank top, smooth texture",
|
114 |
+
"black halter top, white flower accessory",
|
115 |
+
"light pink hairband, green floral dress, gold earrings, light pink nail polish",
|
116 |
+
"white top, low neckline, soft texture",
|
117 |
+
"black tank top, black headband, headphones",
|
118 |
+
"black polka-dot bikini, thin necklace",
|
119 |
+
"black sleeveless top, textured fabric, shiny accessories",
|
120 |
+
"grey cardigan, white shirt, denim overalls, purple jacket, black hair ties",
|
121 |
+
"black leather dress, high-heel boots",
|
122 |
+
"blue camo sports bra, blue camo leggings",
|
123 |
+
"long-sleeve top, white bandeau, pink hues, sheer texture, butterfly prints",
|
124 |
+
"black tank top, white shirt, denim jeans",
|
125 |
+
"blue bikini top, blue high-waisted bottoms, large hoop earrings, white sneakers",
|
126 |
+
"beige hoodie, blue highlights, black sunglasses, blue sneakers, textured sole",
|
127 |
+
"beige hoodie, blue t-shirt, black leggings, blue sneakers, textured materials, oversized top, fitted bottoms",
|
128 |
+
"black crop top, black sheer-panelled bottoms, solid colors, smooth textures",
|
129 |
+
"straw hat, leopard print bikini, white cover-up",
|
130 |
+
"black sports bra, black leggings, smooth textures",
|
131 |
+
"black bikini top, shiny texture, gold necklace",
|
132 |
+
"white sports bra, white leggings, cream textured cardigan",
|
133 |
+
"red dress, thin straps, v-neckline, satin texture",
|
134 |
+
"black tank top, smooth texture",
|
135 |
+
"white halter top, gold necklace",
|
136 |
+
"black bikini, strap details",
|
137 |
+
"black bodysuit, white snow jacket, visible textures",
|
138 |
+
"no visible clothing",
|
139 |
+
"pink beret, light blouse, pink jacket, soft textures",
|
140 |
+
"fur-lined hood, beige coat, texture-soft",
|
141 |
+
"graphic jacket, multicolored, white hoodie, blue jeans",
|
142 |
+
"white tank top, spaghetti straps, lace details, natural textures",
|
143 |
+
"red crop top, white bikini bottoms, ribbed fabric",
|
144 |
+
"red strapless dress, smooth texture",
|
145 |
+
"sleeveless top, neutral color, soft texture",
|
146 |
+
"black sleeveless dress, textured fabric, sheer details",
|
147 |
+
"metallic green dress, crystal choker necklace",
|
148 |
+
"white tank top, gold necklace, natural texture",
|
149 |
+
"pearl headpiece, white textured dress, bejeweled adornments, sheer sleeves",
|
150 |
+
"white dress, deep neckline, sleeveless, lace-up sides, figure-hugging",
|
151 |
+
"white deep v-neck top, gold necklace, neutral makeup, straight hair",
|
152 |
+
"none visible",
|
153 |
+
"patterned blazer, patterned shorts, black bralette, warm colors, glossy texture",
|
154 |
+
"sleeveless top, beige color, denim shorts, light wash, leather seat texture",
|
155 |
+
"floral bikini top, white color, printed texture",
|
156 |
+
"blue dress, white trim, sparkling necklace, silver earrings, silver bracelet",
|
157 |
+
"silver chain necklace, pink pendant, gold bracelet",
|
158 |
+
"white headband, white ribbed top, black undergarment, light-colored jacket",
|
159 |
+
"yellow bikini top, black phone case",
|
160 |
+
"white crop top, light blue ripped jeans, smooth texture, silver necklace",
|
161 |
+
"peach sports bra, peach skirt, smooth fabric",
|
162 |
+
"patterned dress, black and white, deep neckline, short sleeves, textured fabric, black boots, laced footwear",
|
163 |
+
"black sleeveless dress, black heels, silver bracelet, silver necklace",
|
164 |
+
"light pink dress, sheer texture, fringe details, brown belt",
|
165 |
+
"red lace dress, black fur hat, red gloves",
|
166 |
+
"white cropped top, light blue jeans, textured fabric",
|
167 |
+
"pink cropped top, ribbed texture, tie-front detail, blue ripped jeans, casual style, light wash denim, black shoulder bag, brown belt",
|
168 |
+
"blue patterned bikini, sheer sleeves, ruffled cuffs",
|
169 |
+
"red dress, low neckline, sleeveless, smooth texture",
|
170 |
+
"pink sports bra, pink leggings, barefoot, black accents",
|
171 |
+
"striped one-piece swimsuit, blue and white colors, textured fabric",
|
172 |
+
"red ribbed sweater, black leather pants",
|
173 |
+
"white crop top, long sleeves, white skirt, textured fabric, green handbag, gold necklace, white wristwatch",
|
174 |
+
"white crop top, crisscross neckline, white pants, silver chain accents, white handbag, quilted texture",
|
175 |
+
"ribbed beige turtleneck dress, chest cut-out, black handbag, black and white sneakers",
|
176 |
+
"white tank top, black pants, smooth textures",
|
177 |
+
"White long-sleeve top, ribbed texture",
|
178 |
+
"black hoodie, pink leggings, brown shoes, white socks",
|
179 |
+
"Blue-purple bikini top, white lace-up detail, purple patterned skirt",
|
180 |
+
"strapless top, aqua color, textured fabric, high-waisted trousers, matching color, cinched ankles",
|
181 |
+
"pink dress, white cardigan, lacy sleeves",
|
182 |
+
"denim jumpsuit, light blue, sleeveless, lace-up front, fringed hem",
|
183 |
+
"bikini top, bikini bottom, earth tones, string ties",
|
184 |
+
"geometric pattern bodysuit, brown and black colors, plunging neckline, long sleeves, glossy black belt, black shoulder bag",
|
185 |
+
"white sleeveless top, silver zipper, textured fabric, blue denim shorts, frayed hems",
|
186 |
+
"red frilly dress, white heels, blue hair",
|
187 |
+
"white cropped shirt, white shorts, smooth fabric",
|
188 |
+
"yellow patterned bikini top, white bikini bottom, sunglasses, wrist accessories",
|
189 |
+
"grey bikini top, grey skirt, textured fabric, silver wrist accessory",
|
190 |
+
"strapless yellow dress, blue waist sash, beige high heels, black floral hair accessory",
|
191 |
+
"white crop top, black pants, pink and blue leg pads, vaughn glove, white skates",
|
192 |
+
"purple bikini top, lace-up detail, purple print skirt, textured fabric",
|
193 |
+
"pink tank top, blue ripped jeans, black strappy heels, beige shoulder bag",
|
194 |
+
"white tank top, blue denim shorts, textured fabric, visible brand writing",
|
195 |
+
"white cropped top, textured fabric, light-wash denim jeans, high-waisted, lace-up sides",
|
196 |
+
"white cropped cardigan, white pleated skirt, black shoulder bag, dark sunglasses, white bralette, gold necklace",
|
197 |
+
"pink crop top, white midriff band, pink shorts, glossy tan heels",
|
198 |
+
"black bikini top, black bikini bottoms, smooth fabric",
|
199 |
+
"sleeveless top, tan cropped pants, black sunglasses, black backpack straps, ribbed texture top, light colors",
|
200 |
+
"white crochet dress, brown belt, textures visible",
|
201 |
+
"white off-shoulder top, white shorts, textured fabric, ruffled sleeves",
|
202 |
+
"blue crop top, long sleeves, ribbed texture, plunging neckline, gray plaid skirt, pleated design",
|
203 |
+
"floral dress, white base, red and green patterns, V-neckline, long sleeves, brown belt, textured fabric",
|
204 |
+
"purple dress, gold heels, textured fabric, sleeveless, cut-out detailing",
|
205 |
+
"white hat, white dress, tiered ruffles, lace texture, small purse, silver watch, neutral heels",
|
206 |
+
"pink crop top, pink skirt, pink high heels, sleeveless, button details, smooth texture",
|
207 |
+
"black bodysuit, lace texture, sheer fabric",
|
208 |
+
"left: tan bodysuit, right: black dress, plunging neckline, short sleeves",
|
209 |
+
"sleeveless sequined dress, black and blue tones, sheer fabric, high slit, silver sequined dress, beige tones, strappy sandals, ankle strap, heeled footwear",
|
210 |
+
"black corset, lace texture, black gloves, chandelier earrings, silver necklace",
|
211 |
+
"brown polka-dot swimsuit, wide-brimmed straw hat, smooth texture",
|
212 |
+
"pink hearts bodysuit, white base, long sleeves",
|
213 |
+
"gray crop top, gold necklace, gold earrings, light makeup",
|
214 |
+
"Tan crochet bikini top, tan bikini bottom, gold waist chain, black halterneck bikini top, black tie-side bikini bottom, tan crochet bikini top, tan crochet skirt, gold waist chain",
|
215 |
+
"white hat, sunglasses, olive green cropped shirt, olive green skirt, black belt, black bikini bottom visible",
|
216 |
+
"beige dress, deep neckline, ribbed texture, white heels, criss-cross straps",
|
217 |
+
"blue tank top, textured fabric, lace-up front, white shorts, striped pattern, white sneakers",
|
218 |
+
"grey cardigan, white crop top, animal print shorts, blue hair",
|
219 |
+
"green dress, deep neckline, long sleeves, smooth texture, waist belt",
|
220 |
+
"pink bikini, pink heels, pink sunglasses",
|
221 |
+
"patterned jacket, patterned skirt, bikini top, vibrant colors, shiny texture",
|
222 |
+
"white cropped t-shirt, black graphic design, casual style",
|
223 |
+
"Red bikini, white polka dots, bow details",
|
224 |
+
"blue polka-dot dress, front buttoning, sleeveless design, white sunglasses, tied waist belt",
|
225 |
+
"white sports bra, white leggings, black sneakers, textures visible",
|
226 |
+
"lavender floral dress, white sunglasses, silver hoop earrings",
|
227 |
+
"sports bra, leggings, pastel green, form-fitting, sleeveless, high-waisted",
|
228 |
+
"white top, sheer overlay, light textures",
|
229 |
+
"white crop top, blue denim shorts, black and white sneakers, ribbed texture top",
|
230 |
+
"red crop top, blue jeans, light textures",
|
231 |
+
"blue sports bra, blue leggings, smooth texture",
|
232 |
+
"white crop top, high-waisted skirt, textured pink heels, black shoulder bag",
|
233 |
+
"striped swimsuit, blue and white, thin straps",
|
234 |
+
"white bikini top, white bikini bottoms, smooth texture",
|
235 |
+
"denim tube top, denim shorts, light blue, frayed hems, gold necklace, gold bracelet, navel piercing",
|
236 |
+
"black cap, black-framed glasses, red and black striped sweater, denim shorts, black belt, clear-lens glasses",
|
237 |
+
"crocheted bikini, white color, tassel details, tied straps",
|
238 |
+
"black halter dress, cut-out details, form-fitting, knee-length",
|
239 |
+
"white bikini, halter neck top, string bikini bottom, smooth texture",
|
240 |
+
"black dress, sleeveless, cut-out details, form-fitting",
|
241 |
+
"sports bra, leggings, pastel colors, form-fitting, athletic wear",
|
242 |
+
"blue and white striped top, front zipper, black shorts, denim texture",
|
243 |
+
"patterned dress, white with blue spots, short sleeves, v-neckline, textured fabric",
|
244 |
+
"blue bikini, white-orange socks, red-yellow roller skates",
|
245 |
+
"white long-sleeve top, distressed blue jeans, white sneakers",
|
246 |
+
"Black blazer, v-neckline, satin texture",
|
247 |
+
"white off-shoulder top, white bikini bottom, gold necklace, black sunglasses, textured fabrics",
|
248 |
+
"floral bikini, vibrant colors, textured fabric",
|
249 |
+
"green jumpsuit, cut-out torso, wide-leg pants, sleeveless top, flowy fabric",
|
250 |
+
"Pink dress, text patterns, sleeveless, high neckline, cut-out detail",
|
251 |
+
"black corset top, ripped blue jeans, white blazer, golden necklace, sunglasses on head",
|
252 |
+
"pink tank top, blue denim shorts, diamond choker necklace, brown patterned handbag",
|
253 |
+
"black corset top, patterned skirt, glossy texture",
|
254 |
+
"White halter top, blue denim jeans, gold bracelet, beige handbag",
|
255 |
+
"blue fringe haircut, pink sunglasses, pink denim jacket, white tank top, pink skirt, pink heart-shaped purse",
|
256 |
+
"pink crop top, pink shorts, ribbed texture, athletic wear",
|
257 |
+
"white off-shoulder top, wide sleeves, straw hat, textured fabric",
|
258 |
+
"denim jacket, black dress, white sneakers, blue backpack",
|
259 |
+
"white sports bra, black shorts, white sneakers, white socks",
|
260 |
+
"brown corset top, brown leather pants, glossy texture",
|
261 |
+
"brown cropped top, denim shorts, eyeglasses, wrist watch",
|
262 |
+
"white cropped top, blue denim jeans, smooth texture, frayed edges",
|
263 |
+
"light blue corset, denim jeans, silver necklace, black belt, light blue handbag",
|
264 |
+
"white cropped top, patterned green skirt, fabric texture visible, white undergarment",
|
265 |
+
"yellow crop top, blue denim shorts, white strapless top, tan belt, frayed hems",
|
266 |
+
"white crochet top, fringed detailing, denim jeans, tan shoulder bag",
|
267 |
+
"leopard print halter-top, blue ripped jeans",
|
268 |
+
"white long-sleeve top, plunging neckline, high-waisted jeans, distressed denim, blue color, tan ankle boots",
|
269 |
+
"black cut-out dress, gold bracelet, black and white heels, beige handbag",
|
270 |
+
"black crop top, deep neckline, long sleeves, denim shorts, frayed hem, black bralette, multiple straps, sheer sleeves, mesh pattern, choker necklace, high-waisted shorts, button closure",
|
271 |
+
"beige hoodie, matching sweatpants, visible drawstrings, soft texture",
|
272 |
+
"gray t-shirt, blue jeans, smooth texture, casual style",
|
273 |
+
"pink bikini top, pink skirt, sunglasses, gold watch",
|
274 |
+
"lace top, brown skirt, strapless design, textured fabric",
|
275 |
+
"strappy dress, beige color, form-fitting, textured fabric, sleeveless, knee-length",
|
276 |
+
"black t-shirt, rib cage print, white shorts",
|
277 |
+
"light blue hoodie, matching shorts, soft, cotton texture, hoodie drawstrings, exposed midriff",
|
278 |
+
"blue patterned top, blue patterned shorts, black glasses",
|
279 |
+
"black sequin dress, high neckline, sleeveless, side slit, strappy high heels, silver earrings",
|
280 |
+
"black sequined dress, high neckline, sleeveless, back slit, strappy high heels, metallic color",
|
281 |
+
"transparent patterned top, black bralette, glossy black pants, glittery sneakers",
|
282 |
+
"black eyeliner, silver hoop earrings, gray-scale makeup, camouflage long sleeve top, black crop top, glossy black pants, glittery silver sneakers",
|
283 |
+
"blue dress, short sleeves, shiny texture, watch, ring",
|
284 |
+
"white crop top, black headphones, black sunglasses",
|
285 |
+
"button-up dress, peach color, short sleeves, collar, thigh length, fabric texture",
|
286 |
+
"white crop top, yellow sweatpants, textured fabric",
|
287 |
+
"striped swimsuit, glasses",
|
288 |
+
"pink dress, short sleeves, crew neckline, ribbed texture",
|
289 |
+
"pink dress, tiered layers, spaghetti straps, v-neckline, pleated texture, silver watch",
|
290 |
+
"red sports bra, red leggings, smooth texture, athletic wear",
|
291 |
+
"light jacket, matching trousers, white sneakers, black bag",
|
292 |
+
"Yellow checkered bikini, white straps, smooth texture",
|
293 |
+
"white ribbed dress, yellow-tinted sunglasses",
|
294 |
+
"long-sleeve top, ribbed texture, brown color, matching skirt, high-waisted",
|
295 |
+
"black sports bra, striped sheer pants",
|
296 |
+
"golden bikini, textured fabric",
|
297 |
+
"white crop top, blue denim shorts, cow print boots, silver necklace",
|
298 |
+
"orange dress, ribbed texture, short sleeves, side cut-outs, tie-up details",
|
299 |
+
"red bikini top, red bikini bottom, ribbed texture, tied sides",
|
300 |
+
"black bikini, textured fabric",
|
301 |
+
"white corset top, floral pattern, denim jeans, corset laces",
|
302 |
+
"white tank top, grey sports bra, grey shorts, textured fabrics, visible branding",
|
303 |
+
"white ribbed top, front tie, long sleeves, black leather pants, high-waisted",
|
304 |
+
"brown hat, black tank top, white denim shorts, frayed shorts hem",
|
305 |
+
"black crop top, mesh sleeves, checkered mini skirt, black boots, textured fabrics",
|
306 |
+
"black sweatshirt, cartoon graphic, glasses, light shorts, casual style",
|
307 |
+
"crop top, olive green, ribbed texture, high-waisted leggings, olive green, fitted",
|
308 |
+
"black bikini, glossy texture, gold earrings",
|
309 |
+
"black v-neck top, black belt, black trousers, blue handbag, golden necklace",
|
310 |
+
"black crop top, long sleeves, high-waisted leggings, mesh panels, dark hues, white sneakers",
|
311 |
+
"white crop top, gray trousers, white sandals, black sunglasses, gold belt",
|
312 |
+
"gray cardigan, white crop top, leopard print shorts, blue hair",
|
313 |
+
"white v-neck top, knotted waist, light-colored pants, fitted texture",
|
314 |
+
"white crop top, grey shorts, white sneakers, text on top",
|
315 |
+
"black swimsuit, straw hat, textured fabric",
|
316 |
+
"off-shoulder top, white with stripes, casual shorts",
|
317 |
+
"white crop top, glitter texture, black leather jacket, black leather pants",
|
318 |
+
"black tank top, shoulder straps, scoop neckline",
|
319 |
+
"Sleeveless top, pink hue, denim shorts, ripped texture, sunglasses on head",
|
320 |
+
"black long-sleeve top, light blue jeans, silver belt, form-fitting, casual style",
|
321 |
+
"floral jumpsuit, red and beige, texture visible, high heels, tan-colored",
|
322 |
+
"red dress, sleeveless, V-neckline",
|
323 |
+
"dark sunglasses, white collared shirt, navy blue sweater, pleated white skirt, black shoulder bag with gold hardware",
|
324 |
+
"white tank top, textured fabric, large hoop earrings, headscarf with print",
|
325 |
+
"black swimsuit, red headband, sunglasses",
|
326 |
+
"black tank top, sheer fabric, patterned design, golden bracelet",
|
327 |
+
"camouflage bikini, white-brown-beige tones, high-waisted bottoms, sleeveless top, hoop earrings",
|
328 |
+
"patterned crop top, light colors, tie front, long sleeves, white pants, soft texture",
|
329 |
+
"green tank top, white shorts, black glasses",
|
330 |
+
"Red patterned top, deep neckline, short sleeves",
|
331 |
+
"white crop top, lace-up detail, textured skirt, cream color, sleeveless, midriff-baring",
|
332 |
+
"white bathrobe, textured fabric, glasses",
|
333 |
+
"white cropped top, blue trim, long sleeves, blue track pants",
|
334 |
+
"white crop top, pastel green leggings, textured fabric",
|
335 |
+
"spotted swimsuit, light-dark contrast, thin straps, skin exposure",
|
336 |
+
"black dress, double-breasted, v-neckline, sleeveless, silver necklace",
|
337 |
+
"black beanie, black cropped top, black leggings, black boots, red bag, gold watch",
|
338 |
+
"beige fedora, white cropped top, textured terracotta skirt",
|
339 |
+
"blue denim jeans, blue strapless top, texture appears soft",
|
340 |
+
"White lace dress, Off-shoulder sleeves, Corset-style top, Drawstring details",
|
341 |
+
"sleeveless top, beige color, ribbed texture, high neckline, light blue jeans, fitted style, denim material, wrist accessory, silver color, sparkling texture",
|
342 |
+
"white strapless top, white skirt, shiny fabric",
|
343 |
+
"light white dress, thin straps, sheer texture"
|
344 |
+
]
|
data/composition.json
ADDED
@@ -0,0 +1,344 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"lush greenery, blurred foliage, natural lighting",
|
3 |
+
"geometric tiles, circular mirror, bright lighting, hexagonal patterns",
|
4 |
+
"graffiti on door, urban setting, dark tones, metallic door handle",
|
5 |
+
"hockey rink, empty stands, protective netting, overhead lighting",
|
6 |
+
"white textured wall, architectural details, indirect lighting",
|
7 |
+
"interior setting, yacht cabin, neutral colors",
|
8 |
+
"marble interior, bath tub, luxury decor, neutral colors",
|
9 |
+
"white brick wall, soft shadows, neutral tones",
|
10 |
+
"wooden cabinetry, metallic handles, indoor lighting, blurred marina",
|
11 |
+
"black door, white wall, outdoor lighting, architectural details",
|
12 |
+
"boxing gym, hanging punching bags, scattered newspapers, weight plates",
|
13 |
+
"sunlit setting, waterfront, architectural columns, tropical plants",
|
14 |
+
"dark room, graphic door sign, purple wall accents, pink lighting effect",
|
15 |
+
"wooden structures, blurred furnishings, indoor setting, natural light",
|
16 |
+
"white structure, arch details, outdoor setting, other subjects",
|
17 |
+
"white walls, minimalistic design, clear sky, architectural details",
|
18 |
+
"rocky terrain, blurred foliage, natural setting",
|
19 |
+
"open doorway, bright lighting, indoor setting, blurred background",
|
20 |
+
"clear sky, coastal view, lush landscape, outdoor setting",
|
21 |
+
"pale wall, indoor setting, plant left side, yoga mat right side",
|
22 |
+
"outdoor light, blurred marina, overcast sky",
|
23 |
+
"indoor setting, sheer curtains, diffused lighting, soft color palette",
|
24 |
+
"green foliage, blurred leaves, natural setting",
|
25 |
+
"snowy landscape, pine trees, outdoor setting, daytime, wooden structure",
|
26 |
+
"neutral walls, indoor setting, minimalistic style",
|
27 |
+
"blurred indoors, muted colors, window visible",
|
28 |
+
"sandy beach, ocean waves, clear sky, pier structure",
|
29 |
+
"beach view, cloudy sky, calm sea, outdoor setting, blurred horizon",
|
30 |
+
"nighttime cityscape, window reflections, indoor setting",
|
31 |
+
"illuminated pool, purple lighting, night time, outdoor setting, landscaped garden",
|
32 |
+
"neutral colors, indoor setting, framed artwork, white sofa, glass table",
|
33 |
+
"textured white wall, minimalistic, outdoor lighting",
|
34 |
+
"calm water, overcast sky, sandy beach, distant sunshades, tranquil setting",
|
35 |
+
"white sculptures, classical columns, artistic space, diffuse natural light",
|
36 |
+
"urban setting, geometric structures, blurred background, overcast lighting",
|
37 |
+
"modern sculpture, clear sky, reflective water, urban setting, angular architecture",
|
38 |
+
"gym setting, blurred equipment, blue lighting, dark ambiance",
|
39 |
+
"dark blue backdrop, subtle texture, glowing edge",
|
40 |
+
"white walls, minimalistic art, indoor setting",
|
41 |
+
"indoor setting, patterned walls, wooden furniture, relaxed ambiance",
|
42 |
+
"lush greenery, terracotta roofs, coastal view, hazy skyline",
|
43 |
+
"indoor setting, green plants, dark couch, tiled floor, bright lighting",
|
44 |
+
"parking garage, concrete pillars, shadow patterns",
|
45 |
+
"outdoor stairs, building facade, flowering plants",
|
46 |
+
"blurred setting, neutral colors, outdoor environment",
|
47 |
+
"floral surroundings, blurred greens, natural setting",
|
48 |
+
"glass doors, tropical trees, clear sky, outdoor setting",
|
49 |
+
"plain wall, minimal shadows, neutral colors",
|
50 |
+
"staircase behind, indoor lighting, neutral colors",
|
51 |
+
"plain wall, neutral color, minimal shadows, soft lighting",
|
52 |
+
"industrial setting, nighttime, artificial lighting, parking area",
|
53 |
+
"neutral walls, indoor setting, minimalistic decor, potted plant",
|
54 |
+
"neutral-colored walls, indoor setting, plant on side",
|
55 |
+
"white boat, clear skies, sunlit, outdoor setting",
|
56 |
+
"plain wall, wooden floor, indoor lighting, potted plant",
|
57 |
+
"white stairs, surfboard overhead, outdoor setting",
|
58 |
+
"dark green tones, decorative artwork, ambient lighting",
|
59 |
+
"neutral wall, indoor setting, minimal detail",
|
60 |
+
"green cushions, outdoor setting, foliage, shaded area",
|
61 |
+
"outdoor setting, blurred greenery, wooden structure",
|
62 |
+
"blue sky, calm sea, boat deck",
|
63 |
+
"stone wall, draped curtains, indoor lighting",
|
64 |
+
"red car interior, blurred movement, sunlit ambiance",
|
65 |
+
"sunny sky, white structure, outdoor setting, partially cloudy",
|
66 |
+
"blue sky, ocean view, yacht in distance, seated pose",
|
67 |
+
"white interior, sheer curtains, window blinds, minimalistic style",
|
68 |
+
"indoor setting, large windows, daylight, minimalistic decor, outdoor view",
|
69 |
+
"foliage, outdoor setting, blurred greenery, natural light",
|
70 |
+
"car interior, black leather seats, diamond pattern stitching",
|
71 |
+
"indoor setting, neutral colors, minimalistic decor, soft lighting",
|
72 |
+
"arched structure, blurred foliage, outdoor setting",
|
73 |
+
"outdoor setting, white umbrellas, patio chairs, Moet & Chandon bottle, green plants",
|
74 |
+
"indoor setting, mirrored walls, soft lighting",
|
75 |
+
"sunny beach, blurred waves, clear sky",
|
76 |
+
"blurred interior, neutral tones, soft lighting",
|
77 |
+
"nighttime cityscape, blurred lights, outdoor setting",
|
78 |
+
"outdoor setting, tree branches, bright sunlight",
|
79 |
+
"blue umbrella, tropical setting, outdoor seating, beverage can, glass with drink",
|
80 |
+
"indoor setting, chairs visible, cluttered table, neutral colors",
|
81 |
+
"modern structure, blue sections, clear sky, urban setting, old building",
|
82 |
+
"white walls, soft lighting, indoor setting",
|
83 |
+
"light-colored building, dark doorway, minimalistic, urban setting",
|
84 |
+
"white wall, indoor setting, minimalistic decor",
|
85 |
+
"mural art, painted wings, indoor setting, casual ambience",
|
86 |
+
"vehicle interior, leather seats, car door window, slightly blurred",
|
87 |
+
"indoor setting, television on, modern decor, blurred details",
|
88 |
+
"dim lighting, indoor setting, blurred plants, warm tones",
|
89 |
+
"dimly lit room, blurred decor, warm tones, ambient lighting",
|
90 |
+
"dark room, black and white wall art, contrast lighting, minimalistic decor",
|
91 |
+
"sunrise\/sunset, calm water, anchored boats, hilly landscape, clear sky",
|
92 |
+
"indoor setting, blurred surroundings",
|
93 |
+
"outdoor setting, green plants, restaurant ambiance, daylight conditions",
|
94 |
+
"outdoor setting, clear blue sky, mountain view, lush greenery, architectural structure",
|
95 |
+
"bright room, modern furniture, large window",
|
96 |
+
"indoor setting, neutral colors, blurred decor",
|
97 |
+
"indoor setting, windows, blurred room details",
|
98 |
+
"plain white wall, indoor setting, soft lighting",
|
99 |
+
"outdoor setting, blue sky, swimming pool, lush plants, sunny day",
|
100 |
+
"indoor setting, blurred decor, neutral colors",
|
101 |
+
"outdoor cafe, green plants, tropical setting",
|
102 |
+
"stage structures, greenery, daytime, speakers, cables, yellow tennis balls",
|
103 |
+
"wooden structure, blurred greenery, natural daylight",
|
104 |
+
"hazy sky, mountainous terrain, balcony railing",
|
105 |
+
"outdoor setting, sports car, lush greenery",
|
106 |
+
"ocean view, cloudy sky, outdoor setting, sunset lighting",
|
107 |
+
"window curtains, indoor setting, neutral colors",
|
108 |
+
"ornate mirror, floral wallpaper, neutral tones, indoor setting",
|
109 |
+
"solid teal backdrop, soft shadows, no other subjects",
|
110 |
+
"house entrance, evening lighting, brick column, window",
|
111 |
+
"swimming pool, green lawn, outdoor setting, blue sky, daytime",
|
112 |
+
"green foliage, natural lighting, sunny day",
|
113 |
+
"neutral-colored wall, indoor setting, minimalistic decor",
|
114 |
+
"tropical foliage, blurred greenery, sunny daylight",
|
115 |
+
"indoor setting, neutral colors, ambient lighting",
|
116 |
+
"plain white, soft shadow, minimalistic",
|
117 |
+
"indoor room, potted plants, textured floor",
|
118 |
+
"outdoor setting, blurred foliage, overcast sky, natural light, creek or river",
|
119 |
+
"monochromatic hues, blurred setting, dark ambiance",
|
120 |
+
"indoor setting, crowded venue, blurred figures",
|
121 |
+
"white cyclorama, minimalist setting, studio environment",
|
122 |
+
"clear blue sky, lush green plants, sunlit ambiance",
|
123 |
+
"blue sky, palm trees, sunny day, outdoor setting",
|
124 |
+
"underpass structure, concrete columns, shadow patterns",
|
125 |
+
"concrete structure, shadow patterns, sunlit area",
|
126 |
+
"starry space, distant Earth, hexagonal pattern floor, metallic surface",
|
127 |
+
"space setting, starry sky, Earth visible, metallic floor, hexagonal pattern",
|
128 |
+
"tropical beach, green foliage, palm tree, blurred background, serene setting",
|
129 |
+
"sandy beach, green foliage, natural setting",
|
130 |
+
"gym equipment, blurred lights, reflective surfaces",
|
131 |
+
"sunlit building, green grass, shadow patterns, late afternoon",
|
132 |
+
"neutral tones, indoor setting, soft furnishings, blurred textures",
|
133 |
+
"evening sky, blurred greenery, distant water view",
|
134 |
+
"outdoor setting, basketball hoop, lush greenery, bright sunlight, colorful flowers",
|
135 |
+
"white walls, large window, indoor setting",
|
136 |
+
"sandy beach, ocean horizon, clear sky, distant figures",
|
137 |
+
"snowy setting, blurred trees, natural light",
|
138 |
+
"white bathtub, blurred surroundings, indoor setting",
|
139 |
+
"blossoming branches, blurred background, warm tones",
|
140 |
+
"outdoor gathering, blurred people, canopy structure, natural light",
|
141 |
+
"blue gradient, studio setting, no visible objects",
|
142 |
+
"blurred indoors, warm tones, indistinct shapes",
|
143 |
+
"yacht interior, sunset skies, calm water, moored boats",
|
144 |
+
"car interior, nighttime, blurred lights",
|
145 |
+
"white wall, indoor setting, minimal decor",
|
146 |
+
"event backdrop, logo patterns, green carpet",
|
147 |
+
"soft-focused, dark hues, subtle shadows",
|
148 |
+
"vehicle interior, blurred windows, soft lighting",
|
149 |
+
"indoor setting, blurred details, bokeh effect",
|
150 |
+
"solid dark, indoors, soft lighting",
|
151 |
+
"indoor setting, doorway, minimal decor",
|
152 |
+
"swimming pool, clear water, blurred blue, outdoor setting",
|
153 |
+
"outdoor seating, blurred plants, neutral colors",
|
154 |
+
"car interior, daylight, building exterior, reflective window",
|
155 |
+
"water body, hills, clear sky",
|
156 |
+
"indoor setting, blurred bedding, neutral colors",
|
157 |
+
"plain white, no distractions",
|
158 |
+
"urban setting, white buildings, overcast sky",
|
159 |
+
"plain wall, neutral colors, indoor lighting",
|
160 |
+
"sandy beach, rocky terrain, calm sea, clear sky",
|
161 |
+
"indoor room, sheer curtains, soft shadows",
|
162 |
+
"textured wall, concrete texture, muted colors, indoor setting, wooden stool",
|
163 |
+
"pink patterned chair, wooden furniture, cream carpet, floor lamp",
|
164 |
+
"stone wall, white railing, sunny day, shadow patterns",
|
165 |
+
"blue sky, coastal scenery, sparse vegetation, gravel ground",
|
166 |
+
"palm trees, blue sky, white building, parked cars",
|
167 |
+
"city street, cobblestone pavement, street staircase, colorful buildings, overcast sky, European architecture, daylight setting",
|
168 |
+
"indoor setting, gray sofa, sliding door",
|
169 |
+
"indoor setting, natural light, decorative mirror, neutral tones, floral arrangement, contemporary decor",
|
170 |
+
"paved walkway, potted plants, building facade, daytime",
|
171 |
+
"sandy beach, tropical vegetation, kayaks, clear sky",
|
172 |
+
"carousel, vibrant colors, blurry movement, white fence",
|
173 |
+
"outdoor setting, brightly lit, foliage, hexagonal tiles, architectural features",
|
174 |
+
"casino setting, slot machines, ambient lighting, blurred background",
|
175 |
+
"garage setting, parked car, concrete floor",
|
176 |
+
"hockey rink boards, indoor lighting, sporty environment",
|
177 |
+
"Marble steps, clear sky, architectural structure",
|
178 |
+
"luxury car interior, pink seats, door open",
|
179 |
+
"Green foliage, blurred plants, sunny day",
|
180 |
+
"outdoor setting, blooming flowers, wooden structure",
|
181 |
+
"green field, wooden fence, grazing horse, trees, dusk sky",
|
182 |
+
"concrete structure, underpass, soft shadows, daylight",
|
183 |
+
"beach setting, ocean horizon, cloudy sky, gentle waves, soft sand",
|
184 |
+
"parking garage, concrete pillars, EXIT sign, diffused daylight",
|
185 |
+
"metal staircase, blue hues, outdoor location, clear sky",
|
186 |
+
"colored balls, white floor, minimalistic architecture",
|
187 |
+
"marina setting, high-rise buildings, clear sky",
|
188 |
+
"outdoor pool, white building, tropical vegetation, poolside furniture",
|
189 |
+
"boat interior, water view, clear sky, distant buildings",
|
190 |
+
"white curved walls, arch-like alcoves, simple white stools",
|
191 |
+
"ice hockey rink, empty stands, neutral lighting",
|
192 |
+
"lush greenery, blurred foliage, outdoor setting",
|
193 |
+
"white walls, smooth texture, architectural lines, minimalistic style",
|
194 |
+
"red patterned car, daytime, outdoor setting, blurred surroundings",
|
195 |
+
"white picket fence, green foliage, sunlit scene",
|
196 |
+
"palm trees, clear skies, paved walkway, tropical setting",
|
197 |
+
"marble countertop, wooden slats, pink cabinets, makeup brushes",
|
198 |
+
"sandy beach, ocean waves, clear sky, surfboard",
|
199 |
+
"sandy beach, cloudy sky, distant mountains, beachgoers, paragliders, natural setting",
|
200 |
+
"stone wall, narrow pathway, natural light",
|
201 |
+
"urban skyline, water reflections, soft lighting, distant buildings",
|
202 |
+
"autumn leaves, wooded path, blurry foliage, natural setting",
|
203 |
+
"stone walls, green plants, hanging utensils, cobblestone ground, outdoor setting, narrow alley",
|
204 |
+
"gray couch, floral wallpaper, subdued lighting, large blooms, dark tones",
|
205 |
+
"green hedge, evenly lit, shadow on ground, outdoor setting",
|
206 |
+
"yellow couch, pink wall, white pillow, floral arrangement, indoor setting",
|
207 |
+
"red wallpaper, ornate chair, vintage phone, patterned carpet",
|
208 |
+
"greenery, sunlit lawn, blurred backdrop",
|
209 |
+
"theater setting, plush seating, ambient lighting, popcorn spilled, circular patterns on carpet",
|
210 |
+
"grey walls, pumpkin decorations, lit jack-o'-lantern, indoor setting, halloween theme",
|
211 |
+
"sandy beach, blurred foliage, white towel, printed design, scattered flowers",
|
212 |
+
"wooden door frame, snow-covered ground, pine trees",
|
213 |
+
"outdoor setting, waterfront view, glass panes, bar counter, citrus drinks, clear skies",
|
214 |
+
"Beach scenery, cloudy sky, sunset lighting, vegetation",
|
215 |
+
"sandy terrain, rocky formations, clear sky, picnic setup",
|
216 |
+
"tropical setting, palm trees, water body, champagne bucket, white draped chair",
|
217 |
+
"overlooking ocean, tropical foliage, distant islands, clear sky, stone wall",
|
218 |
+
"urban landscape, skyscrapers, overcast sky, greenery, empty lot",
|
219 |
+
"urban landscape, balcony railing, overcast sky, flowering shrubs, distant buildings",
|
220 |
+
"vintage car, car wash setting, soapy water, overcast sky",
|
221 |
+
"red wall, green foliage, natural daylight",
|
222 |
+
"indoor setting, wooden staircase, sunlit doorway",
|
223 |
+
"Blue sky, calm sea, wooden dock, lounge chairs, yellow towel, boat mast",
|
224 |
+
"urban setting, covered walkway, architectural columns, clear sky",
|
225 |
+
"balcony setting, urban skyline, daytime, green box with letters",
|
226 |
+
"lush greenery, purple flowers, blurred details",
|
227 |
+
"gym setting, cardio machines, large windows, snowy outdoors, urban environment",
|
228 |
+
"sandy beach, ocean waves, clear sky",
|
229 |
+
"concrete stairs, outdoor setting, sunlit, shadowed areas",
|
230 |
+
"paved sidewalk, green bushes, white picket fence, clear sky, distant people",
|
231 |
+
"residential area, paved road, clear sky, daytime",
|
232 |
+
"cloudy sky, historical monument, bustling plaza, street lamps",
|
233 |
+
"city skyline, water, daytime, clear skies",
|
234 |
+
"palm tree, tropical foliage, blurred greenery",
|
235 |
+
"lush greenery, flowering shrubs, paved path, outdoor setting, soft-focus plants",
|
236 |
+
"autumn leaves, picnic setting, carved pumpkins, basket, wine bottle, scattered fruits, woodland scenery",
|
237 |
+
"green van, sunlit trees, parked vehicle, daytime",
|
238 |
+
"narrow alleyway, beige walls, soft focus, daylight",
|
239 |
+
"beach setting, evening sky, soft focus, ocean horizon, other person blurred",
|
240 |
+
"beige walls, outdoor setting, architectural features",
|
241 |
+
"outdoor setting, running track, greenery, trees, sunlight",
|
242 |
+
"green trees, sunlit path, daytime, blurred background",
|
243 |
+
"tropical plants, blurred greenery, wooden structure, bright atmosphere",
|
244 |
+
"wooden boardwalk, blurred pedestrians, warm lighting",
|
245 |
+
"neutral tones, indoor setting, minimalist decor",
|
246 |
+
"Blurred shelves, indoor setting, warm tones",
|
247 |
+
"tropical setting, bar counter, patterned tiles, green cushioned chair, beverage visible",
|
248 |
+
"outdoor setting, patio, sliding door",
|
249 |
+
"stone wall, wrought iron gate, urban setting, neat pavements, subtle shadows",
|
250 |
+
"Wooden door, marble walls, indoor lighting, mirrored reflection",
|
251 |
+
"city skyline, large windows, indoor setting, sunset lighting, high-rise view",
|
252 |
+
"glass reflection, blurred greenery, outdoor setting",
|
253 |
+
"indoor setting, wooden floor, ornate furniture",
|
254 |
+
"Green foliage, outdoor setting, sunlit",
|
255 |
+
"ornate iron gate, stone building facade, urban environment, clear skies",
|
256 |
+
"palm trees, clear sky, tropical setting, paved path",
|
257 |
+
"tropical beach setting, palm trees, blue water, clear sky, wooden structure",
|
258 |
+
"stone wall, green hills, cloudy sky, river in distance",
|
259 |
+
"tennis court, blue surface, white lines, tennis racket, yellow tennis balls, net partial view",
|
260 |
+
"city street, evening lighting, shopfront windows, parked cars",
|
261 |
+
"bookshelves, stacked books, indoor setting",
|
262 |
+
"pink chair, white wall, 'VILLAGE' sign, outdoor setting",
|
263 |
+
"glass door, indoor setting, patterned rug, hardwood floors",
|
264 |
+
"fruit stand, hanging bananas, assorted fruits, daylight, outdoor market",
|
265 |
+
"white wall, indoor setting, natural light, door frame, glass reflection",
|
266 |
+
"green foliage, residential area, sunny day, clear sky",
|
267 |
+
"palm trees, sunny skies, floral bushes",
|
268 |
+
"modern interior, white walls, wooden floor, potted plant, bar stools",
|
269 |
+
"modern room, large window, green plant, white sofa, coffee table, beige pillows, gray walls",
|
270 |
+
"neon lights, Chinese characters, urban feel, dark ambiance",
|
271 |
+
"dark backdrop, blue accents, subtle texture, illuminated base",
|
272 |
+
"fuzzy pink blanket, blue-green tinted background, smartphone present, indoors, comfortable setting",
|
273 |
+
"palm trees, blue sky, outdoor furniture, patio setting",
|
274 |
+
"kitchen setting, espresso machine, white cabinets, decorative items",
|
275 |
+
"bright room, curtain-draped window, reflected in mirror, soft shadows",
|
276 |
+
"high-rise view, glass window, modern furniture",
|
277 |
+
"bright interior, white walls, open doorways, tiled floor, minimal decor",
|
278 |
+
"white wall, minimalistic, shadow patterns",
|
279 |
+
"city lights, blurred background, nighttime, wooden railing, dark ambiance",
|
280 |
+
"city lights, bokeh effect, nighttime, wooden surface",
|
281 |
+
"industrial setting, metal window, concrete wall, moss-covered ground",
|
282 |
+
"industrial setting, daylight, weathered building, concrete ground, overgrown vegetation",
|
283 |
+
"red chairs, wooden panels, natural light, yellow rose, white plate, silverware",
|
284 |
+
"clear skies, mountainous terrain, urban landscape",
|
285 |
+
"green hedge, clear sky, outdoor setting, daytime, concrete path",
|
286 |
+
"balcony setting, water view, boats docked, cloudy sky",
|
287 |
+
"city skyline, water, daylight",
|
288 |
+
"car interior, black leather seats, red stitching, parking garage",
|
289 |
+
"curtain-draped windows, cityscape view, natural light, modern interior",
|
290 |
+
"gym setting, blurred weights, indoor environment, clear windows, green foliage outside",
|
291 |
+
"urban setting, blurred vehicles, soft focus, evening light",
|
292 |
+
"Outdoor setting, clear sky, poolside, tropical vegetation",
|
293 |
+
"open road, clear sky, desert landscape",
|
294 |
+
"glass door, reflection visible, outdoor setting, plants, overcast sky",
|
295 |
+
"outdoor setting, greenery, trees, blurred foliage",
|
296 |
+
"beach sands, overturned boat, green foliage",
|
297 |
+
"dirt pathway, green plants, red flowers",
|
298 |
+
"open road, clear sky, mountainous terrain, daylight",
|
299 |
+
"rocky terrain, calm sea, clear sky, daylight",
|
300 |
+
"poolside, sunset sky, tropical trees, water reflections",
|
301 |
+
"green curtains, window blinds, indoor setting, golden hour light",
|
302 |
+
"sandy ground, wooden equipment, blurred buildings",
|
303 |
+
"plain wall, neutral colors, indoor setting",
|
304 |
+
"golden hour, out-of-focus horses, clear sky, outdoor setting, warm tones",
|
305 |
+
"stone wall, dappled sunlight, outdoor setting, foliage",
|
306 |
+
"wooden railing, green foliage, blurred scenery, outdoor environment",
|
307 |
+
"sheer curtains, soft backlight, indoor room, muted colors, minimalist style, peaceful atmosphere",
|
308 |
+
"outdoor setting, stone structure, hanging lanterns, foliage, ceramic pottery",
|
309 |
+
"illuminated buildings, urban setting, nighttime ambiance",
|
310 |
+
"tennis court, hard surface, painted lines, no other people",
|
311 |
+
"clear sky, coastal view, urban skyline, architectural features",
|
312 |
+
"urban skyline, grassy field, overcast sky",
|
313 |
+
"urban setting, blurred fountain, clear sky, buildings in distance",
|
314 |
+
"skyscrapers, palm trees, clear sky, balcony railing",
|
315 |
+
"swimming pool, lounge chairs, palm trees, clear skies",
|
316 |
+
"palm trees, beach huts, clear sky, sandy ground",
|
317 |
+
"gas station pumps, red bricks building, clear sky, daytime",
|
318 |
+
"marble tiles, shower heads, indoor lighting, shower knobs",
|
319 |
+
"Marina setting, yachts docked, clear sky, wooden pier",
|
320 |
+
"wooden pergola, hanging lights, green plants, twilight ambiance, outdoor setting",
|
321 |
+
"green foliage, blurred scenery, outdoor setting, brick path",
|
322 |
+
"blurred setting, neutral colors, outdoor environment",
|
323 |
+
"blurry cityscape, glass balustrade, indoor setting",
|
324 |
+
"blurry nature, earthy tones, out of focus",
|
325 |
+
"desert terrain, clear sky, ATV vehicle",
|
326 |
+
"water feature, blue tiles, blurred buildings, outdoor setting",
|
327 |
+
"outdoor setting, bright sunlight, orange umbrellas, white lounge chairs, clear sky",
|
328 |
+
"horizontal lines, warm lighting, blurred setting, outdoor location",
|
329 |
+
"sunlit trees, blurred foliage, outdoor setting",
|
330 |
+
"Blurry greenery, white structure, defocused meal",
|
331 |
+
"sandy beach, sunset lighting, coastal vegetation, wooden post",
|
332 |
+
"window with sheer curtain, soft natural light, blurred food tray, couch corner",
|
333 |
+
"sunlit street, blurred foliage, warm tones",
|
334 |
+
"neutral tones, minimalistic decor, plain walls",
|
335 |
+
"tropical setting, blurred greenery, open-air structure, beverage on table",
|
336 |
+
"modern interior, large window, daytime, urban skyline, minimal furniture",
|
337 |
+
"city street, stone balustrade, cloudy sky, walking people, fluttering flags",
|
338 |
+
"desert landscape, clear skies, distant camel",
|
339 |
+
"interior setting, ceiling fan, natural lighting, open door, floor lamp",
|
340 |
+
"Indoor setting, Wooden floor, White lampshade, Dining chairs, Kitchen counter",
|
341 |
+
"wooden panels, modern architecture, outdoor setting, bright daylight",
|
342 |
+
"window frame, white wall, pipe visible",
|
343 |
+
"wooden structure, forested area, natural light, out of focus greenery"
|
344 |
+
]
|
data/default_tags.json
ADDED
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"a man",
|
3 |
+
"a woman",
|
4 |
+
"a young man",
|
5 |
+
"a young woman",
|
6 |
+
"a middle aged man",
|
7 |
+
"a middle aged woman",
|
8 |
+
"an old man",
|
9 |
+
"an old woman"
|
10 |
+
]
|
data/device.json
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"Canon EOS 5D Mark IV with Canon EF 24-70mm f-2.8L II",
|
3 |
+
"Canon EOS 90D with Canon EF-S 18-135mm f-3.5-5.6 IS USM",
|
4 |
+
"Canon EOS M6 Mark II with Canon EF-M 32mm f-1.4",
|
5 |
+
"Canon EOS R with Canon RF 28-70mm f-2L",
|
6 |
+
"Canon EOS-1D X Mark III with Canon EF 50mm f-1.2L",
|
7 |
+
"Canon PowerShot G5 X Mark II with Built-in 8.8-44mm f-1.8-2.8",
|
8 |
+
"DJI Mavic Air 2 with Built-in 24mm f-2.8",
|
9 |
+
"FujiFilm X-T4 with Fujinon XF 35mm f-2 R WR",
|
10 |
+
"Fujifilm GFX 100 with GF 110mm f-2 R LM WR",
|
11 |
+
"Fujifilm X-Pro3 with Fujinon XF 56mm f-1.2 R",
|
12 |
+
"Fujifilm X-S10 with Fujinon XF 10-24mm f-4 R OIS WR",
|
13 |
+
"Fujifilm X100V with Fujinon 23mm f-2",
|
14 |
+
"GoPro HERO9 with Built-in f-2.8 Ultra-Wide",
|
15 |
+
"Hasselblad 907X with Hasselblad XCD 30mm f-3.5",
|
16 |
+
"Hasselblad X1D II with Hasselblad XCD 65mm f-2.8",
|
17 |
+
"Kodak PIXPRO AZ901 with Built-in 4.3-258mm f-2.9-6.7",
|
18 |
+
"Leica CL with Leica Summilux-TL 35mm f-1.4 ASPH",
|
19 |
+
"Leica M10 with LEICA 35mm f-2 SUMMICRON-M ASPH",
|
20 |
+
"Leica Q2 with Summilux 28mm f-1.7 ASPH",
|
21 |
+
"Leica SL2 with Leica APO-Summicron-SL 50mm f-2 ASPH",
|
22 |
+
"Nikon Coolpix P950 with Built-in 24-2000mm f-2.8-6.5",
|
23 |
+
"Nikon D780 with Nikkor 14-24mm f-2.8G",
|
24 |
+
"Nikon D850 with Nikkor 50mm f-1.8",
|
25 |
+
"Nikon Z50 with Nikon Z DX 16-50mm f-3.5-6.3",
|
26 |
+
"Nikon Z6 II with Nikon Z 24-70mm f-4 S",
|
27 |
+
"Nikon Z7 with Nikon Z 70-200mm f-2.8 VR S",
|
28 |
+
"Olympus OM-D E-M1 Mark III with M.Zuiko 12-40mm f-2.8",
|
29 |
+
"Olympus OM-D E-M5 Mark III with M.Zuiko 40-150mm f-2.8",
|
30 |
+
"Olympus PEN-F with M.Zuiko 17mm f-1.8",
|
31 |
+
"Olympus Tough TG-6 with Built-in 4.5-18mm f-2-4.9",
|
32 |
+
"Panasonic Lumix G9 with Leica DG 42.5mm f-1.2",
|
33 |
+
"Panasonic Lumix GH5 with Leica DG 25mm f-1.4",
|
34 |
+
"Panasonic Lumix S5 with Lumix S PRO 70-200mm f-2.8 O.I.S",
|
35 |
+
"Panasonic S1R with Lumix S 50mm f-1.4",
|
36 |
+
"Pentax 645Z with Pentax-D FA 645 55mm f-2.8",
|
37 |
+
"Pentax K-1 Mark II with Pentax FA 43mm f-1.9 Limited",
|
38 |
+
"Pentax KP with Pentax HD DA 20-40mm f-2.8-4",
|
39 |
+
"Ricoh GR III with GR 18.3mm f-2.8",
|
40 |
+
"Sigma fp with Sigma 45mm f-2.8 DG DN",
|
41 |
+
"Sigma sd Quattro H with Sigma 24-70mm f-2.8 DG",
|
42 |
+
"Sony A1 with Sony FE 20mm f-1.8 G",
|
43 |
+
"Sony A6400 with Sony E 35mm f-1.8 OSS",
|
44 |
+
"Sony A7C with Sony FE 28-60mm f-4-5.6",
|
45 |
+
"Sony A7R IV with Sony FE 85mm f-1.4 GM",
|
46 |
+
"Sony A9 II with Sony FE 24-70mm f-2.8 GM",
|
47 |
+
"Sony RX100 VII with Built-in 24-200mm f-2.8-4.5"
|
48 |
+
]
|
data/digital_artform.json
ADDED
@@ -0,0 +1,70 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"Glitch Art art",
|
3 |
+
"Digital Painting art",
|
4 |
+
"Acrylic Paint art",
|
5 |
+
"Algorithmic art",
|
6 |
+
"Animation art",
|
7 |
+
"Art glass art",
|
8 |
+
"Assemblage art",
|
9 |
+
"Augmented reality art",
|
10 |
+
"Batik art",
|
11 |
+
"Beadwork art",
|
12 |
+
"Body painting art",
|
13 |
+
"Bookbinding art",
|
14 |
+
"Cast paper art",
|
15 |
+
"Ceramics art",
|
16 |
+
"Bronze art",
|
17 |
+
"Charcoal art",
|
18 |
+
"Collage art",
|
19 |
+
"Collagraphy art",
|
20 |
+
"Colored pencil art",
|
21 |
+
"Computer-generated imagery (cgi) art",
|
22 |
+
"Crochet art",
|
23 |
+
"Decoupage art",
|
24 |
+
"Digital sculpture art",
|
25 |
+
"Foam carving art",
|
26 |
+
"Found objects art",
|
27 |
+
"Fresco art",
|
28 |
+
"Glass art",
|
29 |
+
"Gouache art",
|
30 |
+
"Graffiti art",
|
31 |
+
"Ice art",
|
32 |
+
"Ink wash painting art",
|
33 |
+
"Installation art",
|
34 |
+
"Interactive media art",
|
35 |
+
"Lenticular printing art",
|
36 |
+
"Light projection art",
|
37 |
+
"Lithography art",
|
38 |
+
"Marble art",
|
39 |
+
"Metal art",
|
40 |
+
"Metalpoint art",
|
41 |
+
"Miniature painting art",
|
42 |
+
"Mixed media art",
|
43 |
+
"Monotype printing art",
|
44 |
+
"Neon art",
|
45 |
+
"Oil painting art",
|
46 |
+
"Origami art",
|
47 |
+
"Papier-mache art",
|
48 |
+
"Pastel art",
|
49 |
+
"Pen and ink art",
|
50 |
+
"Plastic arts",
|
51 |
+
"Polymer clay art",
|
52 |
+
"Printmaking art",
|
53 |
+
"Puppetry art",
|
54 |
+
"Pyrography art",
|
55 |
+
"Quilling art",
|
56 |
+
"Quilting art",
|
57 |
+
"Recycled art",
|
58 |
+
"Resin art",
|
59 |
+
"Sand art",
|
60 |
+
"Sound art",
|
61 |
+
"Silverpoint art",
|
62 |
+
"Spray paint art",
|
63 |
+
"Stone art",
|
64 |
+
"Tempera art",
|
65 |
+
"Tattoo art",
|
66 |
+
"Video art",
|
67 |
+
"Watercolor art",
|
68 |
+
"Wax art",
|
69 |
+
"Wood art"
|
70 |
+
]
|
data/hairstyles.json
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"with ((long hair))",
|
3 |
+
"with ((very curly hair))",
|
4 |
+
"with ((curly hair))",
|
5 |
+
"with ((pixie cut hair))",
|
6 |
+
"with ((bob cut hair))",
|
7 |
+
"with ((undercut hair))",
|
8 |
+
"with ((messy hair))",
|
9 |
+
"with ((mullet hair))",
|
10 |
+
"with ((braids))",
|
11 |
+
"with ((french braids))",
|
12 |
+
"with ((cornrows hair))",
|
13 |
+
"with ((ponytail hair))",
|
14 |
+
"with ((side part hair))",
|
15 |
+
"with ((mohawk hair))",
|
16 |
+
"with ((bun hair))",
|
17 |
+
"with ((pompadour hair))",
|
18 |
+
"with ((slicked back hair))",
|
19 |
+
"with ((asymmetrical cut hair))",
|
20 |
+
"with ((multicolored rainbow hair))",
|
21 |
+
"with ((balayage hair))",
|
22 |
+
"with ((french crop hair))",
|
23 |
+
"with ((shaved hair))",
|
24 |
+
"with ((shaved sides hair))",
|
25 |
+
"with ((side swept fringe))",
|
26 |
+
"with ((long bob haircut))",
|
27 |
+
"with ((a-line bob haircut))",
|
28 |
+
"with ((layered cut haircut))",
|
29 |
+
"with ((shag cut hair))",
|
30 |
+
"with ((buzz cut hair))",
|
31 |
+
"with ((feathered cut hair))",
|
32 |
+
"with ((blunt cut hair))",
|
33 |
+
"with ((undercut hair))",
|
34 |
+
"with ((french bob haircut))",
|
35 |
+
"with ((textured bob haircut))",
|
36 |
+
"with ((slicked-back haircut))",
|
37 |
+
"with ((wedge cut haircut))",
|
38 |
+
"with ((long layers haircut))",
|
39 |
+
"with ((curly bob haircut))",
|
40 |
+
"with ((cropped cut haircut))",
|
41 |
+
"with ((faux hawk haircut))",
|
42 |
+
"with ((angled bob haircut))",
|
43 |
+
"with ((razor cut haircut))",
|
44 |
+
"with ((emo haircut))",
|
45 |
+
"with ((curtain bangs haircut))",
|
46 |
+
"with ((waterfall braid haircut))",
|
47 |
+
"with ((fox braids haircut))",
|
48 |
+
"with ((chignon cut hair))",
|
49 |
+
"with ((pigtails))",
|
50 |
+
"with ((plait hair))",
|
51 |
+
"with ((ponytail))",
|
52 |
+
"with ((ringlets hair))",
|
53 |
+
"with ((curl hair))",
|
54 |
+
"with ((double bun topknot))",
|
55 |
+
"with ((drill cut hair))",
|
56 |
+
"with ((twintails hair))",
|
57 |
+
"with ((hair set up for wedding))",
|
58 |
+
"with ((wavy hair))",
|
59 |
+
"with ((beach waves hair))",
|
60 |
+
"with ((fishtail braid))",
|
61 |
+
"with ((dreadlocks))",
|
62 |
+
"with ((pin curls hair))",
|
63 |
+
"with ((twisted updo))",
|
64 |
+
"with ((hime cut hair))",
|
65 |
+
"with ((pull-through braid hair))",
|
66 |
+
"with ((Afro hair))",
|
67 |
+
"with ((crown braid))",
|
68 |
+
"with ((low fade haircut))",
|
69 |
+
"with ((man bun))",
|
70 |
+
"with ((finger waves hair))",
|
71 |
+
"with ((Dutch braids))",
|
72 |
+
"with ((tousled hair))",
|
73 |
+
"with ((princess cut hair))",
|
74 |
+
"with ((micro braids hair))",
|
75 |
+
"with ((lob haircut))",
|
76 |
+
"with ((senegalese twist hair))",
|
77 |
+
"with ((victory rolls hair))",
|
78 |
+
"with ((quiff haircut))",
|
79 |
+
"with ((mermaid waves hair))",
|
80 |
+
"with ((box braids))",
|
81 |
+
"with ((faux locs hair))",
|
82 |
+
"with ((bantu knots))",
|
83 |
+
"with ((spiral curls hair))"
|
84 |
+
]
|
data/lighting.json
ADDED
@@ -0,0 +1,124 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"popping colors, popart style",
|
3 |
+
"bokeh",
|
4 |
+
"dramatic",
|
5 |
+
"golden hour",
|
6 |
+
"depth of field",
|
7 |
+
"movie still",
|
8 |
+
"colorful",
|
9 |
+
"soft lighting",
|
10 |
+
"studio lighting with strong rim light",
|
11 |
+
"ambient lighting",
|
12 |
+
"sun rays",
|
13 |
+
"cinematic lighting",
|
14 |
+
"characteristics of the light",
|
15 |
+
"volumetric lighting",
|
16 |
+
"natural point rose",
|
17 |
+
"outdoor lighting",
|
18 |
+
"soft pastel lighting colors scheme",
|
19 |
+
"sensual lighting",
|
20 |
+
"neon lights",
|
21 |
+
"baroque",
|
22 |
+
"rokoko",
|
23 |
+
"rim light, iridescent accents",
|
24 |
+
"neoclassicism",
|
25 |
+
"realism",
|
26 |
+
"fantastic colors",
|
27 |
+
"surrealism",
|
28 |
+
"futurism",
|
29 |
+
"accent lighting",
|
30 |
+
"high key lighting",
|
31 |
+
"low key lighting",
|
32 |
+
"strong backlight",
|
33 |
+
"artificial lighting",
|
34 |
+
"decorative lighting",
|
35 |
+
"recessed lighting",
|
36 |
+
"wall sconces lighting",
|
37 |
+
"laser lighting",
|
38 |
+
"multi-colored lighting",
|
39 |
+
"mood lighting",
|
40 |
+
"accent lighting",
|
41 |
+
"projection lighting",
|
42 |
+
"bioluminiscent",
|
43 |
+
"plasma",
|
44 |
+
"ice",
|
45 |
+
"water",
|
46 |
+
"rule of thirds",
|
47 |
+
"anamorphic lens flare",
|
48 |
+
"sharp focus",
|
49 |
+
"vivid colors",
|
50 |
+
"masterpiece",
|
51 |
+
"colors",
|
52 |
+
"8k",
|
53 |
+
"atmospheric",
|
54 |
+
"cinematic sensual",
|
55 |
+
"hyperrealistic",
|
56 |
+
"big depth of field",
|
57 |
+
"glow effect",
|
58 |
+
"modelshoot style",
|
59 |
+
"shallow depth of field",
|
60 |
+
"hdr",
|
61 |
+
"dynamic composition",
|
62 |
+
"broad light",
|
63 |
+
"natural lighting",
|
64 |
+
"elegant pose",
|
65 |
+
"flowing",
|
66 |
+
"film photo",
|
67 |
+
"extremely detailed",
|
68 |
+
"big depth of field",
|
69 |
+
"matte skin, pores, wrinkles",
|
70 |
+
"hyperdetailed",
|
71 |
+
"(abstract:1.3)",
|
72 |
+
"intricate and low contrast detailed",
|
73 |
+
"(composition)",
|
74 |
+
"film grain",
|
75 |
+
"(8k, RAW photo, best quality, masterpiece:1.2)",
|
76 |
+
"(realistic, photo-realistic:1.37)",
|
77 |
+
"beautiful detailed eyes, beautiful detailed lips, a captivating gaze, and an alluring expression",
|
78 |
+
"beautiful dynamic dramatic dark moody lighting",
|
79 |
+
"(detailed face:1.3)",
|
80 |
+
"multilayered realism",
|
81 |
+
"majestically strides forward toward us with abandon",
|
82 |
+
"disintegrating moon",
|
83 |
+
"extremely intricate details",
|
84 |
+
"anatomical beauty",
|
85 |
+
"high fantasy",
|
86 |
+
"detailed skin pores",
|
87 |
+
"flat color scheme",
|
88 |
+
"80s music clip background",
|
89 |
+
"Use a backlighting effect to add depth to the image. impressionistic painting style, john singer sarget, blue pallette",
|
90 |
+
"(natural skin texture, hyperrealism, soft light, sharp:1.2)",
|
91 |
+
"(cinematic, teal and orange:0.85)",
|
92 |
+
"(intricate skin detail:1.3), (wrinkles:1.2),(skin blemishes:1.1),(skin pores:1.1),(detailed face:1.3), (lips slightly parted:1.0)",
|
93 |
+
"(muted colors, dim colors, soothing tones:1.3), low saturation, (hyperdetailed:1.2)",
|
94 |
+
"(noir:0.4), (intricate details:1.12), hdr, (intricate details, hyperdetailed:1.15)",
|
95 |
+
"(neutral colors:1.2), art, (hdr:1.5), (muted colors:1.1), (pastel:0.2), hyperdetailed",
|
96 |
+
"dramatic lighting",
|
97 |
+
"((landscape view)), 4k unity, (best illumination)",
|
98 |
+
"dynamic angle",
|
99 |
+
"detailed freckles skin",
|
100 |
+
"movie grain",
|
101 |
+
"epic composition",
|
102 |
+
"Tarot Card style",
|
103 |
+
"(solo focus, one frame)",
|
104 |
+
"(masterpiece, best quality, ultra-detailed, highres)",
|
105 |
+
"biopunk",
|
106 |
+
"dramatic Pull from the ghost of a virtual memory",
|
107 |
+
"gritty industrial",
|
108 |
+
"triadic color palette",
|
109 |
+
"Monochromatic color palette",
|
110 |
+
"Analogous color palette",
|
111 |
+
"Complementary color palette",
|
112 |
+
"Split-Complementary color palette",
|
113 |
+
"Double Complementary (Tetradic) color palette",
|
114 |
+
"Square color palette",
|
115 |
+
"Rectangular (Tetradic) color palette",
|
116 |
+
"Neutral color palette",
|
117 |
+
"Pastel color palette",
|
118 |
+
"Warm color palette",
|
119 |
+
"Cool color palette",
|
120 |
+
"Earth Tone color palette",
|
121 |
+
"Jewel Tone color palette",
|
122 |
+
"Muted color palette",
|
123 |
+
"High Contrast"
|
124 |
+
]
|
data/photo_framing.json
ADDED
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"extreme close-up",
|
3 |
+
"close-up",
|
4 |
+
"medium close-up",
|
5 |
+
"medium shot",
|
6 |
+
"long shot",
|
7 |
+
"establishing shot",
|
8 |
+
"medium full shot",
|
9 |
+
"full shot",
|
10 |
+
"upper body shot",
|
11 |
+
"full body shot"
|
12 |
+
]
|
data/photo_type.json
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"front view",
|
3 |
+
"bilaterally symmetrical",
|
4 |
+
"side view",
|
5 |
+
"back view",
|
6 |
+
"from above",
|
7 |
+
"from below",
|
8 |
+
"from behind",
|
9 |
+
"wide angle view",
|
10 |
+
"fisheyes view",
|
11 |
+
"macro view",
|
12 |
+
"overhead shot",
|
13 |
+
"top down",
|
14 |
+
"birds eye view",
|
15 |
+
"high angle",
|
16 |
+
"slightly above",
|
17 |
+
"straight on",
|
18 |
+
"hero view",
|
19 |
+
"low view",
|
20 |
+
"selfie"
|
21 |
+
]
|
data/photographer.json
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"Alessio Albi",
|
3 |
+
"Alvin Langdon Coburn",
|
4 |
+
"Anne Brigman",
|
5 |
+
"Ansel Adams",
|
6 |
+
"Anton Corbijn",
|
7 |
+
"Berenice Abbott",
|
8 |
+
"Bill Brandt",
|
9 |
+
"Brooke DiDonato",
|
10 |
+
"Bruce Davidson",
|
11 |
+
"Bruno Barbey",
|
12 |
+
"Chris Burkard",
|
13 |
+
"Claude Cahun",
|
14 |
+
"David Bailey",
|
15 |
+
"David Burdeny",
|
16 |
+
"Dawoud Bey",
|
17 |
+
"Diane Arbus",
|
18 |
+
"Dirk Braeckman",
|
19 |
+
"Edward Burtynsky",
|
20 |
+
"Edward S. Curtis",
|
21 |
+
"Elina Brotherus",
|
22 |
+
"Elsa Bleda",
|
23 |
+
"Erwin Blumenfeld",
|
24 |
+
"Flora Borsi",
|
25 |
+
"Gregory Colbert",
|
26 |
+
"Gregory Crewdson",
|
27 |
+
"Guy Aroch",
|
28 |
+
"Guy Bourdin",
|
29 |
+
"Hans Bellmer",
|
30 |
+
"Harry Benson",
|
31 |
+
"Harry Callahan",
|
32 |
+
"Henri Cartier-Bresson",
|
33 |
+
"Ilse Bing",
|
34 |
+
"Imogen Cunningham",
|
35 |
+
"Iwan Baan",
|
36 |
+
"James Balog",
|
37 |
+
"Jamie Baldridge",
|
38 |
+
"James Balog",
|
39 |
+
"Julia Margaret Cameron",
|
40 |
+
"Julie Blackmon",
|
41 |
+
"Karl Blossfeldt",
|
42 |
+
"Katia Chausheva",
|
43 |
+
"Keith Carter",
|
44 |
+
"Larry Burrows",
|
45 |
+
"Larry Clark",
|
46 |
+
"Laurent Baheux",
|
47 |
+
"Lewis Baltz",
|
48 |
+
"Lillian Bassman",
|
49 |
+
"Lynsey Addario",
|
50 |
+
"Margaret Bourke-White",
|
51 |
+
"Marianne Breslauer",
|
52 |
+
"Marta Bevacqua",
|
53 |
+
"Mathew Brady",
|
54 |
+
"Miki Asai",
|
55 |
+
"Miles Aldridge",
|
56 |
+
"Nick Brandt",
|
57 |
+
"Nobuyoshi Araki",
|
58 |
+
"Olive Cotton",
|
59 |
+
"Patrick Demarchelier",
|
60 |
+
"Paul Barson",
|
61 |
+
"Petra Collins",
|
62 |
+
"Petra Collins",
|
63 |
+
"Richard Avedon",
|
64 |
+
"Rineke Dijkstra",
|
65 |
+
"Robby Cavanaugh",
|
66 |
+
"Robert Adams",
|
67 |
+
"Robert Capa",
|
68 |
+
"Roger Ballen",
|
69 |
+
"Ruth Bernhard",
|
70 |
+
"Slim Aarons",
|
71 |
+
"Tami Bone",
|
72 |
+
"Tina Barney",
|
73 |
+
"Vanley Burke"
|
74 |
+
]
|
data/photography_styles.json
ADDED
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"high fashion photography",
|
3 |
+
"avant garde photography",
|
4 |
+
"fashion photography",
|
5 |
+
"portrait photography",
|
6 |
+
"landscape photography",
|
7 |
+
"documentary photography",
|
8 |
+
"street photography",
|
9 |
+
"action photography",
|
10 |
+
"vintage photography"
|
11 |
+
]
|
data/place.json
ADDED
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"indoor",
|
3 |
+
"outdoor",
|
4 |
+
"at night",
|
5 |
+
"in the park",
|
6 |
+
"studio",
|
7 |
+
"at a party",
|
8 |
+
"at a festival",
|
9 |
+
"at a concert",
|
10 |
+
"on persons home planet",
|
11 |
+
"magical portal with particles",
|
12 |
+
"in a neon lit city",
|
13 |
+
"in a cyberpunk city",
|
14 |
+
"in a fantasy world",
|
15 |
+
"glamour photography",
|
16 |
+
"fashion photography",
|
17 |
+
"at home",
|
18 |
+
"at work",
|
19 |
+
"at a cafe",
|
20 |
+
"at a gym",
|
21 |
+
"at a hotel",
|
22 |
+
"at a concert performance",
|
23 |
+
"at the beach",
|
24 |
+
"at a museum",
|
25 |
+
"in a hidden city deep in the rainforest",
|
26 |
+
"in a floating island in the sky",
|
27 |
+
"in an underground world beneath the earths surface ",
|
28 |
+
"in a secret garden hidden in a mysterious maze",
|
29 |
+
"in a grand castle on the top of a remote mountain",
|
30 |
+
"in a enchanted forest with talking animals and magical creatures",
|
31 |
+
"in a mystical island filled with ancient ruins and hidden treasure",
|
32 |
+
"in a faraway planet with a unique and alien landscape",
|
33 |
+
"in a hidden paradise hidden behind a waterfall",
|
34 |
+
"in a dreamlike world where anything is possible and the impossible is real",
|
35 |
+
"in a hidden oasis in the desert",
|
36 |
+
"in a secret underground city",
|
37 |
+
"in an underwater kingdom",
|
38 |
+
"in a lost temple in the jungle",
|
39 |
+
"in a castle in the clouds",
|
40 |
+
"in a hidden valley in the mountains",
|
41 |
+
"in a uturistic city on a distant planet",
|
42 |
+
"in a mystical land of eternal twilight",
|
43 |
+
"Smoke and ash in the air",
|
44 |
+
"suburban america",
|
45 |
+
"suburbs",
|
46 |
+
"slums",
|
47 |
+
"at the sea",
|
48 |
+
"at the ocean",
|
49 |
+
"at the lake",
|
50 |
+
"at the river",
|
51 |
+
"at the waterfall",
|
52 |
+
"in the labyrinth",
|
53 |
+
"in a lab",
|
54 |
+
"rendered in a 2.5D isometric perspective. Soft gradients add dimension, pastel color scheme",
|
55 |
+
"in an ancient enchanted forest",
|
56 |
+
"atop a floating sky island",
|
57 |
+
"inside a crystal cavern",
|
58 |
+
"beside a shimmering fairy pond",
|
59 |
+
"in the ruins of a forgotten temple",
|
60 |
+
"at the heart of a magical vortex",
|
61 |
+
"on the steps of a celestial palace",
|
62 |
+
"in the lair of a mythical beast",
|
63 |
+
"on the shores of an eldritch sea",
|
64 |
+
"within the walls of a dreamer's fortress",
|
65 |
+
"in a neon-lit back alley market",
|
66 |
+
"atop a towering megastructure",
|
67 |
+
"inside a virtual reality dive bar",
|
68 |
+
"beneath the city in the techno catacombs",
|
69 |
+
"on the bustling streets of the augmented metropolis",
|
70 |
+
"at a clandestine hacker's hideout",
|
71 |
+
"in a hover-car chase through the cityscape",
|
72 |
+
"at a black market cybernetics clinic",
|
73 |
+
"within a digital data fortress in cyberspace",
|
74 |
+
"on a rain-soaked rooftop overlooking the neon sprawl",
|
75 |
+
"aboard a sprawling interstellar spaceship",
|
76 |
+
"on a distant planet's alien landscape",
|
77 |
+
"inside a high-tech orbital space station",
|
78 |
+
"at a bustling galactic trade hub",
|
79 |
+
"within the depths of a biomechanical hive",
|
80 |
+
"on a terraformed Martian colony",
|
81 |
+
"in the heart of a quantum singularity",
|
82 |
+
"at a futuristic AI-controlled mega-city",
|
83 |
+
"within the virtual realms of a digital utopia",
|
84 |
+
"on the observation deck of a cosmic observatory",
|
85 |
+
"inside the belly of a gigantic jellyfish floating in space",
|
86 |
+
"on a floating island made entirely of candy and sweets",
|
87 |
+
"within a dimension where colors sing and sounds have taste",
|
88 |
+
"at a bazaar selling bottled dreams and captured starlight",
|
89 |
+
"on a roller coaster weaving through time and memories",
|
90 |
+
"in a library where books sprout legs and share their tales",
|
91 |
+
"on a planet where the oceans are made of liquid crystal",
|
92 |
+
"at a dance party hosted by interdimensional beings on the rings of Saturn",
|
93 |
+
"on a beach where the sand is made of tiny glowing stars"
|
94 |
+
]
|
data/pose.json
ADDED
@@ -0,0 +1,344 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"standing straight, facing camera, leaf in hand",
|
3 |
+
"standing, hands on surface, facing camera",
|
4 |
+
"one arm bent, hip jutted out, direct gaze",
|
5 |
+
"standing straight, hands on pads, confident stance",
|
6 |
+
"hands raised, slight twist, standing straight",
|
7 |
+
"standing straight, hands resting, slight smile",
|
8 |
+
"sitting, relaxed, facing camera",
|
9 |
+
"hand in hair, standing straight, slight smile",
|
10 |
+
"hands on hips, straight posture, direct gaze",
|
11 |
+
"standing straight, left arm raised, right arm down, facing camera",
|
12 |
+
"standing straight, left arm raised, right arm bent, facing camera",
|
13 |
+
"standing straight, hands on hips, head slightly tilted",
|
14 |
+
"holding hair, straight stance, direct gaze",
|
15 |
+
"standing straight, hands relaxed, confident stance",
|
16 |
+
"standing straight, hand on hip, looking at camera",
|
17 |
+
"standing straight, hands clasping bag, weight on right leg, smiling",
|
18 |
+
"seated, arm raised, head tilted",
|
19 |
+
"facing forward, slight tilt, relaxed stance",
|
20 |
+
"standing pose, hands on ledge, facing camera",
|
21 |
+
"standing straight, relaxed arms, holding bottle",
|
22 |
+
"standing straight, facing camera, hands on hips",
|
23 |
+
"leaning forward, hands on thighs, slight smile",
|
24 |
+
"arms crossed, head slightly tilted, direct gaze",
|
25 |
+
"hand on head, standing straight, slight twist, confident stance",
|
26 |
+
"standing straight, hands on hips, facing camera",
|
27 |
+
"facing camera, slight head tilt, relaxed posture",
|
28 |
+
"standing upright, slight smile, facing camera",
|
29 |
+
"standing straight, hands together, slight smile",
|
30 |
+
"facing camera, seated position, hands on knees",
|
31 |
+
"standing straight, hands on hips, facing camera",
|
32 |
+
"facing away, head turned, slight twist",
|
33 |
+
"standing straight, hands on shorts, slightly tilted head",
|
34 |
+
"standing upright, hands raised, interlocked above head, one leg straight, other bent, facing camera",
|
35 |
+
"standing straight, hand on hip, slight bend in right knee, head tilted",
|
36 |
+
"standing straight, hands together, direct gaze",
|
37 |
+
"sitting down, crossed legs, leaning forward",
|
38 |
+
"standing upright, hands on hips, facing forward",
|
39 |
+
"hands on hips, facing camera, confident stance",
|
40 |
+
"facing camera, head tilted, subtle smile",
|
41 |
+
"standing upright, arms raised, hand in hair",
|
42 |
+
"leaning on railing, facing camera, arms apart, straight posture",
|
43 |
+
"sitting down, facing camera, head slightly tilted",
|
44 |
+
"standing straight, looking forward, left hand holding bag",
|
45 |
+
"hands on hips, standing straight, slight body twist",
|
46 |
+
"facing camera, arms crossed, slight smile",
|
47 |
+
"facing camera, gentle gaze, holding arm",
|
48 |
+
"standing upright, arms relaxed, looking forward",
|
49 |
+
"sitting cross-legged, hands on ankles, direct gaze",
|
50 |
+
"standing straight, slight head tilt, direct gaze",
|
51 |
+
"standing upright, hands on hips, slight smile",
|
52 |
+
"standing upright, hand on jacket, confident stance",
|
53 |
+
"standing upright, hands on hips, facing camera",
|
54 |
+
"standing upright, one hand holding object, slight body turn",
|
55 |
+
"sitting, hand on head, legs crossed",
|
56 |
+
"standing upright, hands on hips, looking forward",
|
57 |
+
"seated, open-legged, arms resting",
|
58 |
+
"head turned, gazing upward, flowing hair",
|
59 |
+
"head tilted, hand on chin, direct gaze",
|
60 |
+
"sitting down, one arm resting, head slightly tilted",
|
61 |
+
"facing camera, slightly tilted head, relaxed posture",
|
62 |
+
"facing camera, head tilted, relaxed stance",
|
63 |
+
"facing camera, slight smile, left arm raised",
|
64 |
+
"sitting, smiling, relaxed posture",
|
65 |
+
"facing camera, slight smile, straight posture",
|
66 |
+
"kneeling, hand on forehead, looking at camera",
|
67 |
+
"facing camera, slight smile, relaxed stance",
|
68 |
+
"facing camera, slight smile, head slightly tilted",
|
69 |
+
"facing camera, slight head tilt, relaxed stance",
|
70 |
+
"looking forward, slight head tilt, relaxed posture",
|
71 |
+
"facing camera, slight smile, relaxed stance",
|
72 |
+
"looking forward, slight smile, head tilted",
|
73 |
+
"squatting position, hands in hair, eyes closed",
|
74 |
+
"facing camera, slight head tilt, relaxed shoulders",
|
75 |
+
"head tilted, looking forward, hair swept aside",
|
76 |
+
"hand in hair, facing camera, slight tilt",
|
77 |
+
"facing camera, slight smile, head tilted",
|
78 |
+
"hand on hat, facing camera, slightly leaning",
|
79 |
+
"hand on cheek, sitting down, head slightly tilted",
|
80 |
+
"facing camera, slight smile, head tilted",
|
81 |
+
"tilted head, hand lifting jacket, direct gaze",
|
82 |
+
"looking at camera, slightly tilted head, touching hair",
|
83 |
+
"arms raised, elbows bent, flexing biceps, confident stance",
|
84 |
+
"facing camera, slight tilt, relaxed posture",
|
85 |
+
"seated, slightly leaning, facing camera",
|
86 |
+
"hand in hair, leaning elbow, direct gaze, slightly parted lips",
|
87 |
+
"head tilted, hand in hair, looking at camera, slight smile",
|
88 |
+
"sitting, hands on thighs, direct gaze",
|
89 |
+
"head tilted slightly, eyes looking forward, hand touching hair",
|
90 |
+
"head tilted, hand on neck, relaxed demeanor, bare shoulders",
|
91 |
+
"sitting down, crossed legs, looking downward, one hand near neck",
|
92 |
+
"smiling faces, direct gaze, group hug",
|
93 |
+
"seated position, smiling expression, facing camera",
|
94 |
+
"facing camera, slight smile, relaxed stance",
|
95 |
+
"sitting down, facing camera, one leg bent",
|
96 |
+
"smiling, peace sign, looking forward, head tilted",
|
97 |
+
"facing camera, slight smile, head tilted",
|
98 |
+
"facing camera, slight smile, touching neck, hairclips in hair",
|
99 |
+
"kneeling position, hand in hair, confident gaze, slight smile",
|
100 |
+
"facing camera, slight smile, head tilted",
|
101 |
+
"seated, leaning forward, smiling",
|
102 |
+
"sitting, one leg bent, one leg extended, leaning forward, arms resting",
|
103 |
+
"sitting down, arms crossed, facing camera",
|
104 |
+
"standing, arm raised, facing camera",
|
105 |
+
"seated, relaxed, looking aside",
|
106 |
+
"facing camera, slight smile, relaxed posture",
|
107 |
+
"facing camera, slightly tilted head, relaxed posture",
|
108 |
+
"slight tilt, looking at camera, relaxed posture",
|
109 |
+
"facing forward, slight tilt, confident expression",
|
110 |
+
"straight standing, head tilted, gaze at camera",
|
111 |
+
"head tilt, slight smile, looking at camera",
|
112 |
+
"looking at camera, slight head tilt, relaxed posture",
|
113 |
+
"facing camera, slightly tilted head, one arm visible",
|
114 |
+
"facing camera, slight smile, relaxed stance",
|
115 |
+
"head cocked, hand on chin, looking at camera, slight smile",
|
116 |
+
"facing camera, slightly tilted head, relaxed posture",
|
117 |
+
"kneeling down, facing camera, leaning forward",
|
118 |
+
"facing camera, slight head tilt, pouting lips",
|
119 |
+
"hand on face, leaning slightly, intense gaze",
|
120 |
+
"smiling, hugging children, direct gaze",
|
121 |
+
"leaning forward, one leg raised, playful gesture",
|
122 |
+
"hand in hair, slight tilt, bending forward",
|
123 |
+
"facing camera, slight tilt head, one hand raised",
|
124 |
+
"standing upright, looking forward, relaxed arms",
|
125 |
+
"sitting down, arms rested, legs crossed",
|
126 |
+
"crouching down, chin resting, looking sideways",
|
127 |
+
"squatting position, head tilt, one hand raised",
|
128 |
+
"leaning on tree, gently touching hair, standing pose, eyes closed, relaxed demeanor",
|
129 |
+
"sitting, leaning slightly, smiling",
|
130 |
+
"standing sideways, looking back, slightly bent torso",
|
131 |
+
"gazing forward, slight head tilt, hair pulled back",
|
132 |
+
"sitting down, hand in hair, looking sideways",
|
133 |
+
"hand in hair, looking away, slight twist",
|
134 |
+
"facing camera, slightly tilted head, one-shoulder visible",
|
135 |
+
"facing camera, slight smile, head tilted",
|
136 |
+
"head tilted, slight smile, looking at camera",
|
137 |
+
"facing camera, slight tilt, soft expression",
|
138 |
+
"seated, arms crossed, legs bent",
|
139 |
+
"head tilt, gazing upwards, holding flowers",
|
140 |
+
"head tilted, hand raised, playful expression",
|
141 |
+
"leaning forward, knee up, hand on forehead, gazing at camera",
|
142 |
+
"leaning forward, hand on chin, thoughtful expression",
|
143 |
+
"sitting down, facing camera, slight tilt",
|
144 |
+
"sitting, arm raised, head tilted",
|
145 |
+
"facing camera, slight tilt head, relaxed posture",
|
146 |
+
"head turned, looking back, hand on hip",
|
147 |
+
"hands on face, slight head tilt, looking at camera",
|
148 |
+
"facing camera, relaxed posture, slightly parted lips",
|
149 |
+
"facing camera, slight tilt, soft gaze",
|
150 |
+
"standing, facing camera, hand on neck",
|
151 |
+
"arms crossed, slight smile, looking away",
|
152 |
+
"leaning forward, hands under chin, looking at camera",
|
153 |
+
"seated, hand on head, torso twisted",
|
154 |
+
"looking at camera, slightly angled, relaxed posture",
|
155 |
+
"facing camera, relaxed stance, slight smile",
|
156 |
+
"hand on chin, looking forward, slight tilt",
|
157 |
+
"head tilted, hand in hair, facing camera",
|
158 |
+
"looking forward, hand on head, slightly tilted head",
|
159 |
+
"pouting lips, holding phone, slightly tilted head",
|
160 |
+
"standing straight, left hand raised, smiling at camera",
|
161 |
+
"seated, slightly leaning, soft smile",
|
162 |
+
"sitting, legs crossed, facing camera, relaxed posture",
|
163 |
+
"sitting on floor, looking at camera, one leg bent",
|
164 |
+
"standing straight, hands on hips, smiling",
|
165 |
+
"standing straight, hands near face, facing camera",
|
166 |
+
"hand in hair, slightly turned, standing upright",
|
167 |
+
"standing pose, slightly bent arm, hand touching hair, hip tilted, confident stance, half-turned towards camera, relaxed facial expression",
|
168 |
+
"standing, arms raised, facing camera",
|
169 |
+
"seated position, looking forward, slight tilt, relaxed posture",
|
170 |
+
"standing pose, one hand raised, facing camera, hip jutted",
|
171 |
+
"sitting down, one hand on knee, head slightly tilted",
|
172 |
+
"standing, slightly angled, hand on hip",
|
173 |
+
"standing straight, slightly angled, hands on bag",
|
174 |
+
"standing straight, hand on hip, head slightly tilted",
|
175 |
+
"squatting position, left arm resting, right hand on waist",
|
176 |
+
"sitting on bench, leaning forward, casually posed",
|
177 |
+
"Kneeling, leaning forward, gaze at camera",
|
178 |
+
"sitting, hand gesture, legs crossed",
|
179 |
+
"Standing straight, slight smile, looking at camera",
|
180 |
+
"hands raised, head tilt, standing straight",
|
181 |
+
"standing straight, left hand raised, facing camera",
|
182 |
+
"straight posture, slight lean, direct gaze",
|
183 |
+
"standing straight, arms relaxed, facing camera",
|
184 |
+
"standing upright, left hand on hip, slight left twist, right arm hanging",
|
185 |
+
"standing straight, hand in hair, slight body turn",
|
186 |
+
"crouching, looking at camera, hands on knees",
|
187 |
+
"standing upright, hand in hair, slight twist",
|
188 |
+
"standing straight, left hand adjusting sunglasses, right hand on hip, facing camera",
|
189 |
+
"standing straight, hands together, slight body turn",
|
190 |
+
"standing upright, one leg crossed, hands on hip",
|
191 |
+
"standing straight, hands on pads, front-facing",
|
192 |
+
"standing straight, hands relaxed, facing camera",
|
193 |
+
"standing straight, hands on hips, smiling, facing camera",
|
194 |
+
"standing upright, hands touching, slightly turned",
|
195 |
+
"standing straight, hands by side, direct gaze",
|
196 |
+
"walking forward, left leg forward, slight smile",
|
197 |
+
"seated position, leaning forward, one leg bent",
|
198 |
+
"standing straight, hands on hips, looking at camera",
|
199 |
+
"standing, slightly turned, casual hold of pants, relaxed posture, sunglass on head",
|
200 |
+
"facing camera, slight smile, hand on hip",
|
201 |
+
"leaning forward, arching back, looking away",
|
202 |
+
"standing straight, hands together, looking forward",
|
203 |
+
"sitting down, facing camera, slight smile",
|
204 |
+
"sitting, one leg crossed, looking at camera, confident stance",
|
205 |
+
"standing straight, slight smile, left hand holding purse, right hand relaxed",
|
206 |
+
"sitting down, legs crossed, left hand resting, right hand on thigh, direct gaze",
|
207 |
+
"sitting down, holding phone, legs crossed",
|
208 |
+
"left: standing straight, right hand raised, left: standing, hand on hip",
|
209 |
+
"seated on couch, leaning forward, hands supporting chin, legs crossed, eyes looking upward",
|
210 |
+
"sitting, arm raised, head tilted",
|
211 |
+
"sitting down, legs bent, hands on knee, relaxed demeanor",
|
212 |
+
"standing, facing camera, hand on face",
|
213 |
+
"hand on head, facing camera, slightly smiling",
|
214 |
+
"Standing straight, hands on hips, facing camera",
|
215 |
+
"standing straight, holding object, slight twist",
|
216 |
+
"sitting down, eyes closed, head slightly tilted, holding dress",
|
217 |
+
"sitting down, crossed legs, hands on legs, facing camera",
|
218 |
+
"standing beside bicycle, holding handlebars, facing camera",
|
219 |
+
"sitting, crossed legs, relaxed posture, hand on knee",
|
220 |
+
"bending forward, one hand on car, looking at camera",
|
221 |
+
"standing upright, leaning slightly, one arm raised",
|
222 |
+
"standing upright, one hand raised, facing camera",
|
223 |
+
"Sitting down, slightly leaned forward, direct gaze",
|
224 |
+
"hand on head, standing straight, facing camera, confident stance",
|
225 |
+
"sitting, one leg raised, engaged expression",
|
226 |
+
"hands in hair, seated, legs crossed",
|
227 |
+
"three-quarter view, standing upright, looking over shoulder",
|
228 |
+
"standing upright, slight hip tilt, arms relaxed",
|
229 |
+
"crouching, looking forward, left hand on ground, right arm resting on leg",
|
230 |
+
"standing straight, left hand touching hair, facing camera",
|
231 |
+
"standing straight, slight hip tilt, right arm bent",
|
232 |
+
"sitting, one leg raised, facing camera",
|
233 |
+
"sitting, one knee raised, looking at camera",
|
234 |
+
"standing, one arm raised, facing camera",
|
235 |
+
"standing upright, slight body turn, left hand on hip, right hand holding object",
|
236 |
+
"sitting down, smiling, holding a drink",
|
237 |
+
"standing, facing camera, biting ice cream",
|
238 |
+
"hand on hip, slight body tilt, chin down, forward-facing",
|
239 |
+
"standing upright, relaxed posture, facing camera",
|
240 |
+
"hand in hair, arched back, seductive stance",
|
241 |
+
"standing, three-quarter view, left hand on hip",
|
242 |
+
"standing straight, hands on thighs, facing camera",
|
243 |
+
"sitting on chair, legs crossed, leaning forward, holding drink, looking at camera",
|
244 |
+
"crouching, smiling, looking forward",
|
245 |
+
"sitting, right leg bent, left arm raised",
|
246 |
+
"Direct gaze, slight smile, hand in hair",
|
247 |
+
"sitting, legs crossed, hands on knee",
|
248 |
+
"standing upright, hand in hair, smiling",
|
249 |
+
"arm raised, bent elbow, one leg forward, standing pose, confident stance",
|
250 |
+
"Standing pose, one leg crossed, hand on hip, facing camera",
|
251 |
+
"sitting, hand in hair, facing camera",
|
252 |
+
"standing upright, slight smile, one hand holding bag",
|
253 |
+
"standing upright, hands by side, direct gaze",
|
254 |
+
"Standing pose, facing camera, slight tilt",
|
255 |
+
"standing straight, left hand on sunglasses, right hand holding purse",
|
256 |
+
"standing upright, hands on hips, relaxed posture",
|
257 |
+
"sitting down, touching hat, smiling",
|
258 |
+
"leaning on wall, looking at camera, one leg raised",
|
259 |
+
"seated, legs spread, head tilted down",
|
260 |
+
"standing straight, hands by side, direct gaze",
|
261 |
+
"standing upright, holding book, slight body turn",
|
262 |
+
"sitting down, leaning back, smiling, leg crossed",
|
263 |
+
"standing straight, left hand on hip, right hand holding bag",
|
264 |
+
"standing straight, hands on hips, slight smile",
|
265 |
+
"facing camera, slight smile, relaxed posture, left hand on hip, right hand by side",
|
266 |
+
"standing upright, directly facing camera, relaxed stance",
|
267 |
+
"arms on table, standing straight, slight torso twist",
|
268 |
+
"standing straight, facing camera, holding phone",
|
269 |
+
"standing, left leg forward, hand on waist",
|
270 |
+
"standing upright, hands together, facing camera",
|
271 |
+
"hands on hips, slight lean, confident stance",
|
272 |
+
"reclining, arms raised, directly facing camera, relaxed demeanor",
|
273 |
+
"sitting, one hand holding glass, crossed legs",
|
274 |
+
"standing upright, slightly tilted head, holding hair",
|
275 |
+
"standing upright, slight twist, left hand adjusting, looking at camera",
|
276 |
+
"sitting down, legs crossed, looking at phone",
|
277 |
+
"standing upright, looking forward, hands on stomach, slight smile, casual stance",
|
278 |
+
"standing, one hand holding phone, slight body turn",
|
279 |
+
"sitting pose, one hand on chin, legs crossed, head slightly tilted",
|
280 |
+
"sitting down, hand on cheek, one leg crossed",
|
281 |
+
"one leg extended, leaning back, direct gaze",
|
282 |
+
"leaning back, one leg bent, one leg extended, confident gaze",
|
283 |
+
"facing camera, slightly tilted head, resting arms",
|
284 |
+
"standing upright, DJing, slight smile",
|
285 |
+
"standing upright, left leg forward, hands on thighs, facing camera",
|
286 |
+
"standing upright, arm raised, smiling",
|
287 |
+
"sitting down, slightly leaning forward, facing camera",
|
288 |
+
"seated, relaxed posture, looking forward",
|
289 |
+
"standing straight, hand on hip, slight smile, head tilted",
|
290 |
+
"standing, one arm bent, holding dumbbell, looking forward",
|
291 |
+
"walking, left profile, one foot forward",
|
292 |
+
"Leaning back, angled towards camera, relaxed posture",
|
293 |
+
"looking back, slight twist, right hand resting",
|
294 |
+
"facing away, looking back, left hand raised",
|
295 |
+
"standing, arms raised, hands touching",
|
296 |
+
"sitting down, casual posture",
|
297 |
+
"standing straight, hands on hips, direct gaze",
|
298 |
+
"half-turned, looking back, one arm bent",
|
299 |
+
"arm raised, standing straight, looking forward",
|
300 |
+
"sitting, legs bent, relaxed posture",
|
301 |
+
"sitting down, facing camera, slightly tilted head",
|
302 |
+
"turned sideways, lifting dumbbells, slight bend in knees",
|
303 |
+
"hand on head, slightly turned, standing straight",
|
304 |
+
"standing straight, slight smile, right hand on hip, facing camera",
|
305 |
+
"leaning against wall, one leg bent, looking over shoulder",
|
306 |
+
"sitting, hand on chin, crossed legs",
|
307 |
+
"standing straight, slight twist, gazing forward, relaxed posture, hands not visible",
|
308 |
+
"sitting down, arms raised, head tilted",
|
309 |
+
"leaning on railing, facing camera, slight smile",
|
310 |
+
"sitting, arms raised, looking at camera",
|
311 |
+
"sitting, arms raised, head tilted",
|
312 |
+
"standing, holding bike, facing camera",
|
313 |
+
"standing straight, hands on hips, direct gaze",
|
314 |
+
"standing straight, hand on head, facing away",
|
315 |
+
"sitting, facing away, relaxed posture",
|
316 |
+
"facing away, head turned, one hand touching thigh",
|
317 |
+
"standing pose, leaning on counter, one arm bent, looking at camera",
|
318 |
+
"smiling, facing camera, relaxed stance",
|
319 |
+
"Standing straight, hands on hips, slight smile, looking forward",
|
320 |
+
"looking over shoulder, three-quarter turn, hand on hip",
|
321 |
+
"hand in hair, kneeling position, direct gaze, left leg bent, confident expression",
|
322 |
+
"facing camera, arms crossed, slight tilt",
|
323 |
+
"leaning forward, looking to the side, one hand on hip",
|
324 |
+
"arms crossed, looking at camera, slight head tilt",
|
325 |
+
"kneeling, leaning forward, hands on handles",
|
326 |
+
"leaning forwards, hand on head, facing camera",
|
327 |
+
"standing upright, hands on hips, confident stance",
|
328 |
+
"straight standing, hands together, slight smile",
|
329 |
+
"looking back, slight twist, hand on hip",
|
330 |
+
"Sitting down, facing camera, holding glass",
|
331 |
+
"standing upright, hand in hair, facing camera",
|
332 |
+
"standing, leaning on wall, holding glass, crossed legs",
|
333 |
+
"head tilted, sitting, hand on neck",
|
334 |
+
"standing, looking back, hand on thigh",
|
335 |
+
"sitting, hand on face, legs crossed, relaxed demeanor",
|
336 |
+
"standing, hands on head, eyes closed",
|
337 |
+
"standing upright, facing camera, slight twist",
|
338 |
+
"hand on hat, slightly turned, mid-walk stance",
|
339 |
+
"facing sideways, slight twist, playful stance",
|
340 |
+
"Standing upright, Left hand holding flower, Right hand on hip, Gazing forward",
|
341 |
+
"standing upright, hands on hips, smiling face",
|
342 |
+
"standing upright, arm raised, indirect gaze",
|
343 |
+
"sitting down, hand on head, legs bent, relaxed posture"
|
344 |
+
]
|
data/roles.json
ADDED
@@ -0,0 +1,206 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
[
|
2 |
+
"as a ((cyborg))",
|
3 |
+
"as an ((x-men character))",
|
4 |
+
"as a ((marvel character))",
|
5 |
+
"as a ((character from lord of the rings))",
|
6 |
+
"as a ((superhero character))",
|
7 |
+
"as a ((scifi character))",
|
8 |
+
"as a ((character from star wars))",
|
9 |
+
"as a ((character from star trek))",
|
10 |
+
"as a ((character from the matrix))",
|
11 |
+
"as a ((character from the tv show the boys))",
|
12 |
+
"as a ((glamour model))",
|
13 |
+
"as a ((fashion model))",
|
14 |
+
"as a ((greek god))",
|
15 |
+
"as a ((norse god))",
|
16 |
+
"as a ((egyptian god))",
|
17 |
+
"as a ((construction worker))",
|
18 |
+
"as a ((teacher))",
|
19 |
+
"as a ((body builder))",
|
20 |
+
"as a ((pirate))",
|
21 |
+
"as a ((sanitation worker))",
|
22 |
+
"as a ((plumber))",
|
23 |
+
"as an ((electrician))",
|
24 |
+
"as a ((carpenter))",
|
25 |
+
"as a ((mechanic))",
|
26 |
+
"as a ((farmer))",
|
27 |
+
"as a ((fisherman))",
|
28 |
+
"as a ((hunter))",
|
29 |
+
"as a ((nerd))",
|
30 |
+
"as an ((accountant))",
|
31 |
+
"as an ((artist))",
|
32 |
+
"as an ((athlete))",
|
33 |
+
"as a ((baker))",
|
34 |
+
"as a ((barber))",
|
35 |
+
"as a ((bartender))",
|
36 |
+
"as a ((butcher))",
|
37 |
+
"as a ((doctor))",
|
38 |
+
"as a ((dentist))",
|
39 |
+
"as a ((dancer))",
|
40 |
+
"as a ((designer))",
|
41 |
+
"as a ((diver))",
|
42 |
+
"as a ((director))",
|
43 |
+
"as an ((engineer))",
|
44 |
+
"as a ((firefighter))",
|
45 |
+
"as a ((journalist))",
|
46 |
+
"as a ((lawyer))",
|
47 |
+
"as a ((mechanic))",
|
48 |
+
"as a ((musician))",
|
49 |
+
"as a ((nurse))",
|
50 |
+
"as a ((pilot))",
|
51 |
+
"as a ((police officer))",
|
52 |
+
"as a ((salesperson))",
|
53 |
+
"as a ((scientist))",
|
54 |
+
"as a ((web developer))",
|
55 |
+
"as a ((writer))",
|
56 |
+
"as a ((warrior))",
|
57 |
+
"as a ((mad scientist))",
|
58 |
+
"as a ((knight in armor))",
|
59 |
+
"as a ((jedi with a light saber))",
|
60 |
+
"as a ((wrestler))",
|
61 |
+
"as an ((astronaut))",
|
62 |
+
"as a ((warlord))",
|
63 |
+
"as a ((hobo))",
|
64 |
+
"as a ((surfer))",
|
65 |
+
"as a ((necromancer))",
|
66 |
+
"as a ((thiefling))",
|
67 |
+
"as a ((luxury person))",
|
68 |
+
"as an ((anthropomorphic creature))",
|
69 |
+
"as a ((samurai))",
|
70 |
+
"as a ((viking barbarian))",
|
71 |
+
"as an ((undead))",
|
72 |
+
"as a ((clown))",
|
73 |
+
"as a ((rockstar))",
|
74 |
+
"as an ((influencer))",
|
75 |
+
"as a ((priest))",
|
76 |
+
"((dressed as a pope))",
|
77 |
+
"((dressed as a king))",
|
78 |
+
"as a ((holy person))",
|
79 |
+
"as a ((hunter))",
|
80 |
+
"as an ((alien being))",
|
81 |
+
"as a ((soldier))",
|
82 |
+
"as an ((emo))",
|
83 |
+
"as an ((goth))",
|
84 |
+
"as an ((video game character))",
|
85 |
+
"as an ((michelin chef))",
|
86 |
+
"as a ((military person))",
|
87 |
+
"as a ((serial killer))",
|
88 |
+
"as a ((maniac))",
|
89 |
+
"as a ((captain))",
|
90 |
+
"as an ((evil magician))",
|
91 |
+
"as a ((pure blood))",
|
92 |
+
"as a ((dragon tamer))",
|
93 |
+
"as a ((warlock))",
|
94 |
+
"as a ((mermaid/merman))",
|
95 |
+
"as a ((cowboy))",
|
96 |
+
"as a ((black metal artist))",
|
97 |
+
"as a ((death metal front figure))",
|
98 |
+
"as an ((alien diplomat))",
|
99 |
+
"as a ((demigod))",
|
100 |
+
"as a ((monster hunter))",
|
101 |
+
"as a ((spaceship captain))",
|
102 |
+
"((dressed as jesus))",
|
103 |
+
"as ((the ultimate warrior))",
|
104 |
+
"as a wall street broker yuppie",
|
105 |
+
"as a ((cyborg, a fusion of human and machine, often equipped with advanced technology and prosthetics))",
|
106 |
+
"as a ((dragon whisperer))",
|
107 |
+
"as a ((pixie gardener))",
|
108 |
+
"as a ((necromancer))",
|
109 |
+
"as a ((phoenix tamer))",
|
110 |
+
"as a ((crystal seer))",
|
111 |
+
"as a ((fairy godparent))",
|
112 |
+
"as a ((spellweaver))",
|
113 |
+
"as a ((merfolk ambassador))",
|
114 |
+
"as a ((goblin trader))",
|
115 |
+
"as a ((unicorn healer))",
|
116 |
+
"as a ((dreamcatcher crafter))",
|
117 |
+
"as a ((star navigator))",
|
118 |
+
"as a ((enchanted armor smith))",
|
119 |
+
"as a ((griffin rider))",
|
120 |
+
"as a ((potion master))",
|
121 |
+
"as a ((lunar diviner))",
|
122 |
+
"as a ((eldritch librarian))",
|
123 |
+
"as a ((celestial musician))",
|
124 |
+
"as a ((mystic botanist))",
|
125 |
+
"as a ((spiritual stonemason))",
|
126 |
+
"as a ((shadow puppeteer))",
|
127 |
+
"as a ((time weaver))",
|
128 |
+
"as a ((sorcerous scribe))",
|
129 |
+
"as a ((elemental geologist))",
|
130 |
+
"as a ((ethereal architect))",
|
131 |
+
"as a ((starship engineer))",
|
132 |
+
"as a ((quantum cryptographer))",
|
133 |
+
"as a ((exo-botanist))",
|
134 |
+
"as a ((alien linguist))",
|
135 |
+
"as a ((holodeck programmer))",
|
136 |
+
"as a ((cybernetic surgeon))",
|
137 |
+
"as a ((astrogation specialist))",
|
138 |
+
"as a ((zero-gravity artist))",
|
139 |
+
"as a ((stellar cartographer))",
|
140 |
+
"as a ((time-travel historian))",
|
141 |
+
"as a ((interstellar diplomat))",
|
142 |
+
"as a ((teleportation technician))",
|
143 |
+
"as a ((neural network designer))",
|
144 |
+
"as a ((bio-enhancement consultant))",
|
145 |
+
"as a ((warp drive mechanic))",
|
146 |
+
"as a ((xenobiology researcher))",
|
147 |
+
"as a ((nano-medic))",
|
148 |
+
"as a ((android ethicist))",
|
149 |
+
"as a ((galactic explorer))",
|
150 |
+
"as a ((synthetic life curator))",
|
151 |
+
"as a ((multiverse navigator))",
|
152 |
+
"as a ((quantum foam sculptor))",
|
153 |
+
"as a ((holographic performer))",
|
154 |
+
"as a ((asteroid miner))",
|
155 |
+
"as a ((interdimensional trader))",
|
156 |
+
"as a ((cultist recruiter))",
|
157 |
+
"as a ((elder sign engraver))",
|
158 |
+
"as a ((forbidden tome librarian))",
|
159 |
+
"as a ((abyssal ambassador))",
|
160 |
+
"as a ((deep one liaison))",
|
161 |
+
"as a ((madness muse))",
|
162 |
+
"as a ((eldritch etymologist))",
|
163 |
+
"as a ((non-euclidean architect))",
|
164 |
+
"as a ((miskatonic scholar))",
|
165 |
+
"as a ((R'lyeh relic researcher))",
|
166 |
+
"as a ((dreamland cartographer))",
|
167 |
+
"as a ((night-gaunt navigator))",
|
168 |
+
"as a ((shub-niggurath shepherd))",
|
169 |
+
"as a ((yog-sothoth yodeler))",
|
170 |
+
"as a ((innsmouth innkeeper))",
|
171 |
+
"as a ((cthulhu chorister))",
|
172 |
+
"as a ((dragon devotee))",
|
173 |
+
"as a ((arkham archaeologist))",
|
174 |
+
"as a ((leng plateau pilgrim))",
|
175 |
+
"as a ((whisperer-in-darkness translator))",
|
176 |
+
"as a ((azathoth astronomer))",
|
177 |
+
"as a ((nyarlathotep negotiator))",
|
178 |
+
"as a ((carcosa curator))",
|
179 |
+
"as a ((tsathoggua therapist))",
|
180 |
+
"as a ((elder thing ethnographer))",
|
181 |
+
"as a ((neon netrunner))",
|
182 |
+
"as a ((cyberdeck coder))",
|
183 |
+
"as a ((techno-shaman))",
|
184 |
+
"as a ((hologram hustler))",
|
185 |
+
"as a ((megacity mercenary))",
|
186 |
+
"as a ((virtual voodoo priest))",
|
187 |
+
"as a ((data dive drifter))",
|
188 |
+
"as a ((chrome chaser))",
|
189 |
+
"as a ((synthwave slicer))",
|
190 |
+
"as a ((replicant rehabilitator))",
|
191 |
+
"as a ((black market biomod broker))",
|
192 |
+
"as a ((augmented artisan))",
|
193 |
+
"as a ((neural network ninja))",
|
194 |
+
"as a ((quantum qubit quixote))",
|
195 |
+
"as a ((cyberspace salvager))",
|
196 |
+
"as a ((pixel punker))",
|
197 |
+
"as a ((nanotech nomad))",
|
198 |
+
"as a ((binary blade bouncer))",
|
199 |
+
"as a ((digital dystopia detective))",
|
200 |
+
"as a ((megabuilding mapper))",
|
201 |
+
"as a ((corpo-hacker confidante))",
|
202 |
+
"as a ((aero auto-rickshaw racer))",
|
203 |
+
"as a ((skyline slicer))",
|
204 |
+
"as a ((terminal trickster))",
|
205 |
+
"as a ((matrix maverick))"
|
206 |
+
]
|
env.py
ADDED
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
|
3 |
+
|
4 |
+
CIVITAI_API_KEY = os.environ.get("CIVITAI_API_KEY")
|
5 |
+
hf_token = os.environ.get("HF_TOKEN")
|
6 |
+
hf_read_token = os.environ.get('HF_READ_TOKEN') # only use for private repo
|
7 |
+
|
8 |
+
|
9 |
+
# List all Models for specified user
|
10 |
+
HF_MODEL_USER_LIKES = [] # sorted by number of likes
|
11 |
+
HF_MODEL_USER_EX = [] # sorted by a special rule
|
12 |
+
|
13 |
+
|
14 |
+
# - **Download Models**
|
15 |
+
download_model_list = [
|
16 |
+
]
|
17 |
+
|
18 |
+
# - **Download VAEs**
|
19 |
+
download_vae_list = [
|
20 |
+
]
|
21 |
+
|
22 |
+
# - **Download LoRAs**
|
23 |
+
download_lora_list = [
|
24 |
+
]
|
25 |
+
|
26 |
+
|
27 |
+
directory_models = 'models'
|
28 |
+
os.makedirs(directory_models, exist_ok=True)
|
29 |
+
directory_loras = 'loras'
|
30 |
+
os.makedirs(directory_loras, exist_ok=True)
|
31 |
+
directory_vaes = 'vaes'
|
32 |
+
os.makedirs(directory_vaes, exist_ok=True)
|
33 |
+
|
34 |
+
|
35 |
+
HF_LORA_PRIVATE_REPOS1 = []
|
36 |
+
HF_LORA_PRIVATE_REPOS2 = [] # to be sorted as 1 repo
|
37 |
+
HF_LORA_PRIVATE_REPOS = HF_LORA_PRIVATE_REPOS1 + HF_LORA_PRIVATE_REPOS2
|
38 |
+
HF_LORA_ESSENTIAL_PRIVATE_REPO = '' # to be downloaded on run app
|
39 |
+
HF_VAE_PRIVATE_REPO = ''
|
40 |
+
|
flux.py
ADDED
@@ -0,0 +1,327 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import spaces
|
2 |
+
import os
|
3 |
+
import gradio as gr
|
4 |
+
import json
|
5 |
+
import logging
|
6 |
+
logging.getLogger("diffusers").setLevel(logging.ERROR)
|
7 |
+
import diffusers
|
8 |
+
diffusers.utils.logging.set_verbosity(40)
|
9 |
+
import warnings
|
10 |
+
warnings.filterwarnings(action="ignore", category=FutureWarning, module="diffusers")
|
11 |
+
warnings.filterwarnings(action="ignore", category=UserWarning, module="diffusers")
|
12 |
+
warnings.filterwarnings(action="ignore", category=FutureWarning, module="transformers")
|
13 |
+
from pathlib import Path
|
14 |
+
from env import (
|
15 |
+
hf_token,
|
16 |
+
hf_read_token, # to use only for private repos
|
17 |
+
CIVITAI_API_KEY,
|
18 |
+
HF_LORA_PRIVATE_REPOS1,
|
19 |
+
HF_LORA_PRIVATE_REPOS2,
|
20 |
+
HF_LORA_ESSENTIAL_PRIVATE_REPO,
|
21 |
+
HF_VAE_PRIVATE_REPO,
|
22 |
+
directory_models,
|
23 |
+
directory_loras,
|
24 |
+
directory_vaes,
|
25 |
+
download_model_list,
|
26 |
+
download_lora_list,
|
27 |
+
download_vae_list,
|
28 |
+
)
|
29 |
+
from modutils import (
|
30 |
+
to_list,
|
31 |
+
list_uniq,
|
32 |
+
list_sub,
|
33 |
+
get_lora_model_list,
|
34 |
+
download_private_repo,
|
35 |
+
safe_float,
|
36 |
+
escape_lora_basename,
|
37 |
+
to_lora_key,
|
38 |
+
to_lora_path,
|
39 |
+
get_local_model_list,
|
40 |
+
get_private_lora_model_lists,
|
41 |
+
get_valid_lora_name,
|
42 |
+
get_valid_lora_path,
|
43 |
+
get_valid_lora_wt,
|
44 |
+
get_lora_info,
|
45 |
+
normalize_prompt_list,
|
46 |
+
get_civitai_info,
|
47 |
+
search_lora_on_civitai,
|
48 |
+
)
|
49 |
+
|
50 |
+
|
51 |
+
def download_things(directory, url, hf_token="", civitai_api_key=""):
|
52 |
+
url = url.strip()
|
53 |
+
|
54 |
+
if "drive.google.com" in url:
|
55 |
+
original_dir = os.getcwd()
|
56 |
+
os.chdir(directory)
|
57 |
+
os.system(f"gdown --fuzzy {url}")
|
58 |
+
os.chdir(original_dir)
|
59 |
+
elif "huggingface.co" in url:
|
60 |
+
url = url.replace("?download=true", "")
|
61 |
+
# url = urllib.parse.quote(url, safe=':/') # fix encoding
|
62 |
+
if "/blob/" in url:
|
63 |
+
url = url.replace("/blob/", "/resolve/")
|
64 |
+
user_header = f'"Authorization: Bearer {hf_token}"'
|
65 |
+
if hf_token:
|
66 |
+
os.system(f"aria2c --console-log-level=error --summary-interval=10 --header={user_header} -c -x 16 -k 1M -s 16 {url} -d {directory} -o {url.split('/')[-1]}")
|
67 |
+
else:
|
68 |
+
os.system (f"aria2c --optimize-concurrent-downloads --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 {url} -d {directory} -o {url.split('/')[-1]}")
|
69 |
+
elif "civitai.com" in url:
|
70 |
+
if "?" in url:
|
71 |
+
url = url.split("?")[0]
|
72 |
+
if civitai_api_key:
|
73 |
+
url = url + f"?token={civitai_api_key}"
|
74 |
+
os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
|
75 |
+
else:
|
76 |
+
print("\033[91mYou need an API key to download Civitai models.\033[0m")
|
77 |
+
else:
|
78 |
+
os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
|
79 |
+
|
80 |
+
|
81 |
+
def get_model_list(directory_path):
|
82 |
+
model_list = []
|
83 |
+
valid_extensions = {'.ckpt' , '.pt', '.pth', '.safetensors', '.bin'}
|
84 |
+
|
85 |
+
for filename in os.listdir(directory_path):
|
86 |
+
if os.path.splitext(filename)[1] in valid_extensions:
|
87 |
+
name_without_extension = os.path.splitext(filename)[0]
|
88 |
+
file_path = os.path.join(directory_path, filename)
|
89 |
+
# model_list.append((name_without_extension, file_path))
|
90 |
+
model_list.append(file_path)
|
91 |
+
print('\033[34mFILE: ' + file_path + '\033[0m')
|
92 |
+
return model_list
|
93 |
+
|
94 |
+
|
95 |
+
# - **Download Models**
|
96 |
+
download_model = ", ".join(download_model_list)
|
97 |
+
# - **Download VAEs**
|
98 |
+
download_vae = ", ".join(download_vae_list)
|
99 |
+
# - **Download LoRAs**
|
100 |
+
download_lora = ", ".join(download_lora_list)
|
101 |
+
|
102 |
+
#download_private_repo(HF_LORA_ESSENTIAL_PRIVATE_REPO, directory_loras, True)
|
103 |
+
#download_private_repo(HF_VAE_PRIVATE_REPO, directory_vaes, False)
|
104 |
+
|
105 |
+
CIVITAI_API_KEY = os.environ.get("CIVITAI_API_KEY")
|
106 |
+
hf_token = os.environ.get("HF_TOKEN")
|
107 |
+
|
108 |
+
# Download stuffs
|
109 |
+
for url in [url.strip() for url in download_model.split(',')]:
|
110 |
+
if not os.path.exists(f"./models/{url.split('/')[-1]}"):
|
111 |
+
download_things(directory_models, url, hf_token, CIVITAI_API_KEY)
|
112 |
+
for url in [url.strip() for url in download_vae.split(',')]:
|
113 |
+
if not os.path.exists(f"./vaes/{url.split('/')[-1]}"):
|
114 |
+
download_things(directory_vaes, url, hf_token, CIVITAI_API_KEY)
|
115 |
+
for url in [url.strip() for url in download_lora.split(',')]:
|
116 |
+
if not os.path.exists(f"./loras/{url.split('/')[-1]}"):
|
117 |
+
download_things(directory_loras, url, hf_token, CIVITAI_API_KEY)
|
118 |
+
|
119 |
+
lora_model_list = get_lora_model_list()
|
120 |
+
vae_model_list = get_model_list(directory_vaes)
|
121 |
+
vae_model_list.insert(0, "None")
|
122 |
+
|
123 |
+
|
124 |
+
def get_t2i_model_info(repo_id: str):
|
125 |
+
from huggingface_hub import HfApi
|
126 |
+
api = HfApi()
|
127 |
+
try:
|
128 |
+
if " " in repo_id or not api.repo_exists(repo_id): return ""
|
129 |
+
model = api.model_info(repo_id=repo_id)
|
130 |
+
except Exception as e:
|
131 |
+
print(f"Error: Failed to get {repo_id}'s info. ")
|
132 |
+
print(e)
|
133 |
+
return ""
|
134 |
+
if model.private or model.gated: return ""
|
135 |
+
tags = model.tags
|
136 |
+
info = []
|
137 |
+
url = f"https://huggingface.co/{repo_id}/"
|
138 |
+
if not 'diffusers' in tags: return ""
|
139 |
+
if 'diffusers:StableDiffusionXLPipeline' in tags:
|
140 |
+
info.append("SDXL")
|
141 |
+
elif 'diffusers:StableDiffusionPipeline' in tags:
|
142 |
+
info.append("SD1.5")
|
143 |
+
if model.card_data and model.card_data.tags:
|
144 |
+
info.extend(list_sub(model.card_data.tags, ['text-to-image', 'stable-diffusion', 'stable-diffusion-api', 'safetensors', 'stable-diffusion-xl']))
|
145 |
+
info.append(f"DLs: {model.downloads}")
|
146 |
+
info.append(f"likes: {model.likes}")
|
147 |
+
info.append(model.last_modified.strftime("lastmod: %Y-%m-%d"))
|
148 |
+
md = f"Model Info: {', '.join(info)}, [Model Repo]({url})"
|
149 |
+
return gr.update(value=md)
|
150 |
+
|
151 |
+
|
152 |
+
private_lora_dict = {"": ["", "", "", "", ""]}
|
153 |
+
try:
|
154 |
+
with open('lora_dict.json', encoding='utf-8') as f:
|
155 |
+
d = json.load(f)
|
156 |
+
for k, v in d.items():
|
157 |
+
private_lora_dict[escape_lora_basename(k)] = v
|
158 |
+
except Exception:
|
159 |
+
pass
|
160 |
+
|
161 |
+
|
162 |
+
private_lora_model_list = get_private_lora_model_lists()
|
163 |
+
loras_dict = {"None": ["", "", "", "", ""], "": ["", "", "", "", ""]} | private_lora_dict.copy()
|
164 |
+
loras_url_to_path_dict = {} # {"URL to download": "local filepath", ...}
|
165 |
+
civitai_lora_last_results = {} # {"URL to download": {search results}, ...}
|
166 |
+
all_lora_list = []
|
167 |
+
|
168 |
+
|
169 |
+
def get_all_lora_list():
|
170 |
+
global all_lora_list
|
171 |
+
loras = get_lora_model_list()
|
172 |
+
all_lora_list = loras.copy()
|
173 |
+
return loras
|
174 |
+
|
175 |
+
|
176 |
+
def get_all_lora_tupled_list():
|
177 |
+
global loras_dict
|
178 |
+
models = get_all_lora_list()
|
179 |
+
if not models: return []
|
180 |
+
tupled_list = []
|
181 |
+
for model in models:
|
182 |
+
#if not model: continue # to avoid GUI-related bug
|
183 |
+
basename = Path(model).stem
|
184 |
+
key = to_lora_key(model)
|
185 |
+
items = None
|
186 |
+
if key in loras_dict.keys():
|
187 |
+
items = loras_dict.get(key, None)
|
188 |
+
else:
|
189 |
+
items = get_civitai_info(model)
|
190 |
+
if items != None:
|
191 |
+
loras_dict[key] = items
|
192 |
+
name = basename
|
193 |
+
value = model
|
194 |
+
if items and items[2] != "":
|
195 |
+
if items[1] == "Pony":
|
196 |
+
name = f"{basename} (for {items[1]}🐴, {items[2]})"
|
197 |
+
else:
|
198 |
+
name = f"{basename} (for {items[1]}, {items[2]})"
|
199 |
+
tupled_list.append((name, value))
|
200 |
+
return tupled_list
|
201 |
+
|
202 |
+
|
203 |
+
def update_lora_dict(path: str):
|
204 |
+
global loras_dict
|
205 |
+
key = to_lora_key(path)
|
206 |
+
if key in loras_dict.keys(): return
|
207 |
+
items = get_civitai_info(path)
|
208 |
+
if items == None: return
|
209 |
+
loras_dict[key] = items
|
210 |
+
|
211 |
+
|
212 |
+
def download_lora(dl_urls: str):
|
213 |
+
global loras_url_to_path_dict
|
214 |
+
dl_path = ""
|
215 |
+
before = get_local_model_list(directory_loras)
|
216 |
+
urls = []
|
217 |
+
for url in [url.strip() for url in dl_urls.split(',')]:
|
218 |
+
local_path = f"{directory_loras}/{url.split('/')[-1]}"
|
219 |
+
if not Path(local_path).exists():
|
220 |
+
download_things(directory_loras, url, hf_token, CIVITAI_API_KEY)
|
221 |
+
urls.append(url)
|
222 |
+
after = get_local_model_list(directory_loras)
|
223 |
+
new_files = list_sub(after, before)
|
224 |
+
for i, file in enumerate(new_files):
|
225 |
+
path = Path(file)
|
226 |
+
if path.exists():
|
227 |
+
new_path = Path(f'{path.parent.name}/{escape_lora_basename(path.stem)}{path.suffix}')
|
228 |
+
path.resolve().rename(new_path.resolve())
|
229 |
+
loras_url_to_path_dict[urls[i]] = str(new_path)
|
230 |
+
update_lora_dict(str(new_path))
|
231 |
+
dl_path = str(new_path)
|
232 |
+
return dl_path
|
233 |
+
|
234 |
+
|
235 |
+
def copy_lora(path: str, new_path: str):
|
236 |
+
import shutil
|
237 |
+
if path == new_path: return new_path
|
238 |
+
cpath = Path(path)
|
239 |
+
npath = Path(new_path)
|
240 |
+
if cpath.exists():
|
241 |
+
try:
|
242 |
+
shutil.copy(str(cpath.resolve()), str(npath.resolve()))
|
243 |
+
except Exception:
|
244 |
+
return None
|
245 |
+
update_lora_dict(str(npath))
|
246 |
+
return new_path
|
247 |
+
else:
|
248 |
+
return None
|
249 |
+
|
250 |
+
|
251 |
+
def download_my_lora(dl_urls: str, lora: str):
|
252 |
+
path = download_lora(dl_urls)
|
253 |
+
if path: lora = path
|
254 |
+
choices = get_all_lora_tupled_list()
|
255 |
+
return gr.update(value=lora, choices=choices)
|
256 |
+
|
257 |
+
|
258 |
+
def apply_lora_prompt(lora_info: str):
|
259 |
+
if lora_info == "None": return ""
|
260 |
+
lora_tag = lora_info.replace("/",",")
|
261 |
+
lora_tags = lora_tag.split(",") if str(lora_info) != "None" else []
|
262 |
+
lora_prompts = normalize_prompt_list(lora_tags)
|
263 |
+
prompt = ", ".join(list_uniq(lora_prompts))
|
264 |
+
return prompt
|
265 |
+
|
266 |
+
|
267 |
+
def update_loras(prompt, lora, lora_wt):
|
268 |
+
import re
|
269 |
+
on, label, tag, md = get_lora_info(lora)
|
270 |
+
prompts = prompt.split(",") if prompt else []
|
271 |
+
output_prompts = []
|
272 |
+
for p in prompts:
|
273 |
+
p = str(p).strip()
|
274 |
+
if "<lora" in p:
|
275 |
+
result = re.findall(r'<lora:(.+?):(.+?)>', p)
|
276 |
+
if not result: continue
|
277 |
+
key = result[0][0]
|
278 |
+
wt = result[0][1]
|
279 |
+
path = to_lora_path(key)
|
280 |
+
if not key in loras_dict.keys() or not path: continue
|
281 |
+
if Path(path).exists(): output_prompts.append(f"<lora:{to_lora_key(path)}:{safe_float(wt):.2f}>")
|
282 |
+
elif p:
|
283 |
+
output_prompts.append(p)
|
284 |
+
lora_prompts = []
|
285 |
+
if on: lora_prompts.append(f"<lora:{to_lora_key(lora)}:{lora_wt:.2f}>")
|
286 |
+
output_prompt = ", ".join(list_uniq(output_prompts + lora_prompts))
|
287 |
+
choices = get_all_lora_tupled_list()
|
288 |
+
return gr.update(value=output_prompt), gr.update(value=lora, choices=choices), gr.update(value=lora_wt),\
|
289 |
+
gr.update(value=tag, label=label, visible=on), gr.update(visible=on), gr.update(value=md, visible=on)
|
290 |
+
|
291 |
+
|
292 |
+
def search_civitai_lora(query, base_model):
|
293 |
+
global civitai_lora_last_results
|
294 |
+
items = search_lora_on_civitai(query, base_model)
|
295 |
+
if not items: return gr.update(choices=[("", "")], value="", visible=False),\
|
296 |
+
gr.update(value="", visible=False), gr.update(visible=True), gr.update(visible=True)
|
297 |
+
civitai_lora_last_results = {}
|
298 |
+
choices = []
|
299 |
+
for item in items:
|
300 |
+
base_model_name = "Pony🐴" if item['base_model'] == "Pony" else item['base_model']
|
301 |
+
name = f"{item['name']} (for {base_model_name} / By: {item['creator']} / Tags: {', '.join(item['tags'])})"
|
302 |
+
value = item['dl_url']
|
303 |
+
choices.append((name, value))
|
304 |
+
civitai_lora_last_results[value] = item
|
305 |
+
if not choices: return gr.update(choices=[("", "")], value="", visible=False),\
|
306 |
+
gr.update(value="", visible=False), gr.update(visible=True), gr.update(visible=True)
|
307 |
+
result = civitai_lora_last_results.get(choices[0][1], "None")
|
308 |
+
md = result['md'] if result else ""
|
309 |
+
return gr.update(choices=choices, value=choices[0][1], visible=True), gr.update(value=md, visible=True),\
|
310 |
+
gr.update(visible=True), gr.update(visible=True)
|
311 |
+
|
312 |
+
|
313 |
+
def select_civitai_lora(search_result):
|
314 |
+
if not "http" in search_result: return gr.update(value=""), gr.update(value="None", visible=True)
|
315 |
+
result = civitai_lora_last_results.get(search_result, "None")
|
316 |
+
md = result['md'] if result else ""
|
317 |
+
return gr.update(value=search_result), gr.update(value=md, visible=True)
|
318 |
+
|
319 |
+
|
320 |
+
def search_civitai_lora_json(query, base_model):
|
321 |
+
results = {}
|
322 |
+
items = search_lora_on_civitai(query, base_model)
|
323 |
+
if not items: return gr.update(value=results)
|
324 |
+
for item in items:
|
325 |
+
results[item['dl_url']] = item
|
326 |
+
return gr.update(value=results)
|
327 |
+
|
loras.json
CHANGED
@@ -1,116 +1,116 @@
|
|
1 |
-
[
|
2 |
-
{
|
3 |
-
"image": "https://huggingface.co/multimodalart/flux-tarot-v1/resolve/main/images/e5f2761e5d474e6ba492d20dca0fa26f_e78f1524074b42b6ac49643ffad50ac6.png",
|
4 |
-
"title": "Tarot v1",
|
5 |
-
"repo": "multimodalart/flux-tarot-v1",
|
6 |
-
"trigger_word": "in the style of TOK a trtcrd, tarot style",
|
7 |
-
"aspect": "portrait"
|
8 |
-
},
|
9 |
-
{
|
10 |
-
"image": "https://huggingface.co/alvdansen/frosting_lane_flux/resolve/main/images/content%20-%202024-08-11T005936.346.jpeg",
|
11 |
-
"title": "Frosting Lane Flux",
|
12 |
-
"repo": "alvdansen/frosting_lane_flux",
|
13 |
-
"trigger_word": ""
|
14 |
-
},
|
15 |
-
{
|
16 |
-
"image": "https://github.com/XLabs-AI/x-flux/blob/main/assets/readme/examples/picture-6-rev1.png?raw=true",
|
17 |
-
"title": "flux-Realism",
|
18 |
-
"repo": "XLabs-AI/flux-RealismLora",
|
19 |
-
"trigger_word": ""
|
20 |
-
},
|
21 |
-
{
|
22 |
-
"image": "https://huggingface.co/nerijs/animation2k-flux/resolve/main/images/Q8-oVxNnXvZ9HNrgbNpGw_02762aaaba3b47859ee5fe9403a371e3.png",
|
23 |
-
"title": "animation2k",
|
24 |
-
"repo": "nerijs/animation2k-flux",
|
25 |
-
"trigger_word": ""
|
26 |
-
},
|
27 |
-
{
|
28 |
-
"image":"https://huggingface.co/alvdansen/softserve_anime/resolve/main/images/ComfyUI_00062_.png",
|
29 |
-
"title":"SoftServe Anime",
|
30 |
-
"repo": "alvdansen/softserve_anime",
|
31 |
-
"trigger_word": ""
|
32 |
-
},
|
33 |
-
{
|
34 |
-
"image": "https://huggingface.co/veryVANYA/ps1-style-flux/resolve/main/24439220.jpeg",
|
35 |
-
"title": "PS1 style",
|
36 |
-
"repo": "veryVANYA/ps1-style-flux",
|
37 |
-
"trigger_word": "ps1 game screenshot"
|
38 |
-
},
|
39 |
-
{
|
40 |
-
"image": "https://huggingface.co/alvdansen/flux-koda/resolve/main/images/ComfyUI_00566_%20(2).png",
|
41 |
-
"title": "flux koda",
|
42 |
-
"repo": "alvdansen/flux-koda",
|
43 |
-
"trigger_word": "flmft style"
|
44 |
-
},
|
45 |
-
{
|
46 |
-
"image": "https://pbs.twimg.com/media/GU7NsZPa8AA4Ddl?format=jpg&name=4096x4096",
|
47 |
-
"title": "Half Illustration",
|
48 |
-
"repo": "davisbro/half_illustration",
|
49 |
-
"trigger_word": "in the style of TOK"
|
50 |
-
},
|
51 |
-
{
|
52 |
-
"image":"https://pbs.twimg.com/media/GVRiSH7WgAAnI4P?format=jpg&name=medium",
|
53 |
-
"title":"wrong",
|
54 |
-
"repo": "fofr/flux-wrong",
|
55 |
-
"trigger_word": "WRNG"
|
56 |
-
},
|
57 |
-
{
|
58 |
-
"image":"https://huggingface.co/linoyts/yarn_art_Flux_LoRA/resolve/main/yarn_art_2.png",
|
59 |
-
"title":"Yarn Art",
|
60 |
-
"repo": "linoyts/yarn_art_Flux_LoRA",
|
61 |
-
"trigger_word": ", yarn art style"
|
62 |
-
},
|
63 |
-
{
|
64 |
-
"image": "https://huggingface.co/SebastianBodza/flux_lora_aquarel_watercolor/resolve/main/images/ascend.webp",
|
65 |
-
"title": "Aquarell Watercolor",
|
66 |
-
"repo": "SebastianBodza/Flux_Aquarell_Watercolor_v2",
|
67 |
-
"trigger_word": "in a watercolor style, AQUACOLTOK. White background."
|
68 |
-
},
|
69 |
-
{
|
70 |
-
"image": "https://huggingface.co/dataautogpt3/FLUX-SyntheticAnime/resolve/main/assets/angel.png",
|
71 |
-
"title": "SyntheticAnime",
|
72 |
-
"repo": "dataautogpt3/FLUX-SyntheticAnime",
|
73 |
-
"trigger_word": "1980s anime screengrab, VHS quality"
|
74 |
-
},
|
75 |
-
{
|
76 |
-
"image": "https://github.com/XLabs-AI/x-flux/blob/main/assets/readme/examples/result_14.png?raw=true",
|
77 |
-
"title": "flux-anime",
|
78 |
-
"repo": "XLabs-AI/flux-lora-collection",
|
79 |
-
"weights": "anime_lora.safetensors",
|
80 |
-
"trigger_word": ", anime"
|
81 |
-
},
|
82 |
-
{
|
83 |
-
"image": "https://huggingface.co/kudzueye/Boreal/resolve/main/images/ComfyUI_00845_.png",
|
84 |
-
"title": "Boreal",
|
85 |
-
"repo": "kudzueye/Boreal",
|
86 |
-
"weights": "boreal-flux-dev-lora-v04_1000_steps.safetensors",
|
87 |
-
"trigger_word": "phone photo"
|
88 |
-
},
|
89 |
-
{
|
90 |
-
"image": "https://github.com/XLabs-AI/x-flux/blob/main/assets/readme/examples/result_18.png?raw=true",
|
91 |
-
"title": "flux-disney",
|
92 |
-
"repo": "XLabs-AI/flux-lora-collection",
|
93 |
-
"weights": "disney_lora.safetensors",
|
94 |
-
"trigger_word": ", disney style"
|
95 |
-
},
|
96 |
-
{
|
97 |
-
"image": "https://github.com/XLabs-AI/x-flux/blob/main/assets/readme/examples/result_23.png?raw=true",
|
98 |
-
"title": "flux-art",
|
99 |
-
"repo": "XLabs-AI/flux-lora-collection",
|
100 |
-
"weights": "art_lora.safetensors",
|
101 |
-
"trigger_word": ", art"
|
102 |
-
},
|
103 |
-
{
|
104 |
-
"image": "https://huggingface.co/martintomov/retrofuturism-flux/resolve/main/images/2e40deba-858e-454f-ae1c-d1ba2adb6a65.jpeg",
|
105 |
-
"title": "Retrofuturism Flux",
|
106 |
-
"repo": "martintomov/retrofuturism-flux",
|
107 |
-
"trigger_word": ", retrofuturism"
|
108 |
-
},
|
109 |
-
{
|
110 |
-
"image": "https://huggingface.co/alfredplpl/flux.1-dev-modern-anime-lora/resolve/main/eyecatch2.jpg",
|
111 |
-
"title": "flux.1-dev-modern-anime-lora",
|
112 |
-
"repo": "alfredplpl/flux.1-dev-modern-anime-lora",
|
113 |
-
"weights": "modern-anime-lora_diffusers.safetensors",
|
114 |
-
"trigger_word": "modern anime"
|
115 |
-
}
|
116 |
]
|
|
|
1 |
+
[
|
2 |
+
{
|
3 |
+
"image": "https://huggingface.co/multimodalart/flux-tarot-v1/resolve/main/images/e5f2761e5d474e6ba492d20dca0fa26f_e78f1524074b42b6ac49643ffad50ac6.png",
|
4 |
+
"title": "Tarot v1",
|
5 |
+
"repo": "multimodalart/flux-tarot-v1",
|
6 |
+
"trigger_word": "in the style of TOK a trtcrd, tarot style",
|
7 |
+
"aspect": "portrait"
|
8 |
+
},
|
9 |
+
{
|
10 |
+
"image": "https://huggingface.co/alvdansen/frosting_lane_flux/resolve/main/images/content%20-%202024-08-11T005936.346.jpeg",
|
11 |
+
"title": "Frosting Lane Flux",
|
12 |
+
"repo": "alvdansen/frosting_lane_flux",
|
13 |
+
"trigger_word": ""
|
14 |
+
},
|
15 |
+
{
|
16 |
+
"image": "https://github.com/XLabs-AI/x-flux/blob/main/assets/readme/examples/picture-6-rev1.png?raw=true",
|
17 |
+
"title": "flux-Realism",
|
18 |
+
"repo": "XLabs-AI/flux-RealismLora",
|
19 |
+
"trigger_word": ""
|
20 |
+
},
|
21 |
+
{
|
22 |
+
"image": "https://huggingface.co/nerijs/animation2k-flux/resolve/main/images/Q8-oVxNnXvZ9HNrgbNpGw_02762aaaba3b47859ee5fe9403a371e3.png",
|
23 |
+
"title": "animation2k",
|
24 |
+
"repo": "nerijs/animation2k-flux",
|
25 |
+
"trigger_word": ""
|
26 |
+
},
|
27 |
+
{
|
28 |
+
"image":"https://huggingface.co/alvdansen/softserve_anime/resolve/main/images/ComfyUI_00062_.png",
|
29 |
+
"title":"SoftServe Anime",
|
30 |
+
"repo": "alvdansen/softserve_anime",
|
31 |
+
"trigger_word": ""
|
32 |
+
},
|
33 |
+
{
|
34 |
+
"image": "https://huggingface.co/veryVANYA/ps1-style-flux/resolve/main/24439220.jpeg",
|
35 |
+
"title": "PS1 style",
|
36 |
+
"repo": "veryVANYA/ps1-style-flux",
|
37 |
+
"trigger_word": "ps1 game screenshot"
|
38 |
+
},
|
39 |
+
{
|
40 |
+
"image": "https://huggingface.co/alvdansen/flux-koda/resolve/main/images/ComfyUI_00566_%20(2).png",
|
41 |
+
"title": "flux koda",
|
42 |
+
"repo": "alvdansen/flux-koda",
|
43 |
+
"trigger_word": "flmft style"
|
44 |
+
},
|
45 |
+
{
|
46 |
+
"image": "https://pbs.twimg.com/media/GU7NsZPa8AA4Ddl?format=jpg&name=4096x4096",
|
47 |
+
"title": "Half Illustration",
|
48 |
+
"repo": "davisbro/half_illustration",
|
49 |
+
"trigger_word": "in the style of TOK"
|
50 |
+
},
|
51 |
+
{
|
52 |
+
"image":"https://pbs.twimg.com/media/GVRiSH7WgAAnI4P?format=jpg&name=medium",
|
53 |
+
"title":"wrong",
|
54 |
+
"repo": "fofr/flux-wrong",
|
55 |
+
"trigger_word": "WRNG"
|
56 |
+
},
|
57 |
+
{
|
58 |
+
"image":"https://huggingface.co/linoyts/yarn_art_Flux_LoRA/resolve/main/yarn_art_2.png",
|
59 |
+
"title":"Yarn Art",
|
60 |
+
"repo": "linoyts/yarn_art_Flux_LoRA",
|
61 |
+
"trigger_word": ", yarn art style"
|
62 |
+
},
|
63 |
+
{
|
64 |
+
"image": "https://huggingface.co/SebastianBodza/flux_lora_aquarel_watercolor/resolve/main/images/ascend.webp",
|
65 |
+
"title": "Aquarell Watercolor",
|
66 |
+
"repo": "SebastianBodza/Flux_Aquarell_Watercolor_v2",
|
67 |
+
"trigger_word": "in a watercolor style, AQUACOLTOK. White background."
|
68 |
+
},
|
69 |
+
{
|
70 |
+
"image": "https://huggingface.co/dataautogpt3/FLUX-SyntheticAnime/resolve/main/assets/angel.png",
|
71 |
+
"title": "SyntheticAnime",
|
72 |
+
"repo": "dataautogpt3/FLUX-SyntheticAnime",
|
73 |
+
"trigger_word": "1980s anime screengrab, VHS quality"
|
74 |
+
},
|
75 |
+
{
|
76 |
+
"image": "https://github.com/XLabs-AI/x-flux/blob/main/assets/readme/examples/result_14.png?raw=true",
|
77 |
+
"title": "flux-anime",
|
78 |
+
"repo": "XLabs-AI/flux-lora-collection",
|
79 |
+
"weights": "anime_lora.safetensors",
|
80 |
+
"trigger_word": ", anime"
|
81 |
+
},
|
82 |
+
{
|
83 |
+
"image": "https://huggingface.co/kudzueye/Boreal/resolve/main/images/ComfyUI_00845_.png",
|
84 |
+
"title": "Boreal",
|
85 |
+
"repo": "kudzueye/Boreal",
|
86 |
+
"weights": "boreal-flux-dev-lora-v04_1000_steps.safetensors",
|
87 |
+
"trigger_word": "phone photo"
|
88 |
+
},
|
89 |
+
{
|
90 |
+
"image": "https://github.com/XLabs-AI/x-flux/blob/main/assets/readme/examples/result_18.png?raw=true",
|
91 |
+
"title": "flux-disney",
|
92 |
+
"repo": "XLabs-AI/flux-lora-collection",
|
93 |
+
"weights": "disney_lora.safetensors",
|
94 |
+
"trigger_word": ", disney style"
|
95 |
+
},
|
96 |
+
{
|
97 |
+
"image": "https://github.com/XLabs-AI/x-flux/blob/main/assets/readme/examples/result_23.png?raw=true",
|
98 |
+
"title": "flux-art",
|
99 |
+
"repo": "XLabs-AI/flux-lora-collection",
|
100 |
+
"weights": "art_lora.safetensors",
|
101 |
+
"trigger_word": ", art"
|
102 |
+
},
|
103 |
+
{
|
104 |
+
"image": "https://huggingface.co/martintomov/retrofuturism-flux/resolve/main/images/2e40deba-858e-454f-ae1c-d1ba2adb6a65.jpeg",
|
105 |
+
"title": "Retrofuturism Flux",
|
106 |
+
"repo": "martintomov/retrofuturism-flux",
|
107 |
+
"trigger_word": ", retrofuturism"
|
108 |
+
},
|
109 |
+
{
|
110 |
+
"image": "https://huggingface.co/alfredplpl/flux.1-dev-modern-anime-lora/resolve/main/eyecatch2.jpg",
|
111 |
+
"title": "flux.1-dev-modern-anime-lora",
|
112 |
+
"repo": "alfredplpl/flux.1-dev-modern-anime-lora",
|
113 |
+
"weights": "modern-anime-lora_diffusers.safetensors",
|
114 |
+
"trigger_word": "modern anime"
|
115 |
+
}
|
116 |
]
|
mod.py
CHANGED
@@ -2,6 +2,7 @@ import gradio as gr
|
|
2 |
import torch
|
3 |
import spaces
|
4 |
from diffusers import DiffusionPipeline
|
|
|
5 |
import gc
|
6 |
import subprocess
|
7 |
|
@@ -11,15 +12,35 @@ device = "cuda" if torch.cuda.is_available() else "cpu"
|
|
11 |
torch.set_grad_enabled(False)
|
12 |
|
13 |
|
14 |
-
models = [
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
20 |
]
|
21 |
|
22 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
23 |
def clear_cache():
|
24 |
torch.cuda.empty_cache()
|
25 |
gc.collect()
|
@@ -29,7 +50,7 @@ def get_repo_safetensors(repo_id: str):
|
|
29 |
from huggingface_hub import HfApi
|
30 |
api = HfApi()
|
31 |
try:
|
32 |
-
if
|
33 |
files = api.list_repo_files(repo_id=repo_id)
|
34 |
except Exception as e:
|
35 |
print(f"Error: Failed to get {repo_id}'s info. ")
|
@@ -50,3 +71,64 @@ def change_base_model(repo_id: str):
|
|
50 |
pipe = DiffusionPipeline.from_pretrained(repo_id, torch_dtype=torch.bfloat16)
|
51 |
except Exception as e:
|
52 |
print(e)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import torch
|
3 |
import spaces
|
4 |
from diffusers import DiffusionPipeline
|
5 |
+
from pathlib import Path
|
6 |
import gc
|
7 |
import subprocess
|
8 |
|
|
|
12 |
torch.set_grad_enabled(False)
|
13 |
|
14 |
|
15 |
+
models = [
|
16 |
+
"camenduru/FLUX.1-dev-diffusers",
|
17 |
+
"black-forest-labs/FLUX.1-schnell",
|
18 |
+
"sayakpaul/FLUX.1-merged",
|
19 |
+
"John6666/blue-pencil-flux1-v001-fp8-flux",
|
20 |
+
"John6666/fluxunchained-artfulnsfw-fut516xfp8e4m3fnv11-fp8-flux",
|
21 |
+
"John6666/nepotism-fuxdevschnell-v3aio-flux"
|
22 |
]
|
23 |
|
24 |
|
25 |
+
num_loras = 3
|
26 |
+
|
27 |
+
|
28 |
+
def is_repo_name(s):
|
29 |
+
import re
|
30 |
+
return re.fullmatch(r'^[^/,\s]+?/[^/,\s]+?$', s)
|
31 |
+
|
32 |
+
|
33 |
+
def is_repo_exists(repo_id):
|
34 |
+
from huggingface_hub import HfApi
|
35 |
+
api = HfApi()
|
36 |
+
try:
|
37 |
+
if api.repo_exists(repo_id=repo_id): return True
|
38 |
+
else: return False
|
39 |
+
except Exception as e:
|
40 |
+
print(f"Error: Failed to connect {repo_id}. ")
|
41 |
+
return True # for safe
|
42 |
+
|
43 |
+
|
44 |
def clear_cache():
|
45 |
torch.cuda.empty_cache()
|
46 |
gc.collect()
|
|
|
50 |
from huggingface_hub import HfApi
|
51 |
api = HfApi()
|
52 |
try:
|
53 |
+
if not is_repo_name(repo_id) or not is_repo_exists(repo_id): return gr.update(value="", choices=[])
|
54 |
files = api.list_repo_files(repo_id=repo_id)
|
55 |
except Exception as e:
|
56 |
print(f"Error: Failed to get {repo_id}'s info. ")
|
|
|
71 |
pipe = DiffusionPipeline.from_pretrained(repo_id, torch_dtype=torch.bfloat16)
|
72 |
except Exception as e:
|
73 |
print(e)
|
74 |
+
|
75 |
+
|
76 |
+
def compose_lora_json(lorajson: list[dict], i: int, name: str, scale: float, filename: str, trigger: str):
|
77 |
+
lorajson[i]["name"] = str(name) if name != "None" else ""
|
78 |
+
lorajson[i]["scale"] = float(scale)
|
79 |
+
lorajson[i]["filename"] = str(filename)
|
80 |
+
lorajson[i]["trigger"] = str(trigger)
|
81 |
+
return lorajson
|
82 |
+
|
83 |
+
|
84 |
+
def is_valid_lora(lorajson: list[dict]):
|
85 |
+
valid = False
|
86 |
+
for d in lorajson:
|
87 |
+
if "name" in d.keys() and d["name"] and d["name"] != "None": valid = True
|
88 |
+
return valid
|
89 |
+
|
90 |
+
|
91 |
+
def get_trigger_word(lorajson: list[dict]):
|
92 |
+
trigger = ""
|
93 |
+
for d in lorajson:
|
94 |
+
if "name" in d.keys() and d["name"] and d["name"] != "None" and d["trigger"]:
|
95 |
+
trigger += ", " + d["trigger"]
|
96 |
+
return trigger
|
97 |
+
|
98 |
+
|
99 |
+
# https://github.com/huggingface/diffusers/issues/4919
|
100 |
+
def fuse_loras(pipe, lorajson: list[dict]):
|
101 |
+
if not lorajson or not isinstance(lorajson, list): return
|
102 |
+
a_list = []
|
103 |
+
w_list = []
|
104 |
+
for d in lorajson:
|
105 |
+
if not d or not isinstance(d, dict) or not d["name"] or d["name"] == "None": continue
|
106 |
+
k = d["name"]
|
107 |
+
if is_repo_name(k) and is_repo_exists(k):
|
108 |
+
a_name = Path(k).stem
|
109 |
+
pipe.load_lora_weights(k, weight_name=d["filename"], adapter_name = a_name)
|
110 |
+
elif not Path(k).exists():
|
111 |
+
print(f"LoRA not found: {k}")
|
112 |
+
continue
|
113 |
+
else:
|
114 |
+
w_name = Path(k).name
|
115 |
+
a_name = Path(k).stem
|
116 |
+
pipe.load_lora_weights(k, weight_name = w_name, adapter_name = a_name)
|
117 |
+
a_list.append(a_name)
|
118 |
+
w_list.append(d["scale"])
|
119 |
+
if not a_list: return
|
120 |
+
pipe.set_adapters(a_list, adapter_weights=w_list)
|
121 |
+
pipe.fuse_lora(adapter_names=a_list, lora_scale=1.0)
|
122 |
+
#pipe.unload_lora_weights()
|
123 |
+
|
124 |
+
|
125 |
+
fuse_loras.zerogpu = True
|
126 |
+
|
127 |
+
|
128 |
+
def description_ui():
|
129 |
+
gr.Markdown(
|
130 |
+
"""
|
131 |
+
- Mod of [multimodalart/flux-lora-the-explorer](https://huggingface.co/spaces/multimodalart/flux-lora-the-explorer),
|
132 |
+
[gokaygokay/FLUX-Prompt-Generator](https://huggingface.co/spaces/gokaygokay/FLUX-Prompt-Generator).
|
133 |
+
"""
|
134 |
+
)
|
modutils.py
ADDED
@@ -0,0 +1,1224 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
import gradio as gr
|
3 |
+
from huggingface_hub import HfApi
|
4 |
+
import os
|
5 |
+
from pathlib import Path
|
6 |
+
|
7 |
+
from env import (
|
8 |
+
HF_LORA_PRIVATE_REPOS1,
|
9 |
+
HF_LORA_PRIVATE_REPOS2,
|
10 |
+
HF_MODEL_USER_EX,
|
11 |
+
HF_MODEL_USER_LIKES,
|
12 |
+
directory_loras,
|
13 |
+
hf_read_token,
|
14 |
+
hf_token,
|
15 |
+
CIVITAI_API_KEY,
|
16 |
+
)
|
17 |
+
|
18 |
+
|
19 |
+
def get_user_agent():
|
20 |
+
return 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:127.0) Gecko/20100101 Firefox/127.0'
|
21 |
+
|
22 |
+
|
23 |
+
def to_list(s):
|
24 |
+
return [x.strip() for x in s.split(",") if not s == ""]
|
25 |
+
|
26 |
+
|
27 |
+
def list_uniq(l):
|
28 |
+
return sorted(set(l), key=l.index)
|
29 |
+
|
30 |
+
|
31 |
+
def list_sub(a, b):
|
32 |
+
return [e for e in a if e not in b]
|
33 |
+
|
34 |
+
|
35 |
+
def get_local_model_list(dir_path):
|
36 |
+
model_list = []
|
37 |
+
valid_extensions = ('.ckpt', '.pt', '.pth', '.safetensors', '.bin')
|
38 |
+
for file in Path(dir_path).glob("*"):
|
39 |
+
if file.suffix in valid_extensions:
|
40 |
+
file_path = str(Path(f"{dir_path}/{file.name}"))
|
41 |
+
model_list.append(file_path)
|
42 |
+
return model_list
|
43 |
+
|
44 |
+
|
45 |
+
def download_things(directory, url, hf_token="", civitai_api_key=""):
|
46 |
+
url = url.strip()
|
47 |
+
|
48 |
+
if "drive.google.com" in url:
|
49 |
+
original_dir = os.getcwd()
|
50 |
+
os.chdir(directory)
|
51 |
+
os.system(f"gdown --fuzzy {url}")
|
52 |
+
os.chdir(original_dir)
|
53 |
+
elif "huggingface.co" in url:
|
54 |
+
url = url.replace("?download=true", "")
|
55 |
+
# url = urllib.parse.quote(url, safe=':/') # fix encoding
|
56 |
+
if "/blob/" in url:
|
57 |
+
url = url.replace("/blob/", "/resolve/")
|
58 |
+
user_header = f'"Authorization: Bearer {hf_token}"'
|
59 |
+
if hf_token:
|
60 |
+
os.system(f"aria2c --console-log-level=error --summary-interval=10 --header={user_header} -c -x 16 -k 1M -s 16 {url} -d {directory} -o {url.split('/')[-1]}")
|
61 |
+
else:
|
62 |
+
os.system (f"aria2c --optimize-concurrent-downloads --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 {url} -d {directory} -o {url.split('/')[-1]}")
|
63 |
+
elif "civitai.com" in url:
|
64 |
+
if "?" in url:
|
65 |
+
url = url.split("?")[0]
|
66 |
+
if civitai_api_key:
|
67 |
+
url = url + f"?token={civitai_api_key}"
|
68 |
+
os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
|
69 |
+
else:
|
70 |
+
print("\033[91mYou need an API key to download Civitai models.\033[0m")
|
71 |
+
else:
|
72 |
+
os.system(f"aria2c --console-log-level=error --summary-interval=10 -c -x 16 -k 1M -s 16 -d {directory} {url}")
|
73 |
+
|
74 |
+
|
75 |
+
def escape_lora_basename(basename: str):
|
76 |
+
return basename.replace(".", "_").replace(" ", "_").replace(",", "")
|
77 |
+
|
78 |
+
|
79 |
+
def to_lora_key(path: str):
|
80 |
+
return escape_lora_basename(Path(path).stem)
|
81 |
+
|
82 |
+
|
83 |
+
def to_lora_path(key: str):
|
84 |
+
if Path(key).is_file(): return key
|
85 |
+
path = Path(f"{directory_loras}/{escape_lora_basename(key)}.safetensors")
|
86 |
+
return str(path)
|
87 |
+
|
88 |
+
|
89 |
+
def safe_float(input):
|
90 |
+
output = 1.0
|
91 |
+
try:
|
92 |
+
output = float(input)
|
93 |
+
except Exception:
|
94 |
+
output = 1.0
|
95 |
+
return output
|
96 |
+
|
97 |
+
|
98 |
+
def save_gallery_images(images, progress=gr.Progress(track_tqdm=True)):
|
99 |
+
from datetime import datetime, timezone, timedelta
|
100 |
+
progress(0, desc="Updating gallery...")
|
101 |
+
dt_now = datetime.now(timezone(timedelta(hours=9)))
|
102 |
+
basename = dt_now.strftime('%Y%m%d_%H%M%S_')
|
103 |
+
i = 1
|
104 |
+
if not images: return images
|
105 |
+
output_images = []
|
106 |
+
output_paths = []
|
107 |
+
for image in images:
|
108 |
+
filename = basename + str(i) + ".png"
|
109 |
+
i += 1
|
110 |
+
oldpath = Path(image[0])
|
111 |
+
newpath = oldpath
|
112 |
+
try:
|
113 |
+
if oldpath.exists():
|
114 |
+
newpath = oldpath.resolve().rename(Path(filename).resolve())
|
115 |
+
except Exception:
|
116 |
+
pass
|
117 |
+
finally:
|
118 |
+
output_paths.append(str(newpath))
|
119 |
+
output_images.append((str(newpath), str(filename)))
|
120 |
+
progress(1, desc="Gallery updated.")
|
121 |
+
return gr.update(value=output_images), gr.update(value=output_paths), gr.update(visible=True)
|
122 |
+
|
123 |
+
|
124 |
+
def download_private_repo(repo_id, dir_path, is_replace):
|
125 |
+
from huggingface_hub import snapshot_download
|
126 |
+
if not hf_read_token: return
|
127 |
+
try:
|
128 |
+
snapshot_download(repo_id=repo_id, local_dir=dir_path, allow_patterns=['*.ckpt', '*.pt', '*.pth', '*.safetensors', '*.bin'], use_auth_token=hf_read_token)
|
129 |
+
except Exception as e:
|
130 |
+
print(f"Error: Failed to download {repo_id}. ")
|
131 |
+
return
|
132 |
+
if is_replace:
|
133 |
+
for file in Path(dir_path).glob("*"):
|
134 |
+
if file.exists() and "." in file.stem or " " in file.stem and file.suffix in ['.ckpt', '.pt', '.pth', '.safetensors', '.bin']:
|
135 |
+
newpath = Path(f'{file.parent.name}/{escape_lora_basename(file.stem)}{file.suffix}')
|
136 |
+
file.resolve().rename(newpath.resolve())
|
137 |
+
|
138 |
+
|
139 |
+
private_model_path_repo_dict = {} # {"local filepath": "huggingface repo_id", ...}
|
140 |
+
|
141 |
+
|
142 |
+
def get_private_model_list(repo_id, dir_path):
|
143 |
+
global private_model_path_repo_dict
|
144 |
+
api = HfApi()
|
145 |
+
if not hf_read_token: return []
|
146 |
+
try:
|
147 |
+
files = api.list_repo_files(repo_id, token=hf_read_token)
|
148 |
+
except Exception as e:
|
149 |
+
print(f"Error: Failed to list {repo_id}. ")
|
150 |
+
return []
|
151 |
+
model_list = []
|
152 |
+
for file in files:
|
153 |
+
path = Path(f"{dir_path}/{file}")
|
154 |
+
if path.suffix in ['.ckpt', '.pt', '.pth', '.safetensors', '.bin']:
|
155 |
+
model_list.append(str(path))
|
156 |
+
for model in model_list:
|
157 |
+
private_model_path_repo_dict[model] = repo_id
|
158 |
+
return model_list
|
159 |
+
|
160 |
+
|
161 |
+
def download_private_file(repo_id, path, is_replace):
|
162 |
+
from huggingface_hub import hf_hub_download
|
163 |
+
file = Path(path)
|
164 |
+
newpath = Path(f'{file.parent.name}/{escape_lora_basename(file.stem)}{file.suffix}') if is_replace else file
|
165 |
+
if not hf_read_token or newpath.exists(): return
|
166 |
+
filename = file.name
|
167 |
+
dirname = file.parent.name
|
168 |
+
try:
|
169 |
+
hf_hub_download(repo_id=repo_id, filename=filename, local_dir=dirname, use_auth_token=hf_read_token)
|
170 |
+
except Exception as e:
|
171 |
+
print(f"Error: Failed to download {filename}. ")
|
172 |
+
return
|
173 |
+
if is_replace:
|
174 |
+
file.resolve().rename(newpath.resolve())
|
175 |
+
|
176 |
+
|
177 |
+
def download_private_file_from_somewhere(path, is_replace):
|
178 |
+
if not path in private_model_path_repo_dict.keys(): return
|
179 |
+
repo_id = private_model_path_repo_dict.get(path, None)
|
180 |
+
download_private_file(repo_id, path, is_replace)
|
181 |
+
|
182 |
+
|
183 |
+
model_id_list = []
|
184 |
+
def get_model_id_list():
|
185 |
+
global model_id_list
|
186 |
+
if len(model_id_list) != 0: return model_id_list
|
187 |
+
api = HfApi()
|
188 |
+
model_ids = []
|
189 |
+
try:
|
190 |
+
models_likes = []
|
191 |
+
for author in HF_MODEL_USER_LIKES:
|
192 |
+
models_likes.extend(api.list_models(author=author, cardData=True, sort="likes"))
|
193 |
+
models_ex = []
|
194 |
+
for author in HF_MODEL_USER_EX:
|
195 |
+
models_ex = api.list_models(author=author, cardData=True, sort="last_modified")
|
196 |
+
except Exception as e:
|
197 |
+
print(f"Error: Failed to list {author}'s models. ")
|
198 |
+
return model_ids
|
199 |
+
for model in models_likes:
|
200 |
+
model_ids.append(model.id) if not model.private else ""
|
201 |
+
anime_models = []
|
202 |
+
real_models = []
|
203 |
+
for model in models_ex:
|
204 |
+
if not model.private:
|
205 |
+
anime_models.append(model.id) if 'anime' in model.tags else real_models.append(model.id)
|
206 |
+
model_ids.extend(anime_models)
|
207 |
+
model_ids.extend(real_models)
|
208 |
+
model_id_list = model_ids.copy()
|
209 |
+
return model_ids
|
210 |
+
|
211 |
+
|
212 |
+
model_id_list = get_model_id_list()
|
213 |
+
|
214 |
+
|
215 |
+
def get_t2i_model_info(repo_id: str):
|
216 |
+
api = HfApi()
|
217 |
+
try:
|
218 |
+
if " " in repo_id or not api.repo_exists(repo_id): return ""
|
219 |
+
model = api.model_info(repo_id=repo_id)
|
220 |
+
except Exception as e:
|
221 |
+
print(f"Error: Failed to get {repo_id}'s info. ")
|
222 |
+
return ""
|
223 |
+
if model.private or model.gated: return ""
|
224 |
+
tags = model.tags
|
225 |
+
info = []
|
226 |
+
url = f"https://huggingface.co/{repo_id}/"
|
227 |
+
if not 'diffusers' in tags: return ""
|
228 |
+
if 'diffusers:StableDiffusionXLPipeline' in tags:
|
229 |
+
info.append("SDXL")
|
230 |
+
elif 'diffusers:StableDiffusionPipeline' in tags:
|
231 |
+
info.append("SD1.5")
|
232 |
+
if model.card_data and model.card_data.tags:
|
233 |
+
info.extend(list_sub(model.card_data.tags, ['text-to-image', 'stable-diffusion', 'stable-diffusion-api', 'safetensors', 'stable-diffusion-xl']))
|
234 |
+
info.append(f"DLs: {model.downloads}")
|
235 |
+
info.append(f"likes: {model.likes}")
|
236 |
+
info.append(model.last_modified.strftime("lastmod: %Y-%m-%d"))
|
237 |
+
md = f"Model Info: {', '.join(info)}, [Model Repo]({url})"
|
238 |
+
return gr.update(value=md)
|
239 |
+
|
240 |
+
|
241 |
+
def get_tupled_model_list(model_list):
|
242 |
+
if not model_list: return []
|
243 |
+
tupled_list = []
|
244 |
+
for repo_id in model_list:
|
245 |
+
api = HfApi()
|
246 |
+
try:
|
247 |
+
if not api.repo_exists(repo_id): continue
|
248 |
+
model = api.model_info(repo_id=repo_id)
|
249 |
+
except Exception as e:
|
250 |
+
continue
|
251 |
+
if model.private or model.gated: continue
|
252 |
+
tags = model.tags
|
253 |
+
info = []
|
254 |
+
if not 'diffusers' in tags: continue
|
255 |
+
if 'diffusers:StableDiffusionXLPipeline' in tags:
|
256 |
+
info.append("SDXL")
|
257 |
+
elif 'diffusers:StableDiffusionPipeline' in tags:
|
258 |
+
info.append("SD1.5")
|
259 |
+
if model.card_data and model.card_data.tags:
|
260 |
+
info.extend(list_sub(model.card_data.tags, ['text-to-image', 'stable-diffusion', 'stable-diffusion-api', 'safetensors', 'stable-diffusion-xl']))
|
261 |
+
if "pony" in info:
|
262 |
+
info.remove("pony")
|
263 |
+
name = f"{repo_id} (Pony🐴, {', '.join(info)})"
|
264 |
+
else:
|
265 |
+
name = f"{repo_id} ({', '.join(info)})"
|
266 |
+
tupled_list.append((name, repo_id))
|
267 |
+
return tupled_list
|
268 |
+
|
269 |
+
|
270 |
+
private_lora_dict = {}
|
271 |
+
try:
|
272 |
+
with open('lora_dict.json', encoding='utf-8') as f:
|
273 |
+
d = json.load(f)
|
274 |
+
for k, v in d.items():
|
275 |
+
private_lora_dict[escape_lora_basename(k)] = v
|
276 |
+
except Exception:
|
277 |
+
pass
|
278 |
+
loras_dict = {"None": ["", "", "", "", ""], "": ["", "", "", "", ""]} | private_lora_dict.copy()
|
279 |
+
civitai_not_exists_list = []
|
280 |
+
loras_url_to_path_dict = {} # {"URL to download": "local filepath", ...}
|
281 |
+
civitai_lora_last_results = {} # {"URL to download": {search results}, ...}
|
282 |
+
all_lora_list = []
|
283 |
+
|
284 |
+
|
285 |
+
private_lora_model_list = []
|
286 |
+
def get_private_lora_model_lists():
|
287 |
+
global private_lora_model_list
|
288 |
+
if len(private_lora_model_list) != 0: return private_lora_model_list
|
289 |
+
models1 = []
|
290 |
+
models2 = []
|
291 |
+
for repo in HF_LORA_PRIVATE_REPOS1:
|
292 |
+
models1.extend(get_private_model_list(repo, directory_loras))
|
293 |
+
for repo in HF_LORA_PRIVATE_REPOS2:
|
294 |
+
models2.extend(get_private_model_list(repo, directory_loras))
|
295 |
+
models = list_uniq(models1 + sorted(models2))
|
296 |
+
private_lora_model_list = models.copy()
|
297 |
+
return models
|
298 |
+
|
299 |
+
|
300 |
+
private_lora_model_list = get_private_lora_model_lists()
|
301 |
+
|
302 |
+
|
303 |
+
def get_civitai_info(path):
|
304 |
+
global civitai_not_exists_list
|
305 |
+
import requests
|
306 |
+
from urllib3.util import Retry
|
307 |
+
from requests.adapters import HTTPAdapter
|
308 |
+
if path in set(civitai_not_exists_list): return ["", "", "", "", ""]
|
309 |
+
if not Path(path).exists(): return None
|
310 |
+
user_agent = get_user_agent()
|
311 |
+
headers = {'User-Agent': user_agent, 'content-type': 'application/json'}
|
312 |
+
base_url = 'https://civitai.com/api/v1/model-versions/by-hash/'
|
313 |
+
params = {}
|
314 |
+
session = requests.Session()
|
315 |
+
retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
|
316 |
+
session.mount("https://", HTTPAdapter(max_retries=retries))
|
317 |
+
import hashlib
|
318 |
+
with open(path, 'rb') as file:
|
319 |
+
file_data = file.read()
|
320 |
+
hash_sha256 = hashlib.sha256(file_data).hexdigest()
|
321 |
+
url = base_url + hash_sha256
|
322 |
+
try:
|
323 |
+
r = session.get(url, params=params, headers=headers, stream=True, timeout=(3.0, 15))
|
324 |
+
except Exception as e:
|
325 |
+
return ["", "", "", "", ""]
|
326 |
+
if not r.ok: return None
|
327 |
+
json = r.json()
|
328 |
+
if not 'baseModel' in json:
|
329 |
+
civitai_not_exists_list.append(path)
|
330 |
+
return ["", "", "", "", ""]
|
331 |
+
items = []
|
332 |
+
items.append(" / ".join(json['trainedWords']))
|
333 |
+
items.append(json['baseModel'])
|
334 |
+
items.append(json['model']['name'])
|
335 |
+
items.append(f"https://civitai.com/models/{json['modelId']}")
|
336 |
+
items.append(json['images'][0]['url'])
|
337 |
+
return items
|
338 |
+
|
339 |
+
|
340 |
+
def get_lora_model_list():
|
341 |
+
loras = list_uniq(get_private_lora_model_lists() + get_local_model_list(directory_loras))
|
342 |
+
loras.insert(0, "None")
|
343 |
+
loras.insert(0, "")
|
344 |
+
return loras
|
345 |
+
|
346 |
+
|
347 |
+
def get_all_lora_list():
|
348 |
+
global all_lora_list
|
349 |
+
loras = get_lora_model_list()
|
350 |
+
all_lora_list = loras.copy()
|
351 |
+
return loras
|
352 |
+
|
353 |
+
|
354 |
+
def get_all_lora_tupled_list():
|
355 |
+
global loras_dict
|
356 |
+
models = get_all_lora_list()
|
357 |
+
if not models: return []
|
358 |
+
tupled_list = []
|
359 |
+
for model in models:
|
360 |
+
#if not model: continue # to avoid GUI-related bug
|
361 |
+
basename = Path(model).stem
|
362 |
+
key = to_lora_key(model)
|
363 |
+
items = None
|
364 |
+
if key in loras_dict.keys():
|
365 |
+
items = loras_dict.get(key, None)
|
366 |
+
else:
|
367 |
+
items = get_civitai_info(model)
|
368 |
+
if items != None:
|
369 |
+
loras_dict[key] = items
|
370 |
+
name = basename
|
371 |
+
value = model
|
372 |
+
if items and items[2] != "":
|
373 |
+
if items[1] == "Pony":
|
374 |
+
name = f"{basename} (for {items[1]}🐴, {items[2]})"
|
375 |
+
else:
|
376 |
+
name = f"{basename} (for {items[1]}, {items[2]})"
|
377 |
+
tupled_list.append((name, value))
|
378 |
+
return tupled_list
|
379 |
+
|
380 |
+
|
381 |
+
def update_lora_dict(path):
|
382 |
+
global loras_dict
|
383 |
+
key = escape_lora_basename(Path(path).stem)
|
384 |
+
if key in loras_dict.keys(): return
|
385 |
+
items = get_civitai_info(path)
|
386 |
+
if items == None: return
|
387 |
+
loras_dict[key] = items
|
388 |
+
|
389 |
+
|
390 |
+
def download_lora(dl_urls: str):
|
391 |
+
global loras_url_to_path_dict
|
392 |
+
dl_path = ""
|
393 |
+
before = get_local_model_list(directory_loras)
|
394 |
+
urls = []
|
395 |
+
for url in [url.strip() for url in dl_urls.split(',')]:
|
396 |
+
local_path = f"{directory_loras}/{url.split('/')[-1]}"
|
397 |
+
if not Path(local_path).exists():
|
398 |
+
download_things(directory_loras, url, hf_token, CIVITAI_API_KEY)
|
399 |
+
urls.append(url)
|
400 |
+
after = get_local_model_list(directory_loras)
|
401 |
+
new_files = list_sub(after, before)
|
402 |
+
i = 0
|
403 |
+
for file in new_files:
|
404 |
+
path = Path(file)
|
405 |
+
if path.exists():
|
406 |
+
new_path = Path(f'{path.parent.name}/{escape_lora_basename(path.stem)}{path.suffix}')
|
407 |
+
path.resolve().rename(new_path.resolve())
|
408 |
+
loras_url_to_path_dict[urls[i]] = str(new_path)
|
409 |
+
update_lora_dict(str(new_path))
|
410 |
+
dl_path = str(new_path)
|
411 |
+
i += 1
|
412 |
+
return dl_path
|
413 |
+
|
414 |
+
|
415 |
+
def copy_lora(path: str, new_path: str):
|
416 |
+
import shutil
|
417 |
+
if path == new_path: return new_path
|
418 |
+
cpath = Path(path)
|
419 |
+
npath = Path(new_path)
|
420 |
+
if cpath.exists():
|
421 |
+
try:
|
422 |
+
shutil.copy(str(cpath.resolve()), str(npath.resolve()))
|
423 |
+
except Exception:
|
424 |
+
return None
|
425 |
+
update_lora_dict(str(npath))
|
426 |
+
return new_path
|
427 |
+
else:
|
428 |
+
return None
|
429 |
+
|
430 |
+
|
431 |
+
def download_my_lora(dl_urls: str, lora1: str, lora2: str, lora3: str, lora4: str, lora5: str):
|
432 |
+
path = download_lora(dl_urls)
|
433 |
+
if path:
|
434 |
+
if not lora1 or lora1 == "None":
|
435 |
+
lora1 = path
|
436 |
+
elif not lora2 or lora2 == "None":
|
437 |
+
lora2 = path
|
438 |
+
elif not lora3 or lora3 == "None":
|
439 |
+
lora3 = path
|
440 |
+
elif not lora4 or lora4 == "None":
|
441 |
+
lora4 = path
|
442 |
+
elif not lora5 or lora5 == "None":
|
443 |
+
lora5 = path
|
444 |
+
choices = get_all_lora_tupled_list()
|
445 |
+
return gr.update(value=lora1, choices=choices), gr.update(value=lora2, choices=choices), gr.update(value=lora3, choices=choices),\
|
446 |
+
gr.update(value=lora4, choices=choices), gr.update(value=lora5, choices=choices)
|
447 |
+
|
448 |
+
|
449 |
+
def get_valid_lora_name(query: str):
|
450 |
+
path = "None"
|
451 |
+
if not query or query == "None": return "None"
|
452 |
+
if to_lora_key(query) in loras_dict.keys(): return query
|
453 |
+
if query in loras_url_to_path_dict.keys():
|
454 |
+
path = loras_url_to_path_dict[query]
|
455 |
+
else:
|
456 |
+
path = to_lora_path(query.strip().split('/')[-1])
|
457 |
+
if Path(path).exists():
|
458 |
+
return path
|
459 |
+
elif "http" in query:
|
460 |
+
dl_file = download_lora(query)
|
461 |
+
if dl_file and Path(dl_file).exists(): return dl_file
|
462 |
+
else:
|
463 |
+
dl_file = find_similar_lora(query)
|
464 |
+
if dl_file and Path(dl_file).exists(): return dl_file
|
465 |
+
return "None"
|
466 |
+
|
467 |
+
|
468 |
+
def get_valid_lora_path(query: str):
|
469 |
+
path = None
|
470 |
+
if not query or query == "None": return None
|
471 |
+
if to_lora_key(query) in loras_dict.keys(): return query
|
472 |
+
if Path(path).exists():
|
473 |
+
return path
|
474 |
+
else:
|
475 |
+
return None
|
476 |
+
|
477 |
+
|
478 |
+
def get_valid_lora_wt(prompt: str, lora_path: str, lora_wt: float):
|
479 |
+
import re
|
480 |
+
wt = lora_wt
|
481 |
+
result = re.findall(f'<lora:{to_lora_key(lora_path)}:(.+?)>', prompt)
|
482 |
+
if not result: return wt
|
483 |
+
wt = safe_float(result[0][0])
|
484 |
+
return wt
|
485 |
+
|
486 |
+
|
487 |
+
def set_prompt_loras(prompt, prompt_syntax, lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt):
|
488 |
+
import re
|
489 |
+
if not "Classic" in str(prompt_syntax): return lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt
|
490 |
+
lora1 = get_valid_lora_name(lora1)
|
491 |
+
lora2 = get_valid_lora_name(lora2)
|
492 |
+
lora3 = get_valid_lora_name(lora3)
|
493 |
+
lora4 = get_valid_lora_name(lora4)
|
494 |
+
lora5 = get_valid_lora_name(lora5)
|
495 |
+
if not "<lora" in prompt: return lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt
|
496 |
+
lora1_wt = get_valid_lora_wt(prompt, lora1, lora1_wt)
|
497 |
+
lora2_wt = get_valid_lora_wt(prompt, lora2, lora2_wt)
|
498 |
+
lora3_wt = get_valid_lora_wt(prompt, lora3, lora3_wt)
|
499 |
+
lora4_wt = get_valid_lora_wt(prompt, lora4, lora4_wt)
|
500 |
+
lora5_wt = get_valid_lora_wt(prompt, lora5, lora5_wt)
|
501 |
+
on1, label1, tag1, md1 = get_lora_info(lora1)
|
502 |
+
on2, label2, tag2, md2 = get_lora_info(lora2)
|
503 |
+
on3, label3, tag3, md3 = get_lora_info(lora3)
|
504 |
+
on4, label4, tag4, md4 = get_lora_info(lora4)
|
505 |
+
on5, label5, tag5, md5 = get_lora_info(lora5)
|
506 |
+
lora_paths = [lora1, lora2, lora3, lora4, lora5]
|
507 |
+
prompts = prompt.split(",") if prompt else []
|
508 |
+
for p in prompts:
|
509 |
+
p = str(p).strip()
|
510 |
+
if "<lora" in p:
|
511 |
+
result = re.findall(r'<lora:(.+?):(.+?)>', p)
|
512 |
+
if not result: continue
|
513 |
+
key = result[0][0]
|
514 |
+
wt = result[0][1]
|
515 |
+
path = to_lora_path(key)
|
516 |
+
if not key in loras_dict.keys() or not path:
|
517 |
+
path = get_valid_lora_name(path)
|
518 |
+
if not path or path == "None": continue
|
519 |
+
if path in lora_paths:
|
520 |
+
continue
|
521 |
+
elif not on1:
|
522 |
+
lora1 = path
|
523 |
+
lora_paths = [lora1, lora2, lora3, lora4, lora5]
|
524 |
+
lora1_wt = safe_float(wt)
|
525 |
+
on1 = True
|
526 |
+
elif not on2:
|
527 |
+
lora2 = path
|
528 |
+
lora_paths = [lora1, lora2, lora3, lora4, lora5]
|
529 |
+
lora2_wt = safe_float(wt)
|
530 |
+
on2 = True
|
531 |
+
elif not on3:
|
532 |
+
lora3 = path
|
533 |
+
lora_paths = [lora1, lora2, lora3, lora4, lora5]
|
534 |
+
lora3_wt = safe_float(wt)
|
535 |
+
on3 = True
|
536 |
+
elif not on4:
|
537 |
+
lora4 = path
|
538 |
+
lora_paths = [lora1, lora2, lora3, lora4, lora5]
|
539 |
+
lora4_wt = safe_float(wt)
|
540 |
+
on4, label4, tag4, md4 = get_lora_info(lora4)
|
541 |
+
elif not on5:
|
542 |
+
lora5 = path
|
543 |
+
lora_paths = [lora1, lora2, lora3, lora4, lora5]
|
544 |
+
lora5_wt = safe_float(wt)
|
545 |
+
on5 = True
|
546 |
+
return lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt
|
547 |
+
|
548 |
+
|
549 |
+
def get_lora_info(lora_path: str):
|
550 |
+
is_valid = False
|
551 |
+
tag = ""
|
552 |
+
label = ""
|
553 |
+
md = "None"
|
554 |
+
if not lora_path or lora_path == "None":
|
555 |
+
print("LoRA file not found.")
|
556 |
+
return is_valid, label, tag, md
|
557 |
+
path = Path(lora_path)
|
558 |
+
new_path = Path(f'{path.parent.name}/{escape_lora_basename(path.stem)}{path.suffix}')
|
559 |
+
if not to_lora_key(str(new_path)) in loras_dict.keys() and str(path) not in set(get_all_lora_list()):
|
560 |
+
print("LoRA file is not registered.")
|
561 |
+
return tag, label, tag, md
|
562 |
+
if not new_path.exists():
|
563 |
+
download_private_file_from_somewhere(str(path), True)
|
564 |
+
basename = new_path.stem
|
565 |
+
label = f'Name: {basename}'
|
566 |
+
items = loras_dict.get(basename, None)
|
567 |
+
if items == None:
|
568 |
+
items = get_civitai_info(str(new_path))
|
569 |
+
if items != None:
|
570 |
+
loras_dict[basename] = items
|
571 |
+
if items and items[2] != "":
|
572 |
+
tag = items[0]
|
573 |
+
label = f'Name: {basename}'
|
574 |
+
if items[1] == "Pony":
|
575 |
+
label = f'Name: {basename} (for Pony🐴)'
|
576 |
+
if items[4]:
|
577 |
+
md = f'<img src="{items[4]}" alt="thumbnail" width="150" height="240"><br>[LoRA Model URL]({items[3]})'
|
578 |
+
elif items[3]:
|
579 |
+
md = f'[LoRA Model URL]({items[3]})'
|
580 |
+
is_valid = True
|
581 |
+
return is_valid, label, tag, md
|
582 |
+
|
583 |
+
|
584 |
+
def normalize_prompt_list(tags: list[str]):
|
585 |
+
prompts = []
|
586 |
+
for tag in tags:
|
587 |
+
tag = str(tag).strip()
|
588 |
+
if tag:
|
589 |
+
prompts.append(tag)
|
590 |
+
return prompts
|
591 |
+
|
592 |
+
|
593 |
+
def apply_lora_prompt(prompt: str = "", lora_info: str = ""):
|
594 |
+
if lora_info == "None": return gr.update(value=prompt)
|
595 |
+
tags = prompt.split(",") if prompt else []
|
596 |
+
prompts = normalize_prompt_list(tags)
|
597 |
+
|
598 |
+
lora_tag = lora_info.replace("/",",")
|
599 |
+
lora_tags = lora_tag.split(",") if str(lora_info) != "None" else []
|
600 |
+
lora_prompts = normalize_prompt_list(lora_tags)
|
601 |
+
|
602 |
+
empty = [""]
|
603 |
+
prompt = ", ".join(list_uniq(prompts + lora_prompts) + empty)
|
604 |
+
return gr.update(value=prompt)
|
605 |
+
|
606 |
+
|
607 |
+
def update_loras(prompt, prompt_syntax, lora1, lora1_wt, lora2, lora2_wt, lora3, lora3_wt, lora4, lora4_wt, lora5, lora5_wt):
|
608 |
+
import re
|
609 |
+
on1, label1, tag1, md1 = get_lora_info(lora1)
|
610 |
+
on2, label2, tag2, md2 = get_lora_info(lora2)
|
611 |
+
on3, label3, tag3, md3 = get_lora_info(lora3)
|
612 |
+
on4, label4, tag4, md4 = get_lora_info(lora4)
|
613 |
+
on5, label5, tag5, md5 = get_lora_info(lora5)
|
614 |
+
lora_paths = [lora1, lora2, lora3, lora4, lora5]
|
615 |
+
|
616 |
+
output_prompt = prompt
|
617 |
+
if "Classic" in str(prompt_syntax):
|
618 |
+
prompts = prompt.split(",") if prompt else []
|
619 |
+
output_prompts = []
|
620 |
+
for p in prompts:
|
621 |
+
p = str(p).strip()
|
622 |
+
if "<lora" in p:
|
623 |
+
result = re.findall(r'<lora:(.+?):(.+?)>', p)
|
624 |
+
if not result: continue
|
625 |
+
key = result[0][0]
|
626 |
+
wt = result[0][1]
|
627 |
+
path = to_lora_path(key)
|
628 |
+
if not key in loras_dict.keys() or not path: continue
|
629 |
+
if path in lora_paths:
|
630 |
+
output_prompts.append(f"<lora:{to_lora_key(path)}:{safe_float(wt):.2f}>")
|
631 |
+
elif p:
|
632 |
+
output_prompts.append(p)
|
633 |
+
lora_prompts = []
|
634 |
+
if on1: lora_prompts.append(f"<lora:{to_lora_key(lora1)}:{lora1_wt:.2f}>")
|
635 |
+
if on2: lora_prompts.append(f"<lora:{to_lora_key(lora2)}:{lora2_wt:.2f}>")
|
636 |
+
if on3: lora_prompts.append(f"<lora:{to_lora_key(lora3)}:{lora3_wt:.2f}>")
|
637 |
+
if on4: lora_prompts.append(f"<lora:{to_lora_key(lora4)}:{lora4_wt:.2f}>")
|
638 |
+
if on5: lora_prompts.append(f"<lora:{to_lora_key(lora5)}:{lora5_wt:.2f}>")
|
639 |
+
output_prompt = ", ".join(list_uniq(output_prompts + lora_prompts + [""]))
|
640 |
+
choices = get_all_lora_tupled_list()
|
641 |
+
|
642 |
+
return gr.update(value=output_prompt), gr.update(value=lora1, choices=choices), gr.update(value=lora1_wt),\
|
643 |
+
gr.update(value=tag1, label=label1, visible=on1), gr.update(visible=on1), gr.update(value=md1, visible=on1),\
|
644 |
+
gr.update(value=lora2, choices=choices), gr.update(value=lora2_wt),\
|
645 |
+
gr.update(value=tag2, label=label2, visible=on2), gr.update(visible=on2), gr.update(value=md2, visible=on2),\
|
646 |
+
gr.update(value=lora3, choices=choices), gr.update(value=lora3_wt),\
|
647 |
+
gr.update(value=tag3, label=label3, visible=on3), gr.update(visible=on3), gr.update(value=md3, visible=on3),\
|
648 |
+
gr.update(value=lora4, choices=choices), gr.update(value=lora4_wt),\
|
649 |
+
gr.update(value=tag4, label=label4, visible=on4), gr.update(visible=on4), gr.update(value=md4, visible=on4),\
|
650 |
+
gr.update(value=lora5, choices=choices), gr.update(value=lora5_wt),\
|
651 |
+
gr.update(value=tag5, label=label5, visible=on5), gr.update(visible=on5), gr.update(value=md5, visible=on5)
|
652 |
+
|
653 |
+
|
654 |
+
def get_my_lora(link_url):
|
655 |
+
from pathlib import Path
|
656 |
+
before = get_local_model_list(directory_loras)
|
657 |
+
for url in [url.strip() for url in link_url.split(',')]:
|
658 |
+
if not Path(f"{directory_loras}/{url.split('/')[-1]}").exists():
|
659 |
+
download_things(directory_loras, url, hf_token, CIVITAI_API_KEY)
|
660 |
+
after = get_local_model_list(directory_loras)
|
661 |
+
new_files = list_sub(after, before)
|
662 |
+
for file in new_files:
|
663 |
+
path = Path(file)
|
664 |
+
if path.exists():
|
665 |
+
new_path = Path(f'{path.parent.name}/{escape_lora_basename(path.stem)}{path.suffix}')
|
666 |
+
path.resolve().rename(new_path.resolve())
|
667 |
+
update_lora_dict(str(new_path))
|
668 |
+
new_lora_model_list = get_lora_model_list()
|
669 |
+
new_lora_tupled_list = get_all_lora_tupled_list()
|
670 |
+
|
671 |
+
return gr.update(
|
672 |
+
choices=new_lora_tupled_list, value=new_lora_model_list[-1]
|
673 |
+
), gr.update(
|
674 |
+
choices=new_lora_tupled_list
|
675 |
+
), gr.update(
|
676 |
+
choices=new_lora_tupled_list
|
677 |
+
), gr.update(
|
678 |
+
choices=new_lora_tupled_list
|
679 |
+
), gr.update(
|
680 |
+
choices=new_lora_tupled_list
|
681 |
+
)
|
682 |
+
|
683 |
+
|
684 |
+
def upload_file_lora(files, progress=gr.Progress(track_tqdm=True)):
|
685 |
+
progress(0, desc="Uploading...")
|
686 |
+
file_paths = [file.name for file in files]
|
687 |
+
progress(1, desc="Uploaded.")
|
688 |
+
return gr.update(value=file_paths, visible=True), gr.update(visible=True)
|
689 |
+
|
690 |
+
|
691 |
+
def move_file_lora(filepaths):
|
692 |
+
import shutil
|
693 |
+
for file in filepaths:
|
694 |
+
path = Path(shutil.move(Path(file).resolve(), Path(f"./{directory_loras}").resolve()))
|
695 |
+
newpath = Path(f'{path.parent.name}/{escape_lora_basename(path.stem)}{path.suffix}')
|
696 |
+
path.resolve().rename(newpath.resolve())
|
697 |
+
update_lora_dict(str(newpath))
|
698 |
+
|
699 |
+
new_lora_model_list = get_lora_model_list()
|
700 |
+
new_lora_tupled_list = get_all_lora_tupled_list()
|
701 |
+
|
702 |
+
return gr.update(
|
703 |
+
choices=new_lora_tupled_list, value=new_lora_model_list[-1]
|
704 |
+
), gr.update(
|
705 |
+
choices=new_lora_tupled_list
|
706 |
+
), gr.update(
|
707 |
+
choices=new_lora_tupled_list
|
708 |
+
), gr.update(
|
709 |
+
choices=new_lora_tupled_list
|
710 |
+
), gr.update(
|
711 |
+
choices=new_lora_tupled_list
|
712 |
+
)
|
713 |
+
|
714 |
+
|
715 |
+
def get_civitai_info(path):
|
716 |
+
global civitai_not_exists_list
|
717 |
+
global loras_url_to_path_dict
|
718 |
+
import requests
|
719 |
+
from requests.adapters import HTTPAdapter
|
720 |
+
from urllib3.util import Retry
|
721 |
+
default = ["", "", "", "", ""]
|
722 |
+
if path in set(civitai_not_exists_list): return default
|
723 |
+
if not Path(path).exists(): return None
|
724 |
+
user_agent = get_user_agent()
|
725 |
+
headers = {'User-Agent': user_agent, 'content-type': 'application/json'}
|
726 |
+
base_url = 'https://civitai.com/api/v1/model-versions/by-hash/'
|
727 |
+
params = {}
|
728 |
+
session = requests.Session()
|
729 |
+
retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
|
730 |
+
session.mount("https://", HTTPAdapter(max_retries=retries))
|
731 |
+
import hashlib
|
732 |
+
with open(path, 'rb') as file:
|
733 |
+
file_data = file.read()
|
734 |
+
hash_sha256 = hashlib.sha256(file_data).hexdigest()
|
735 |
+
url = base_url + hash_sha256
|
736 |
+
try:
|
737 |
+
r = session.get(url, params=params, headers=headers, stream=True, timeout=(3.0, 15))
|
738 |
+
except Exception as e:
|
739 |
+
print(e)
|
740 |
+
return default
|
741 |
+
else:
|
742 |
+
if not r.ok: return None
|
743 |
+
json = r.json()
|
744 |
+
if 'baseModel' not in json:
|
745 |
+
civitai_not_exists_list.append(path)
|
746 |
+
return default
|
747 |
+
items = []
|
748 |
+
items.append(" / ".join(json['trainedWords'])) # The words (prompts) used to trigger the model
|
749 |
+
items.append(json['baseModel']) # Base model (SDXL1.0, Pony, ...)
|
750 |
+
items.append(json['model']['name']) # The name of the model version
|
751 |
+
items.append(f"https://civitai.com/models/{json['modelId']}") # The repo url for the model
|
752 |
+
items.append(json['images'][0]['url']) # The url for a sample image
|
753 |
+
loras_url_to_path_dict[path] = json['downloadUrl'] # The download url to get the model file for this specific version
|
754 |
+
return items
|
755 |
+
|
756 |
+
|
757 |
+
def search_lora_on_civitai(query: str, allow_model: list[str] = ["Pony", "SDXL 1.0"], limit: int = 100):
|
758 |
+
import requests
|
759 |
+
from requests.adapters import HTTPAdapter
|
760 |
+
from urllib3.util import Retry
|
761 |
+
if not query: return None
|
762 |
+
user_agent = get_user_agent()
|
763 |
+
headers = {'User-Agent': user_agent, 'content-type': 'application/json'}
|
764 |
+
base_url = 'https://civitai.com/api/v1/models'
|
765 |
+
params = {'query': query, 'types': ['LORA'], 'sort': 'Highest Rated', 'period': 'AllTime',
|
766 |
+
'nsfw': 'true', 'supportsGeneration ': 'true', 'limit': limit}
|
767 |
+
session = requests.Session()
|
768 |
+
retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504])
|
769 |
+
session.mount("https://", HTTPAdapter(max_retries=retries))
|
770 |
+
try:
|
771 |
+
r = session.get(base_url, params=params, headers=headers, stream=True, timeout=(3.0, 30))
|
772 |
+
except Exception as e:
|
773 |
+
print(e)
|
774 |
+
return None
|
775 |
+
else:
|
776 |
+
if not r.ok: return None
|
777 |
+
json = r.json()
|
778 |
+
if 'items' not in json: return None
|
779 |
+
items = []
|
780 |
+
for j in json['items']:
|
781 |
+
for model in j['modelVersions']:
|
782 |
+
item = {}
|
783 |
+
if model['baseModel'] not in set(allow_model): continue
|
784 |
+
item['name'] = j['name']
|
785 |
+
item['creator'] = j['creator']['username']
|
786 |
+
item['tags'] = j['tags']
|
787 |
+
item['model_name'] = model['name']
|
788 |
+
item['base_model'] = model['baseModel']
|
789 |
+
item['dl_url'] = model['downloadUrl']
|
790 |
+
item['md'] = f'<img src="{model["images"][0]["url"]}" alt="thumbnail" width="150" height="240"><br>[LoRA Model URL](https://civitai.com/models/{j["id"]})'
|
791 |
+
items.append(item)
|
792 |
+
return items
|
793 |
+
|
794 |
+
|
795 |
+
def search_civitai_lora(query, base_model):
|
796 |
+
global civitai_lora_last_results
|
797 |
+
items = search_lora_on_civitai(query, base_model)
|
798 |
+
if not items: return gr.update(choices=[("", "")], value="", visible=False),\
|
799 |
+
gr.update(value="", visible=False), gr.update(visible=True), gr.update(visible=True)
|
800 |
+
civitai_lora_last_results = {}
|
801 |
+
choices = []
|
802 |
+
for item in items:
|
803 |
+
base_model_name = "Pony🐴" if item['base_model'] == "Pony" else item['base_model']
|
804 |
+
name = f"{item['name']} (for {base_model_name} / By: {item['creator']} / Tags: {', '.join(item['tags'])})"
|
805 |
+
value = item['dl_url']
|
806 |
+
choices.append((name, value))
|
807 |
+
civitai_lora_last_results[value] = item
|
808 |
+
if not choices: return gr.update(choices=[("", "")], value="", visible=False),\
|
809 |
+
gr.update(value="", visible=False), gr.update(visible=True), gr.update(visible=True)
|
810 |
+
result = civitai_lora_last_results.get(choices[0][1], "None")
|
811 |
+
md = result['md'] if result else ""
|
812 |
+
return gr.update(choices=choices, value=choices[0][1], visible=True), gr.update(value=md, visible=True),\
|
813 |
+
gr.update(visible=True), gr.update(visible=True)
|
814 |
+
|
815 |
+
|
816 |
+
def select_civitai_lora(search_result):
|
817 |
+
if not "http" in search_result: return gr.update(value=""), gr.update(value="None", visible=True)
|
818 |
+
result = civitai_lora_last_results.get(search_result, "None")
|
819 |
+
md = result['md'] if result else ""
|
820 |
+
return gr.update(value=search_result), gr.update(value=md, visible=True)
|
821 |
+
|
822 |
+
|
823 |
+
def find_similar_lora(q: str):
|
824 |
+
from rapidfuzz.process import extractOne
|
825 |
+
from rapidfuzz.utils import default_process
|
826 |
+
query = to_lora_key(q)
|
827 |
+
print(f"Finding <lora:{query}:...>...")
|
828 |
+
keys = list(private_lora_dict.keys())
|
829 |
+
values = [x[2] for x in list(private_lora_dict.values())]
|
830 |
+
s = default_process(query)
|
831 |
+
e1 = extractOne(s, keys + values, processor=default_process, score_cutoff=80.0)
|
832 |
+
key = ""
|
833 |
+
if e1:
|
834 |
+
e = e1[0]
|
835 |
+
if e in set(keys): key = e
|
836 |
+
elif e in set(values): key = keys[values.index(e)]
|
837 |
+
if key:
|
838 |
+
path = to_lora_path(key)
|
839 |
+
new_path = to_lora_path(query)
|
840 |
+
if not Path(path).exists():
|
841 |
+
if not Path(new_path).exists(): download_private_file_from_somewhere(path, True)
|
842 |
+
if Path(path).exists() and copy_lora(path, new_path): return new_path
|
843 |
+
print(f"Finding <lora:{query}:...> on Civitai...")
|
844 |
+
civitai_query = Path(query).stem if Path(query).is_file() else query
|
845 |
+
civitai_query = civitai_query.replace("_", " ").replace("-", " ")
|
846 |
+
base_model = ["Pony", "SDXL 1.0"]
|
847 |
+
items = search_lora_on_civitai(civitai_query, base_model, 1)
|
848 |
+
if items:
|
849 |
+
item = items[0]
|
850 |
+
path = download_lora(item['dl_url'])
|
851 |
+
new_path = query if Path(query).is_file() else to_lora_path(query)
|
852 |
+
if path and copy_lora(path, new_path): return new_path
|
853 |
+
return None
|
854 |
+
|
855 |
+
|
856 |
+
def change_interface_mode(mode: str):
|
857 |
+
if mode == "Fast":
|
858 |
+
return gr.update(open=False), gr.update(visible=True), gr.update(open=False), gr.update(open=False),\
|
859 |
+
gr.update(visible=True), gr.update(open=False), gr.update(visible=True), gr.update(open=False),\
|
860 |
+
gr.update(visible=True), gr.update(value="Fast")
|
861 |
+
elif mode == "Simple": # t2i mode
|
862 |
+
return gr.update(open=True), gr.update(visible=True), gr.update(open=False), gr.update(open=False),\
|
863 |
+
gr.update(visible=True), gr.update(open=False), gr.update(visible=False), gr.update(open=True),\
|
864 |
+
gr.update(visible=False), gr.update(value="Standard")
|
865 |
+
elif mode == "LoRA": # t2i LoRA mode
|
866 |
+
return gr.update(open=True), gr.update(visible=True), gr.update(open=True), gr.update(open=False),\
|
867 |
+
gr.update(visible=True), gr.update(open=True), gr.update(visible=True), gr.update(open=False),\
|
868 |
+
gr.update(visible=False), gr.update(value="Standard")
|
869 |
+
else: # Standard
|
870 |
+
return gr.update(open=False), gr.update(visible=True), gr.update(open=False), gr.update(open=False),\
|
871 |
+
gr.update(visible=True), gr.update(open=False), gr.update(visible=True), gr.update(open=False),\
|
872 |
+
gr.update(visible=True), gr.update(value="Standard")
|
873 |
+
|
874 |
+
|
875 |
+
quality_prompt_list = [
|
876 |
+
{
|
877 |
+
"name": "None",
|
878 |
+
"prompt": "",
|
879 |
+
"negative_prompt": "lowres",
|
880 |
+
},
|
881 |
+
{
|
882 |
+
"name": "Animagine Common",
|
883 |
+
"prompt": "anime artwork, anime style, vibrant, studio anime, highly detailed, masterpiece, best quality, very aesthetic, absurdres",
|
884 |
+
"negative_prompt": "lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]",
|
885 |
+
},
|
886 |
+
{
|
887 |
+
"name": "Pony Anime Common",
|
888 |
+
"prompt": "source_anime, score_9, score_8_up, score_7_up, masterpiece, best quality, very aesthetic, absurdres",
|
889 |
+
"negative_prompt": "source_pony, source_furry, source_cartoon, score_6, score_5, score_4, busty, ugly face, mutated hands, low res, blurry face, black and white, the simpsons, overwatch, apex legends",
|
890 |
+
},
|
891 |
+
{
|
892 |
+
"name": "Pony Common",
|
893 |
+
"prompt": "source_anime, score_9, score_8_up, score_7_up",
|
894 |
+
"negative_prompt": "source_pony, source_furry, source_cartoon, score_6, score_5, score_4, busty, ugly face, mutated hands, low res, blurry face, black and white, the simpsons, overwatch, apex legends",
|
895 |
+
},
|
896 |
+
{
|
897 |
+
"name": "Animagine Standard v3.0",
|
898 |
+
"prompt": "masterpiece, best quality",
|
899 |
+
"negative_prompt": "lowres, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, worst quality, low quality, normal quality, jpeg artifacts, signature, watermark, username, blurry, artist name",
|
900 |
+
},
|
901 |
+
{
|
902 |
+
"name": "Animagine Standard v3.1",
|
903 |
+
"prompt": "masterpiece, best quality, very aesthetic, absurdres",
|
904 |
+
"negative_prompt": "lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]",
|
905 |
+
},
|
906 |
+
{
|
907 |
+
"name": "Animagine Light v3.1",
|
908 |
+
"prompt": "(masterpiece), best quality, very aesthetic, perfect face",
|
909 |
+
"negative_prompt": "(low quality, worst quality:1.2), very displeasing, 3d, watermark, signature, ugly, poorly drawn",
|
910 |
+
},
|
911 |
+
{
|
912 |
+
"name": "Animagine Heavy v3.1",
|
913 |
+
"prompt": "(masterpiece), (best quality), (ultra-detailed), very aesthetic, illustration, disheveled hair, perfect composition, moist skin, intricate details",
|
914 |
+
"negative_prompt": "longbody, lowres, bad anatomy, bad hands, missing fingers, pubic hair, extra digit, fewer digits, cropped, worst quality, low quality, very displeasing",
|
915 |
+
},
|
916 |
+
]
|
917 |
+
|
918 |
+
|
919 |
+
style_list = [
|
920 |
+
{
|
921 |
+
"name": "None",
|
922 |
+
"prompt": "",
|
923 |
+
"negative_prompt": "",
|
924 |
+
},
|
925 |
+
{
|
926 |
+
"name": "Cinematic",
|
927 |
+
"prompt": "cinematic still, emotional, harmonious, vignette, highly detailed, high budget, bokeh, cinemascope, moody, epic, gorgeous, film grain, grainy",
|
928 |
+
"negative_prompt": "cartoon, graphic, text, painting, crayon, graphite, abstract, glitch, deformed, mutated, ugly, disfigured",
|
929 |
+
},
|
930 |
+
{
|
931 |
+
"name": "Photographic",
|
932 |
+
"prompt": "cinematic photo, 35mm photograph, film, bokeh, professional, 4k, highly detailed",
|
933 |
+
"negative_prompt": "drawing, painting, crayon, sketch, graphite, impressionist, noisy, blurry, soft, deformed, ugly",
|
934 |
+
},
|
935 |
+
{
|
936 |
+
"name": "Anime",
|
937 |
+
"prompt": "anime artwork, anime style, vibrant, studio anime, highly detailed",
|
938 |
+
"negative_prompt": "photo, deformed, black and white, realism, disfigured, low contrast",
|
939 |
+
},
|
940 |
+
{
|
941 |
+
"name": "Manga",
|
942 |
+
"prompt": "manga style, vibrant, high-energy, detailed, iconic, Japanese comic style",
|
943 |
+
"negative_prompt": "ugly, deformed, noisy, blurry, low contrast, realism, photorealistic, Western comic style",
|
944 |
+
},
|
945 |
+
{
|
946 |
+
"name": "Digital Art",
|
947 |
+
"prompt": "concept art, digital artwork, illustrative, painterly, matte painting, highly detailed",
|
948 |
+
"negative_prompt": "photo, photorealistic, realism, ugly",
|
949 |
+
},
|
950 |
+
{
|
951 |
+
"name": "Pixel art",
|
952 |
+
"prompt": "pixel-art, low-res, blocky, pixel art style, 8-bit graphics",
|
953 |
+
"negative_prompt": "sloppy, messy, blurry, noisy, highly detailed, ultra textured, photo, realistic",
|
954 |
+
},
|
955 |
+
{
|
956 |
+
"name": "Fantasy art",
|
957 |
+
"prompt": "ethereal fantasy concept art, magnificent, celestial, ethereal, painterly, epic, majestic, magical, fantasy art, cover art, dreamy",
|
958 |
+
"negative_prompt": "photographic, realistic, realism, 35mm film, dslr, cropped, frame, text, deformed, glitch, noise, noisy, off-center, deformed, cross-eyed, closed eyes, bad anatomy, ugly, disfigured, sloppy, duplicate, mutated, black and white",
|
959 |
+
},
|
960 |
+
{
|
961 |
+
"name": "Neonpunk",
|
962 |
+
"prompt": "neonpunk style, cyberpunk, vaporwave, neon, vibes, vibrant, stunningly beautiful, crisp, detailed, sleek, ultramodern, magenta highlights, dark purple shadows, high contrast, cinematic, ultra detailed, intricate, professional",
|
963 |
+
"negative_prompt": "painting, drawing, illustration, glitch, deformed, mutated, cross-eyed, ugly, disfigured",
|
964 |
+
},
|
965 |
+
{
|
966 |
+
"name": "3D Model",
|
967 |
+
"prompt": "professional 3d model, octane render, highly detailed, volumetric, dramatic lighting",
|
968 |
+
"negative_prompt": "ugly, deformed, noisy, low poly, blurry, painting",
|
969 |
+
},
|
970 |
+
]
|
971 |
+
|
972 |
+
|
973 |
+
optimization_list = {
|
974 |
+
"None": [28, 7., 'Euler a', False, 'None', 1.],
|
975 |
+
"Default": [28, 7., 'Euler a', False, 'None', 1.],
|
976 |
+
"SPO": [28, 7., 'Euler a', True, 'loras/spo_sdxl_10ep_4k-data_lora_diffusers.safetensors', 1.],
|
977 |
+
"DPO": [28, 7., 'Euler a', True, 'loras/sdxl-DPO-LoRA.safetensors', 1.],
|
978 |
+
"DPO Turbo": [8, 2.5, 'LCM', True, 'loras/sd_xl_dpo_turbo_lora_v1-128dim.safetensors', 1.],
|
979 |
+
"SDXL Turbo": [8, 2.5, 'LCM', True, 'loras/sd_xl_turbo_lora_v1.safetensors', 1.],
|
980 |
+
"Hyper-SDXL 12step": [12, 5., 'TCD', True, 'loras/Hyper-SDXL-12steps-CFG-lora.safetensors', 1.],
|
981 |
+
"Hyper-SDXL 8step": [8, 5., 'TCD', True, 'loras/Hyper-SDXL-8steps-CFG-lora.safetensors', 1.],
|
982 |
+
"Hyper-SDXL 4step": [4, 0, 'TCD', True, 'loras/Hyper-SDXL-4steps-lora.safetensors', 1.],
|
983 |
+
"Hyper-SDXL 2step": [2, 0, 'TCD', True, 'loras/Hyper-SDXL-2steps-lora.safetensors', 1.],
|
984 |
+
"Hyper-SDXL 1step": [1, 0, 'TCD', True, 'loras/Hyper-SDXL-1steps-lora.safetensors', 1.],
|
985 |
+
"PCM 16step": [16, 4., 'Euler a trailing', True, 'loras/pcm_sdxl_normalcfg_16step_converted.safetensors', 1.],
|
986 |
+
"PCM 8step": [8, 4., 'Euler a trailing', True, 'loras/pcm_sdxl_normalcfg_8step_converted.safetensors', 1.],
|
987 |
+
"PCM 4step": [4, 2., 'Euler a trailing', True, 'loras/pcm_sdxl_smallcfg_4step_converted.safetensors', 1.],
|
988 |
+
"PCM 2step": [2, 1., 'Euler a trailing', True, 'loras/pcm_sdxl_smallcfg_2step_converted.safetensors', 1.],
|
989 |
+
}
|
990 |
+
|
991 |
+
|
992 |
+
def set_optimization(opt, steps_gui, cfg_gui, sampler_gui, clip_skip_gui, lora_gui, lora_scale_gui):
|
993 |
+
if not opt in list(optimization_list.keys()): opt = "None"
|
994 |
+
def_steps_gui = 28
|
995 |
+
def_cfg_gui = 7.
|
996 |
+
steps = optimization_list.get(opt, "None")[0]
|
997 |
+
cfg = optimization_list.get(opt, "None")[1]
|
998 |
+
sampler = optimization_list.get(opt, "None")[2]
|
999 |
+
clip_skip = optimization_list.get(opt, "None")[3]
|
1000 |
+
lora = optimization_list.get(opt, "None")[4]
|
1001 |
+
lora_scale = optimization_list.get(opt, "None")[5]
|
1002 |
+
if opt == "None":
|
1003 |
+
steps = max(steps_gui, def_steps_gui)
|
1004 |
+
cfg = max(cfg_gui, def_cfg_gui)
|
1005 |
+
clip_skip = clip_skip_gui
|
1006 |
+
elif opt == "SPO" or opt == "DPO":
|
1007 |
+
steps = max(steps_gui, def_steps_gui)
|
1008 |
+
cfg = max(cfg_gui, def_cfg_gui)
|
1009 |
+
|
1010 |
+
return gr.update(value=steps), gr.update(value=cfg), gr.update(value=sampler),\
|
1011 |
+
gr.update(value=clip_skip), gr.update(value=lora), gr.update(value=lora_scale),
|
1012 |
+
|
1013 |
+
|
1014 |
+
# [sampler_gui, steps_gui, cfg_gui, clip_skip_gui, img_width_gui, img_height_gui, optimization_gui]
|
1015 |
+
preset_sampler_setting = {
|
1016 |
+
"None": ["Euler a", 28, 7., True, 1024, 1024, "None"],
|
1017 |
+
"Anime 3:4 Fast": ["LCM", 8, 2.5, True, 896, 1152, "DPO Turbo"],
|
1018 |
+
"Anime 3:4 Standard": ["Euler a", 28, 7., True, 896, 1152, "None"],
|
1019 |
+
"Anime 3:4 Heavy": ["Euler a", 40, 7., True, 896, 1152, "None"],
|
1020 |
+
"Anime 1:1 Fast": ["LCM", 8, 2.5, True, 1024, 1024, "DPO Turbo"],
|
1021 |
+
"Anime 1:1 Standard": ["Euler a", 28, 7., True, 1024, 1024, "None"],
|
1022 |
+
"Anime 1:1 Heavy": ["Euler a", 40, 7., True, 1024, 1024, "None"],
|
1023 |
+
"Photo 3:4 Fast": ["LCM", 8, 2.5, False, 896, 1152, "DPO Turbo"],
|
1024 |
+
"Photo 3:4 Standard": ["DPM++ 2M Karras", 28, 7., False, 896, 1152, "None"],
|
1025 |
+
"Photo 3:4 Heavy": ["DPM++ 2M Karras", 40, 7., False, 896, 1152, "None"],
|
1026 |
+
"Photo 1:1 Fast": ["LCM", 8, 2.5, False, 1024, 1024, "DPO Turbo"],
|
1027 |
+
"Photo 1:1 Standard": ["DPM++ 2M Karras", 28, 7., False, 1024, 1024, "None"],
|
1028 |
+
"Photo 1:1 Heavy": ["DPM++ 2M Karras", 40, 7., False, 1024, 1024, "None"],
|
1029 |
+
}
|
1030 |
+
|
1031 |
+
|
1032 |
+
def set_sampler_settings(sampler_setting):
|
1033 |
+
if not sampler_setting in list(preset_sampler_setting.keys()) or sampler_setting == "None":
|
1034 |
+
return gr.update(value="Euler a"), gr.update(value=28), gr.update(value=7.), gr.update(value=True),\
|
1035 |
+
gr.update(value=1024), gr.update(value=1024), gr.update(value="None")
|
1036 |
+
v = preset_sampler_setting.get(sampler_setting, ["Euler a", 28, 7., True, 1024, 1024])
|
1037 |
+
# sampler, steps, cfg, clip_skip, width, height, optimization
|
1038 |
+
return gr.update(value=v[0]), gr.update(value=v[1]), gr.update(value=v[2]), gr.update(value=v[3]),\
|
1039 |
+
gr.update(value=v[4]), gr.update(value=v[5]), gr.update(value=v[6])
|
1040 |
+
|
1041 |
+
|
1042 |
+
preset_styles = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in style_list}
|
1043 |
+
preset_quality = {k["name"]: (k["prompt"], k["negative_prompt"]) for k in quality_prompt_list}
|
1044 |
+
|
1045 |
+
|
1046 |
+
def process_style_prompt(prompt: str, neg_prompt: str, styles_key: str = "None", quality_key: str = "None", type: str = "Auto"):
|
1047 |
+
def to_list(s):
|
1048 |
+
return [x.strip() for x in s.split(",") if not s == ""]
|
1049 |
+
|
1050 |
+
def list_sub(a, b):
|
1051 |
+
return [e for e in a if e not in b]
|
1052 |
+
|
1053 |
+
def list_uniq(l):
|
1054 |
+
return sorted(set(l), key=l.index)
|
1055 |
+
|
1056 |
+
animagine_ps = to_list("anime artwork, anime style, vibrant, studio anime, highly detailed, masterpiece, best quality, very aesthetic, absurdres")
|
1057 |
+
animagine_nps = to_list("lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]")
|
1058 |
+
pony_ps = to_list("source_anime, score_9, score_8_up, score_7_up, masterpiece, best quality, very aesthetic, absurdres")
|
1059 |
+
pony_nps = to_list("source_pony, source_furry, source_cartoon, score_6, score_5, score_4, busty, ugly face, mutated hands, low res, blurry face, black and white, the simpsons, overwatch, apex legends")
|
1060 |
+
prompts = to_list(prompt)
|
1061 |
+
neg_prompts = to_list(neg_prompt)
|
1062 |
+
|
1063 |
+
all_styles_ps = []
|
1064 |
+
all_styles_nps = []
|
1065 |
+
for d in style_list:
|
1066 |
+
all_styles_ps.extend(to_list(str(d.get("prompt", ""))))
|
1067 |
+
all_styles_nps.extend(to_list(str(d.get("negative_prompt", ""))))
|
1068 |
+
|
1069 |
+
all_quality_ps = []
|
1070 |
+
all_quality_nps = []
|
1071 |
+
for d in quality_prompt_list:
|
1072 |
+
all_quality_ps.extend(to_list(str(d.get("prompt", ""))))
|
1073 |
+
all_quality_nps.extend(to_list(str(d.get("negative_prompt", ""))))
|
1074 |
+
|
1075 |
+
quality_ps = to_list(preset_quality[quality_key][0])
|
1076 |
+
quality_nps = to_list(preset_quality[quality_key][1])
|
1077 |
+
styles_ps = to_list(preset_styles[styles_key][0])
|
1078 |
+
styles_nps = to_list(preset_styles[styles_key][1])
|
1079 |
+
|
1080 |
+
prompts = list_sub(prompts, animagine_ps + pony_ps + all_styles_ps + all_quality_ps)
|
1081 |
+
neg_prompts = list_sub(neg_prompts, animagine_nps + pony_nps + all_styles_nps + all_quality_nps)
|
1082 |
+
|
1083 |
+
last_empty_p = [""] if not prompts and type != "None" and type != "Auto" and styles_key != "None" and quality_key != "None" else []
|
1084 |
+
last_empty_np = [""] if not neg_prompts and type != "None" and type != "Auto" and styles_key != "None" and quality_key != "None" else []
|
1085 |
+
|
1086 |
+
if type == "Animagine":
|
1087 |
+
prompts = prompts + animagine_ps
|
1088 |
+
neg_prompts = neg_prompts + animagine_nps
|
1089 |
+
elif type == "Pony":
|
1090 |
+
prompts = prompts + pony_ps
|
1091 |
+
neg_prompts = neg_prompts + pony_nps
|
1092 |
+
|
1093 |
+
prompts = prompts + styles_ps + quality_ps
|
1094 |
+
neg_prompts = neg_prompts + styles_nps + quality_nps
|
1095 |
+
|
1096 |
+
prompt = ", ".join(list_uniq(prompts) + last_empty_p)
|
1097 |
+
neg_prompt = ", ".join(list_uniq(neg_prompts) + last_empty_np)
|
1098 |
+
|
1099 |
+
return gr.update(value=prompt), gr.update(value=neg_prompt), gr.update(value=type)
|
1100 |
+
|
1101 |
+
|
1102 |
+
def set_quick_presets(genre:str = "None", type:str = "Auto", speed:str = "None", aspect:str = "None"):
|
1103 |
+
quality = "None"
|
1104 |
+
style = "None"
|
1105 |
+
sampler = "None"
|
1106 |
+
opt = "None"
|
1107 |
+
|
1108 |
+
if genre == "Anime":
|
1109 |
+
if type != "None" and type != "Auto": style = "Anime"
|
1110 |
+
if aspect == "1:1":
|
1111 |
+
if speed == "Heavy":
|
1112 |
+
sampler = "Anime 1:1 Heavy"
|
1113 |
+
elif speed == "Fast":
|
1114 |
+
sampler = "Anime 1:1 Fast"
|
1115 |
+
else:
|
1116 |
+
sampler = "Anime 1:1 Standard"
|
1117 |
+
elif aspect == "3:4":
|
1118 |
+
if speed == "Heavy":
|
1119 |
+
sampler = "Anime 3:4 Heavy"
|
1120 |
+
elif speed == "Fast":
|
1121 |
+
sampler = "Anime 3:4 Fast"
|
1122 |
+
else:
|
1123 |
+
sampler = "Anime 3:4 Standard"
|
1124 |
+
if type == "Pony":
|
1125 |
+
quality = "Pony Anime Common"
|
1126 |
+
elif type == "Animagine":
|
1127 |
+
quality = "Animagine Common"
|
1128 |
+
else:
|
1129 |
+
quality = "None"
|
1130 |
+
elif genre == "Photo":
|
1131 |
+
if type != "None" and type != "Auto": style = "Photographic"
|
1132 |
+
if aspect == "1:1":
|
1133 |
+
if speed == "Heavy":
|
1134 |
+
sampler = "Photo 1:1 Heavy"
|
1135 |
+
elif speed == "Fast":
|
1136 |
+
sampler = "Photo 1:1 Fast"
|
1137 |
+
else:
|
1138 |
+
sampler = "Photo 1:1 Standard"
|
1139 |
+
elif aspect == "3:4":
|
1140 |
+
if speed == "Heavy":
|
1141 |
+
sampler = "Photo 3:4 Heavy"
|
1142 |
+
elif speed == "Fast":
|
1143 |
+
sampler = "Photo 3:4 Fast"
|
1144 |
+
else:
|
1145 |
+
sampler = "Photo 3:4 Standard"
|
1146 |
+
if type == "Pony":
|
1147 |
+
quality = "Pony Common"
|
1148 |
+
else:
|
1149 |
+
quality = "None"
|
1150 |
+
|
1151 |
+
if speed == "Fast":
|
1152 |
+
opt = "DPO Turbo"
|
1153 |
+
if genre == "Anime" and type != "Pony" and type != "Auto": quality = "Animagine Light v3.1"
|
1154 |
+
|
1155 |
+
return gr.update(value=quality), gr.update(value=style), gr.update(value=sampler), gr.update(value=opt), gr.update(value=type)
|
1156 |
+
|
1157 |
+
|
1158 |
+
textual_inversion_dict = {}
|
1159 |
+
try:
|
1160 |
+
with open('textual_inversion_dict.json', encoding='utf-8') as f:
|
1161 |
+
textual_inversion_dict = json.load(f)
|
1162 |
+
except Exception:
|
1163 |
+
pass
|
1164 |
+
textual_inversion_file_token_list = []
|
1165 |
+
|
1166 |
+
|
1167 |
+
def get_tupled_embed_list(embed_list):
|
1168 |
+
global textual_inversion_file_list
|
1169 |
+
tupled_list = []
|
1170 |
+
for file in embed_list:
|
1171 |
+
token = textual_inversion_dict.get(Path(file).name, [Path(file).stem.replace(",",""), False])[0]
|
1172 |
+
tupled_list.append((token, file))
|
1173 |
+
textual_inversion_file_token_list.append(token)
|
1174 |
+
return tupled_list
|
1175 |
+
|
1176 |
+
|
1177 |
+
def set_textual_inversion_prompt(textual_inversion_gui, prompt_gui, neg_prompt_gui, prompt_syntax_gui):
|
1178 |
+
ti_tags = list(textual_inversion_dict.values()) + textual_inversion_file_token_list
|
1179 |
+
tags = prompt_gui.split(",") if prompt_gui else []
|
1180 |
+
prompts = []
|
1181 |
+
for tag in tags:
|
1182 |
+
tag = str(tag).strip()
|
1183 |
+
if tag and not tag in ti_tags:
|
1184 |
+
prompts.append(tag)
|
1185 |
+
ntags = neg_prompt_gui.split(",") if neg_prompt_gui else []
|
1186 |
+
neg_prompts = []
|
1187 |
+
for tag in ntags:
|
1188 |
+
tag = str(tag).strip()
|
1189 |
+
if tag and not tag in ti_tags:
|
1190 |
+
neg_prompts.append(tag)
|
1191 |
+
ti_prompts = []
|
1192 |
+
ti_neg_prompts = []
|
1193 |
+
for ti in textual_inversion_gui:
|
1194 |
+
tokens = textual_inversion_dict.get(Path(ti).name, [Path(ti).stem.replace(",",""), False])
|
1195 |
+
is_positive = tokens[1] == True or "positive" in Path(ti).parent.name
|
1196 |
+
if is_positive: # positive prompt
|
1197 |
+
ti_prompts.append(tokens[0])
|
1198 |
+
else: # negative prompt (default)
|
1199 |
+
ti_neg_prompts.append(tokens[0])
|
1200 |
+
empty = [""]
|
1201 |
+
prompt = ", ".join(prompts + ti_prompts + empty)
|
1202 |
+
neg_prompt = ", ".join(neg_prompts + ti_neg_prompts + empty)
|
1203 |
+
return gr.update(value=prompt), gr.update(value=neg_prompt),
|
1204 |
+
|
1205 |
+
|
1206 |
+
def get_model_pipeline(repo_id: str):
|
1207 |
+
from huggingface_hub import HfApi
|
1208 |
+
api = HfApi()
|
1209 |
+
default = "StableDiffusionPipeline"
|
1210 |
+
try:
|
1211 |
+
if " " in repo_id or not api.repo_exists(repo_id): return default
|
1212 |
+
model = api.model_info(repo_id=repo_id)
|
1213 |
+
except Exception as e:
|
1214 |
+
return default
|
1215 |
+
if model.private or model.gated: return default
|
1216 |
+
tags = model.tags
|
1217 |
+
if not 'diffusers' in tags: return default
|
1218 |
+
if 'diffusers:StableDiffusionXLPipeline' in tags:
|
1219 |
+
return "StableDiffusionXLPipeline"
|
1220 |
+
elif 'diffusers:StableDiffusionPipeline' in tags:
|
1221 |
+
return "StableDiffusionPipeline"
|
1222 |
+
else:
|
1223 |
+
return default
|
1224 |
+
|
packages.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
aria2 -y
|
pre-requirements.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
pip>=23.0.0
|
prompt.py
ADDED
@@ -0,0 +1,554 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import random
|
3 |
+
import json
|
4 |
+
import os
|
5 |
+
import re
|
6 |
+
from datetime import datetime
|
7 |
+
from huggingface_hub import InferenceClient
|
8 |
+
import subprocess
|
9 |
+
import torch
|
10 |
+
from PIL import Image
|
11 |
+
from transformers import AutoProcessor, AutoModelForCausalLM
|
12 |
+
import random
|
13 |
+
import spaces
|
14 |
+
|
15 |
+
subprocess.run('pip install flash-attn --no-build-isolation', env={'FLASH_ATTENTION_SKIP_CUDA_BUILD': "TRUE"}, shell=True)
|
16 |
+
|
17 |
+
# Initialize Florence model
|
18 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
19 |
+
florence_model = AutoModelForCausalLM.from_pretrained('gokaygokay/Florence-2-Flux', trust_remote_code=True).to("cpu").eval()
|
20 |
+
florence_processor = AutoProcessor.from_pretrained('gokaygokay/Florence-2-Flux', trust_remote_code=True)
|
21 |
+
|
22 |
+
# Florence caption function
|
23 |
+
@spaces.GPU(duration=30)
|
24 |
+
def florence_caption(image):
|
25 |
+
if not isinstance(image, Image.Image):
|
26 |
+
image = Image.fromarray(image)
|
27 |
+
|
28 |
+
florence_model.to(device=device)
|
29 |
+
inputs = florence_processor(text="<MORE_DETAILED_CAPTION>", images=image, return_tensors="pt").to(device)
|
30 |
+
generated_ids = florence_model.generate(
|
31 |
+
input_ids=inputs["input_ids"],
|
32 |
+
pixel_values=inputs["pixel_values"],
|
33 |
+
max_new_tokens=1024,
|
34 |
+
early_stopping=False,
|
35 |
+
do_sample=False,
|
36 |
+
num_beams=3,
|
37 |
+
)
|
38 |
+
florence_model.to("cpu")
|
39 |
+
generated_text = florence_processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
|
40 |
+
parsed_answer = florence_processor.post_process_generation(
|
41 |
+
generated_text,
|
42 |
+
task="<MORE_DETAILED_CAPTION>",
|
43 |
+
image_size=(image.width, image.height)
|
44 |
+
)
|
45 |
+
return parsed_answer["<MORE_DETAILED_CAPTION>"]
|
46 |
+
|
47 |
+
# Load JSON files
|
48 |
+
def load_json_file(file_name):
|
49 |
+
file_path = os.path.join("data", file_name)
|
50 |
+
with open(file_path, "r") as file:
|
51 |
+
return json.load(file)
|
52 |
+
|
53 |
+
ARTFORM = load_json_file("artform.json")
|
54 |
+
PHOTO_TYPE = load_json_file("photo_type.json")
|
55 |
+
BODY_TYPES = load_json_file("body_types.json")
|
56 |
+
DEFAULT_TAGS = load_json_file("default_tags.json")
|
57 |
+
ROLES = load_json_file("roles.json")
|
58 |
+
HAIRSTYLES = load_json_file("hairstyles.json")
|
59 |
+
ADDITIONAL_DETAILS = load_json_file("additional_details.json")
|
60 |
+
PHOTOGRAPHY_STYLES = load_json_file("photography_styles.json")
|
61 |
+
DEVICE = load_json_file("device.json")
|
62 |
+
PHOTOGRAPHER = load_json_file("photographer.json")
|
63 |
+
ARTIST = load_json_file("artist.json")
|
64 |
+
DIGITAL_ARTFORM = load_json_file("digital_artform.json")
|
65 |
+
PLACE = load_json_file("place.json")
|
66 |
+
LIGHTING = load_json_file("lighting.json")
|
67 |
+
CLOTHING = load_json_file("clothing.json")
|
68 |
+
COMPOSITION = load_json_file("composition.json")
|
69 |
+
POSE = load_json_file("pose.json")
|
70 |
+
BACKGROUND = load_json_file("background.json")
|
71 |
+
|
72 |
+
class PromptGenerator:
|
73 |
+
def __init__(self, seed=None):
|
74 |
+
self.rng = random.Random(seed)
|
75 |
+
|
76 |
+
def split_and_choose(self, input_str):
|
77 |
+
choices = [choice.strip() for choice in input_str.split(",")]
|
78 |
+
return self.rng.choices(choices, k=1)[0]
|
79 |
+
|
80 |
+
def get_choice(self, input_str, default_choices):
|
81 |
+
if input_str.lower() == "disabled":
|
82 |
+
return ""
|
83 |
+
elif "," in input_str:
|
84 |
+
return self.split_and_choose(input_str)
|
85 |
+
elif input_str.lower() == "random":
|
86 |
+
return self.rng.choices(default_choices, k=1)[0]
|
87 |
+
else:
|
88 |
+
return input_str
|
89 |
+
|
90 |
+
def clean_consecutive_commas(self, input_string):
|
91 |
+
cleaned_string = re.sub(r',\s*,', ',', input_string)
|
92 |
+
return cleaned_string
|
93 |
+
|
94 |
+
def process_string(self, replaced, seed):
|
95 |
+
replaced = re.sub(r'\s*,\s*', ',', replaced)
|
96 |
+
replaced = re.sub(r',+', ',', replaced)
|
97 |
+
original = replaced
|
98 |
+
|
99 |
+
first_break_clipl_index = replaced.find("BREAK_CLIPL")
|
100 |
+
second_break_clipl_index = replaced.find("BREAK_CLIPL", first_break_clipl_index + len("BREAK_CLIPL"))
|
101 |
+
|
102 |
+
if first_break_clipl_index != -1 and second_break_clipl_index != -1:
|
103 |
+
clip_content_l = replaced[first_break_clipl_index + len("BREAK_CLIPL"):second_break_clipl_index]
|
104 |
+
replaced = replaced[:first_break_clipl_index].strip(", ") + replaced[second_break_clipl_index + len("BREAK_CLIPL"):].strip(", ")
|
105 |
+
clip_l = clip_content_l
|
106 |
+
else:
|
107 |
+
clip_l = ""
|
108 |
+
|
109 |
+
first_break_clipg_index = replaced.find("BREAK_CLIPG")
|
110 |
+
second_break_clipg_index = replaced.find("BREAK_CLIPG", first_break_clipg_index + len("BREAK_CLIPG"))
|
111 |
+
|
112 |
+
if first_break_clipg_index != -1 and second_break_clipg_index != -1:
|
113 |
+
clip_content_g = replaced[first_break_clipg_index + len("BREAK_CLIPG"):second_break_clipg_index]
|
114 |
+
replaced = replaced[:first_break_clipg_index].strip(", ") + replaced[second_break_clipg_index + len("BREAK_CLIPG"):].strip(", ")
|
115 |
+
clip_g = clip_content_g
|
116 |
+
else:
|
117 |
+
clip_g = ""
|
118 |
+
|
119 |
+
t5xxl = replaced
|
120 |
+
|
121 |
+
original = original.replace("BREAK_CLIPL", "").replace("BREAK_CLIPG", "")
|
122 |
+
original = re.sub(r'\s*,\s*', ',', original)
|
123 |
+
original = re.sub(r',+', ',', original)
|
124 |
+
clip_l = re.sub(r'\s*,\s*', ',', clip_l)
|
125 |
+
clip_l = re.sub(r',+', ',', clip_l)
|
126 |
+
clip_g = re.sub(r'\s*,\s*', ',', clip_g)
|
127 |
+
clip_g = re.sub(r',+', ',', clip_g)
|
128 |
+
if clip_l.startswith(","):
|
129 |
+
clip_l = clip_l[1:]
|
130 |
+
if clip_g.startswith(","):
|
131 |
+
clip_g = clip_g[1:]
|
132 |
+
if original.startswith(","):
|
133 |
+
original = original[1:]
|
134 |
+
if t5xxl.startswith(","):
|
135 |
+
t5xxl = t5xxl[1:]
|
136 |
+
|
137 |
+
return original, seed, t5xxl, clip_l, clip_g
|
138 |
+
|
139 |
+
def generate_prompt(self, seed, custom, subject, artform, photo_type, body_types, default_tags, roles, hairstyles,
|
140 |
+
additional_details, photography_styles, device, photographer, artist, digital_artform,
|
141 |
+
place, lighting, clothing, composition, pose, background, input_image):
|
142 |
+
kwargs = locals()
|
143 |
+
del kwargs['self']
|
144 |
+
|
145 |
+
seed = kwargs.get("seed", 0)
|
146 |
+
if seed is not None:
|
147 |
+
self.rng = random.Random(seed)
|
148 |
+
components = []
|
149 |
+
custom = kwargs.get("custom", "")
|
150 |
+
if custom:
|
151 |
+
components.append(custom)
|
152 |
+
is_photographer = kwargs.get("artform", "").lower() == "photography" or (
|
153 |
+
kwargs.get("artform", "").lower() == "random"
|
154 |
+
and self.rng.choice([True, False])
|
155 |
+
)
|
156 |
+
|
157 |
+
subject = kwargs.get("subject", "")
|
158 |
+
|
159 |
+
if is_photographer:
|
160 |
+
selected_photo_style = self.get_choice(kwargs.get("photography_styles", ""), PHOTOGRAPHY_STYLES)
|
161 |
+
if not selected_photo_style:
|
162 |
+
selected_photo_style = "photography"
|
163 |
+
components.append(selected_photo_style)
|
164 |
+
if kwargs.get("photography_style", "") != "disabled" and kwargs.get("default_tags", "") != "disabled" or subject != "":
|
165 |
+
components.append(" of")
|
166 |
+
|
167 |
+
default_tags = kwargs.get("default_tags", "random")
|
168 |
+
body_type = kwargs.get("body_types", "")
|
169 |
+
if not subject:
|
170 |
+
if default_tags == "random":
|
171 |
+
if body_type != "disabled" and body_type != "random":
|
172 |
+
selected_subject = self.get_choice(kwargs.get("default_tags", ""), DEFAULT_TAGS).replace("a ", "").replace("an ", "")
|
173 |
+
components.append("a ")
|
174 |
+
components.append(body_type)
|
175 |
+
components.append(selected_subject)
|
176 |
+
elif body_type == "disabled":
|
177 |
+
selected_subject = self.get_choice(kwargs.get("default_tags", ""), DEFAULT_TAGS)
|
178 |
+
components.append(selected_subject)
|
179 |
+
else:
|
180 |
+
body_type = self.get_choice(body_type, BODY_TYPES)
|
181 |
+
components.append("a ")
|
182 |
+
components.append(body_type)
|
183 |
+
selected_subject = self.get_choice(kwargs.get("default_tags", ""), DEFAULT_TAGS).replace("a ", "").replace("an ", "")
|
184 |
+
components.append(selected_subject)
|
185 |
+
elif default_tags == "disabled":
|
186 |
+
pass
|
187 |
+
else:
|
188 |
+
components.append(default_tags)
|
189 |
+
else:
|
190 |
+
if body_type != "disabled" and body_type != "random":
|
191 |
+
components.append("a ")
|
192 |
+
components.append(body_type)
|
193 |
+
elif body_type == "disabled":
|
194 |
+
pass
|
195 |
+
else:
|
196 |
+
body_type = self.get_choice(body_type, BODY_TYPES)
|
197 |
+
components.append("a ")
|
198 |
+
components.append(body_type)
|
199 |
+
components.append(subject)
|
200 |
+
|
201 |
+
params = [
|
202 |
+
("roles", ROLES),
|
203 |
+
("hairstyles", HAIRSTYLES),
|
204 |
+
("additional_details", ADDITIONAL_DETAILS),
|
205 |
+
]
|
206 |
+
for param in params:
|
207 |
+
components.append(self.get_choice(kwargs.get(param[0], ""), param[1]))
|
208 |
+
for i in reversed(range(len(components))):
|
209 |
+
if components[i] in PLACE:
|
210 |
+
components[i] += ","
|
211 |
+
break
|
212 |
+
if kwargs.get("clothing", "") != "disabled" and kwargs.get("clothing", "") != "random":
|
213 |
+
components.append(", dressed in ")
|
214 |
+
clothing = kwargs.get("clothing", "")
|
215 |
+
components.append(clothing)
|
216 |
+
elif kwargs.get("clothing", "") == "random":
|
217 |
+
components.append(", dressed in ")
|
218 |
+
clothing = self.get_choice(kwargs.get("clothing", ""), CLOTHING)
|
219 |
+
components.append(clothing)
|
220 |
+
|
221 |
+
if kwargs.get("composition", "") != "disabled" and kwargs.get("composition", "") != "random":
|
222 |
+
components.append(",")
|
223 |
+
composition = kwargs.get("composition", "")
|
224 |
+
components.append(composition)
|
225 |
+
elif kwargs.get("composition", "") == "random":
|
226 |
+
components.append(",")
|
227 |
+
composition = self.get_choice(kwargs.get("composition", ""), COMPOSITION)
|
228 |
+
components.append(composition)
|
229 |
+
|
230 |
+
if kwargs.get("pose", "") != "disabled" and kwargs.get("pose", "") != "random":
|
231 |
+
components.append(",")
|
232 |
+
pose = kwargs.get("pose", "")
|
233 |
+
components.append(pose)
|
234 |
+
elif kwargs.get("pose", "") == "random":
|
235 |
+
components.append(",")
|
236 |
+
pose = self.get_choice(kwargs.get("pose", ""), POSE)
|
237 |
+
components.append(pose)
|
238 |
+
components.append("BREAK_CLIPG")
|
239 |
+
if kwargs.get("background", "") != "disabled" and kwargs.get("background", "") != "random":
|
240 |
+
components.append(",")
|
241 |
+
background = kwargs.get("background", "")
|
242 |
+
components.append(background)
|
243 |
+
elif kwargs.get("background", "") == "random":
|
244 |
+
components.append(",")
|
245 |
+
background = self.get_choice(kwargs.get("background", ""), BACKGROUND)
|
246 |
+
components.append(background)
|
247 |
+
|
248 |
+
if kwargs.get("place", "") != "disabled" and kwargs.get("place", "") != "random":
|
249 |
+
components.append(",")
|
250 |
+
place = kwargs.get("place", "")
|
251 |
+
components.append(place)
|
252 |
+
elif kwargs.get("place", "") == "random":
|
253 |
+
components.append(",")
|
254 |
+
place = self.get_choice(kwargs.get("place", ""), PLACE)
|
255 |
+
components.append(place + ",")
|
256 |
+
|
257 |
+
lighting = kwargs.get("lighting", "").lower()
|
258 |
+
if lighting == "random":
|
259 |
+
selected_lighting = ", ".join(self.rng.sample(LIGHTING, self.rng.randint(2, 5)))
|
260 |
+
components.append(",")
|
261 |
+
components.append(selected_lighting)
|
262 |
+
elif lighting == "disabled":
|
263 |
+
pass
|
264 |
+
else:
|
265 |
+
components.append(", ")
|
266 |
+
components.append(lighting)
|
267 |
+
components.append("BREAK_CLIPG")
|
268 |
+
components.append("BREAK_CLIPL")
|
269 |
+
if is_photographer:
|
270 |
+
if kwargs.get("photo_type", "") != "disabled":
|
271 |
+
photo_type_choice = self.get_choice(kwargs.get("photo_type", ""), PHOTO_TYPE)
|
272 |
+
if photo_type_choice and photo_type_choice != "random" and photo_type_choice != "disabled":
|
273 |
+
random_value = round(self.rng.uniform(1.1, 1.5), 1)
|
274 |
+
components.append(f", ({photo_type_choice}:{random_value}), ")
|
275 |
+
|
276 |
+
params = [
|
277 |
+
("device", DEVICE),
|
278 |
+
("photographer", PHOTOGRAPHER),
|
279 |
+
]
|
280 |
+
components.extend([self.get_choice(kwargs.get(param[0], ""), param[1]) for param in params])
|
281 |
+
if kwargs.get("device", "") != "disabled":
|
282 |
+
components[-2] = f", shot on {components[-2]}"
|
283 |
+
if kwargs.get("photographer", "") != "disabled":
|
284 |
+
components[-1] = f", photo by {components[-1]}"
|
285 |
+
else:
|
286 |
+
digital_artform_choice = self.get_choice(kwargs.get("digital_artform", ""), DIGITAL_ARTFORM)
|
287 |
+
if digital_artform_choice:
|
288 |
+
components.append(f"{digital_artform_choice}")
|
289 |
+
if kwargs.get("artist", "") != "disabled":
|
290 |
+
components.append(f"by {self.get_choice(kwargs.get('artist', ''), ARTIST)}")
|
291 |
+
components.append("BREAK_CLIPL")
|
292 |
+
|
293 |
+
prompt = " ".join(components)
|
294 |
+
prompt = re.sub(" +", " ", prompt)
|
295 |
+
replaced = prompt.replace("of as", "of")
|
296 |
+
replaced = self.clean_consecutive_commas(replaced)
|
297 |
+
|
298 |
+
return self.process_string(replaced, seed)
|
299 |
+
|
300 |
+
def add_caption_to_prompt(self, prompt, caption):
|
301 |
+
if caption:
|
302 |
+
return f"{prompt}, {caption}"
|
303 |
+
return prompt
|
304 |
+
|
305 |
+
class HuggingFaceInferenceNode:
|
306 |
+
def __init__(self):
|
307 |
+
self.clients = {
|
308 |
+
"Mixtral": InferenceClient("NousResearch/Nous-Hermes-2-Mixtral-8x7B-DPO"),
|
309 |
+
"Mistral": InferenceClient("mistralai/Mistral-7B-Instruct-v0.3"),
|
310 |
+
"Llama 3": InferenceClient("meta-llama/Meta-Llama-3-8B-Instruct"),
|
311 |
+
"Mistral-Nemo": InferenceClient("mistralai/Mistral-Nemo-Instruct-2407")
|
312 |
+
}
|
313 |
+
self.prompts_dir = "./prompts"
|
314 |
+
os.makedirs(self.prompts_dir, exist_ok=True)
|
315 |
+
|
316 |
+
def save_prompt(self, prompt):
|
317 |
+
filename_text = "hf_" + prompt.split(',')[0].strip()
|
318 |
+
filename_text = re.sub(r'[^\w\-_\. ]', '_', filename_text)
|
319 |
+
filename_text = filename_text[:30]
|
320 |
+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
321 |
+
base_filename = f"{filename_text}_{timestamp}.txt"
|
322 |
+
filename = os.path.join(self.prompts_dir, base_filename)
|
323 |
+
|
324 |
+
with open(filename, "w") as file:
|
325 |
+
file.write(prompt)
|
326 |
+
|
327 |
+
print(f"Prompt saved to {filename}")
|
328 |
+
|
329 |
+
def generate(self, model, input_text, happy_talk, compress, compression_level, poster, custom_base_prompt=""):
|
330 |
+
try:
|
331 |
+
client = self.clients[model]
|
332 |
+
|
333 |
+
default_happy_prompt = """Create a detailed visually descriptive caption of this description, which will be used as a prompt for a text to image AI system (caption only, no instructions like "create an image").Remove any mention of digital artwork or artwork style. Give detailed visual descriptions of the character(s), including ethnicity, skin tone, expression etc. Imagine using keywords for a still for someone who has aphantasia. Describe the image style, e.g. any photographic or art styles / techniques utilized. Make sure to fully describe all aspects of the cinematography, with abundant technical details and visual descriptions. If there is more than one image, combine the elements and characters from all of the images creatively into a single cohesive composition with a single background, inventing an interaction between the characters. Be creative in combining the characters into a single cohesive scene. Focus on two primary characters (or one) and describe an interesting interaction between them, such as a hug, a kiss, a fight, giving an object, an emotional reaction / interaction. If there is more than one background in the images, pick the most appropriate one. Your output is only the caption itself, no comments or extra formatting. The caption is in a single long paragraph. If you feel the images are inappropriate, invent a new scene / characters inspired by these. Additionally, incorporate a specific movie director's visual style and describe the lighting setup in detail, including the type, color, and placement of light sources to create the desired mood and atmosphere. Always frame the scene, including details about the film grain, color grading, and any artifacts or characteristics specific."""
|
334 |
+
|
335 |
+
default_simple_prompt = """Create a brief, straightforward caption for this description, suitable for a text-to-image AI system. Focus on the main elements, key characters, and overall scene without elaborate details. Provide a clear and concise description in one or two sentences."""
|
336 |
+
|
337 |
+
poster_prompt = """Analyze the provided description and extract key information to create a movie poster style description. Format the output as follows:
|
338 |
+
Title: A catchy, intriguing title that captures the essence of the scene, place the title in "".
|
339 |
+
Main character: Give a description of the main character.
|
340 |
+
Background: Describe the background in detail.
|
341 |
+
Supporting characters: Describe the supporting characters
|
342 |
+
Branding type: Describe the branding type
|
343 |
+
Tagline: Include a tagline that captures the essence of the movie.
|
344 |
+
Visual style: Ensure that the visual style fits the branding type and tagline.
|
345 |
+
You are allowed to make up film and branding names, and do them like 80's, 90's or modern movie posters."""
|
346 |
+
|
347 |
+
if poster:
|
348 |
+
base_prompt = poster_prompt
|
349 |
+
elif custom_base_prompt.strip():
|
350 |
+
base_prompt = custom_base_prompt
|
351 |
+
else:
|
352 |
+
base_prompt = default_happy_prompt if happy_talk else default_simple_prompt
|
353 |
+
|
354 |
+
if compress and not poster:
|
355 |
+
compression_chars = {
|
356 |
+
"soft": 600 if happy_talk else 300,
|
357 |
+
"medium": 400 if happy_talk else 200,
|
358 |
+
"hard": 200 if happy_talk else 100
|
359 |
+
}
|
360 |
+
char_limit = compression_chars[compression_level]
|
361 |
+
base_prompt += f" Compress the output to be concise while retaining key visual details. MAX OUTPUT SIZE no more than {char_limit} characters."
|
362 |
+
|
363 |
+
messages = f"<|im_start|>system\nYou are a helpful assistant. Try your best to give best response possible to user.<|im_end|>"
|
364 |
+
messages += f"\n<|im_start|>user\n{base_prompt}\nDescription: {input_text}<|im_end|>\n<|im_start|>assistant\n"
|
365 |
+
|
366 |
+
stream = client.text_generation(messages, max_new_tokens=4000, do_sample=True, stream=True, details=True, return_full_text=False)
|
367 |
+
output = ""
|
368 |
+
for response in stream:
|
369 |
+
if not response.token.text == "<|im_end|>":
|
370 |
+
output += response.token.text
|
371 |
+
|
372 |
+
# Remove specific tokens based on the model
|
373 |
+
if model == "Llama 3":
|
374 |
+
output = output.rstrip("<|eot_id|>")
|
375 |
+
elif model == "Mistral":
|
376 |
+
output = output.rstrip("</s>")
|
377 |
+
elif model == "Mistral-Nemo":
|
378 |
+
output = output.rstrip("<|im_end|></s>")
|
379 |
+
|
380 |
+
# Clean up the output
|
381 |
+
if ": " in output:
|
382 |
+
output = output.split(": ", 1)[1].strip()
|
383 |
+
elif output.lower().startswith("here"):
|
384 |
+
sentences = output.split(". ")
|
385 |
+
if len(sentences) > 1:
|
386 |
+
output = ". ".join(sentences[1:]).strip()
|
387 |
+
|
388 |
+
return output
|
389 |
+
|
390 |
+
except Exception as e:
|
391 |
+
print(f"An error occurred: {e}")
|
392 |
+
return f"Error occurred while processing the request: {str(e)}"
|
393 |
+
|
394 |
+
pg_title = """<h1 align="center">FLUX Prompt Generator</h1>
|
395 |
+
<p><center>
|
396 |
+
<a href="https://x.com/gokayfem" target="_blank">[X gokaygokay]</a>
|
397 |
+
<a href="https://github.com/gokayfem" target="_blank">[Github gokayfem]</a>
|
398 |
+
<a href="https://github.com/dagthomas/comfyui_dagthomas" target="_blank">[comfyui_dagthomas]</a>
|
399 |
+
<p align="center">Create long prompts from images or simple words. Enhance your short prompts with prompt enhancer.</p>
|
400 |
+
</center></p>
|
401 |
+
"""
|
402 |
+
|
403 |
+
def create_interface():
|
404 |
+
prompt_generator = PromptGenerator()
|
405 |
+
huggingface_node = HuggingFaceInferenceNode()
|
406 |
+
|
407 |
+
with gr.Blocks(theme='bethecloud/storj_theme') as demo:
|
408 |
+
|
409 |
+
gr.HTML(pg_title)
|
410 |
+
|
411 |
+
with gr.Row():
|
412 |
+
with gr.Column(scale=2):
|
413 |
+
with gr.Accordion("Basic Settings"):
|
414 |
+
pg_seed = gr.Slider(0, 30000, label='Seed', step=1, value=random.randint(0,30000))
|
415 |
+
pg_custom = gr.Textbox(label="Custom Input Prompt (optional)")
|
416 |
+
pg_subject = gr.Textbox(label="Subject (optional)")
|
417 |
+
|
418 |
+
# Add the radio button for global option selection
|
419 |
+
pg_global_option = gr.Radio(
|
420 |
+
["Disabled", "Random", "No Figure Rand"],
|
421 |
+
label="Set all options to:",
|
422 |
+
value="Disabled"
|
423 |
+
)
|
424 |
+
|
425 |
+
with gr.Accordion("Artform and Photo Type", open=False):
|
426 |
+
pg_artform = gr.Dropdown(["disabled", "random"] + ARTFORM, label="Artform", value="disabled")
|
427 |
+
pg_photo_type = gr.Dropdown(["disabled", "random"] + PHOTO_TYPE, label="Photo Type", value="disabled")
|
428 |
+
|
429 |
+
with gr.Accordion("Character Details", open=False):
|
430 |
+
pg_body_types = gr.Dropdown(["disabled", "random"] + BODY_TYPES, label="Body Types", value="disabled")
|
431 |
+
pg_default_tags = gr.Dropdown(["disabled", "random"] + DEFAULT_TAGS, label="Default Tags", value="disabled")
|
432 |
+
pg_roles = gr.Dropdown(["disabled", "random"] + ROLES, label="Roles", value="disabled")
|
433 |
+
pg_hairstyles = gr.Dropdown(["disabled", "random"] + HAIRSTYLES, label="Hairstyles", value="disabled")
|
434 |
+
pg_clothing = gr.Dropdown(["disabled", "random"] + CLOTHING, label="Clothing", value="disabled")
|
435 |
+
|
436 |
+
with gr.Accordion("Scene Details", open=False):
|
437 |
+
pg_place = gr.Dropdown(["disabled", "random"] + PLACE, label="Place", value="disabled")
|
438 |
+
pg_lighting = gr.Dropdown(["disabled", "random"] + LIGHTING, label="Lighting", value="disabled")
|
439 |
+
pg_composition = gr.Dropdown(["disabled", "random"] + COMPOSITION, label="Composition", value="disabled")
|
440 |
+
pg_pose = gr.Dropdown(["disabled", "random"] + POSE, label="Pose", value="disabled")
|
441 |
+
pg_background = gr.Dropdown(["disabled", "random"] + BACKGROUND, label="Background", value="disabled")
|
442 |
+
|
443 |
+
with gr.Accordion("Style and Artist", open=False):
|
444 |
+
pg_additional_details = gr.Dropdown(["disabled", "random"] + ADDITIONAL_DETAILS, label="Additional Details", value="disabled")
|
445 |
+
pg_photography_styles = gr.Dropdown(["disabled", "random"] + PHOTOGRAPHY_STYLES, label="Photography Styles", value="disabled")
|
446 |
+
pg_device = gr.Dropdown(["disabled", "random"] + DEVICE, label="Device", value="disabled")
|
447 |
+
pg_photographer = gr.Dropdown(["disabled", "random"] + PHOTOGRAPHER, label="Photographer", value="disabled")
|
448 |
+
pg_artist = gr.Dropdown(["disabled", "random"] + ARTIST, label="Artist", value="disabled")
|
449 |
+
pg_digital_artform = gr.Dropdown(["disabled", "random"] + DIGITAL_ARTFORM, label="Digital Artform", value="disabled")
|
450 |
+
|
451 |
+
pg_generate_button = gr.Button("Generate Prompt")
|
452 |
+
|
453 |
+
with gr.Column(scale=2):
|
454 |
+
with gr.Accordion("Image and Caption", open=False):
|
455 |
+
pg_input_image = gr.Image(label="Input Image (optional)")
|
456 |
+
pg_caption_output = gr.Textbox(label="Generated Caption", lines=3)
|
457 |
+
pg_create_caption_button = gr.Button("Create Caption")
|
458 |
+
pg_add_caption_button = gr.Button("Add Caption to Prompt")
|
459 |
+
|
460 |
+
with gr.Accordion("Prompt Generation", open=True):
|
461 |
+
pg_output = gr.Textbox(label="Generated Prompt / Input Text", lines=4)
|
462 |
+
pg_t5xxl_output = gr.Textbox(label="T5XXL Output", visible=True)
|
463 |
+
pg_clip_l_output = gr.Textbox(label="CLIP L Output", visible=True)
|
464 |
+
pg_clip_g_output = gr.Textbox(label="CLIP G Output", visible=True)
|
465 |
+
|
466 |
+
with gr.Column(scale=2):
|
467 |
+
with gr.Accordion("Prompt Generation with LLM", open=False):
|
468 |
+
pg_model = gr.Dropdown(["Mixtral", "Mistral", "Llama 3", "Mistral-Nemo"], label="Model", value="Llama 3")
|
469 |
+
pg_happy_talk = gr.Checkbox(label="Happy Talk", value=True)
|
470 |
+
pg_compress = gr.Checkbox(label="Compress", value=True)
|
471 |
+
pg_compression_level = gr.Radio(["soft", "medium", "hard"], label="Compression Level", value="hard")
|
472 |
+
pg_poster = gr.Checkbox(label="Poster", value=False)
|
473 |
+
pg_custom_base_prompt = gr.Textbox(label="Custom Base Prompt", lines=5)
|
474 |
+
pg_generate_text_button = gr.Button("Generate Prompt with LLM")
|
475 |
+
pg_text_output = gr.Textbox(label="Generated Text", lines=10)
|
476 |
+
|
477 |
+
def create_caption(image):
|
478 |
+
if image is not None:
|
479 |
+
return florence_caption(image)
|
480 |
+
return ""
|
481 |
+
|
482 |
+
pg_create_caption_button.click(
|
483 |
+
create_caption,
|
484 |
+
inputs=[pg_input_image],
|
485 |
+
outputs=[pg_caption_output]
|
486 |
+
)
|
487 |
+
|
488 |
+
pg_generate_button.click(
|
489 |
+
prompt_generator.generate_prompt,
|
490 |
+
inputs=[pg_seed, pg_custom, pg_subject, pg_artform, pg_photo_type, pg_body_types,
|
491 |
+
pg_default_tags, pg_roles, pg_hairstyles,
|
492 |
+
pg_additional_details, pg_photography_styles, pg_device, pg_photographer,
|
493 |
+
pg_artist, pg_digital_artform,
|
494 |
+
pg_place, pg_lighting, pg_clothing, pg_composition, pg_pose, pg_background],
|
495 |
+
outputs=[pg_output, gr.Number(visible=False), pg_t5xxl_output, pg_clip_l_output, pg_clip_g_output]
|
496 |
+
)
|
497 |
+
|
498 |
+
pg_add_caption_button.click(
|
499 |
+
prompt_generator.add_caption_to_prompt,
|
500 |
+
inputs=[pg_output, pg_caption_output],
|
501 |
+
outputs=[pg_output]
|
502 |
+
)
|
503 |
+
|
504 |
+
pg_generate_text_button.click(
|
505 |
+
huggingface_node.generate,
|
506 |
+
inputs=[pg_model, pg_output, pg_happy_talk, pg_compress, pg_compression_level,
|
507 |
+
pg_poster, pg_custom_base_prompt],
|
508 |
+
outputs=pg_text_output
|
509 |
+
)
|
510 |
+
|
511 |
+
def update_all_options(choice):
|
512 |
+
updates = {}
|
513 |
+
if choice == "Disabled":
|
514 |
+
for dropdown in [
|
515 |
+
pg_artform, pg_photo_type, pg_body_types, pg_default_tags,
|
516 |
+
pg_roles, pg_hairstyles, pg_clothing,
|
517 |
+
pg_place, pg_lighting, pg_composition, pg_pose, pg_background, pg_additional_details,
|
518 |
+
pg_photography_styles, pg_device, pg_photographer, pg_artist, pg_digital_artform
|
519 |
+
]:
|
520 |
+
updates[dropdown] = gr.update(value="disabled")
|
521 |
+
elif choice == "Random":
|
522 |
+
for dropdown in [
|
523 |
+
pg_artform, pg_photo_type, pg_body_types, pg_default_tags,
|
524 |
+
pg_roles, pg_hairstyles, pg_clothing,
|
525 |
+
pg_place, pg_lighting, pg_composition, pg_pose, pg_background, pg_additional_details,
|
526 |
+
pg_photography_styles, pg_device, pg_photographer, pg_artist, pg_digital_artform
|
527 |
+
]:
|
528 |
+
updates[dropdown] = gr.update(value="random")
|
529 |
+
else: # No Figure Random
|
530 |
+
for dropdown in [pg_photo_type, pg_body_types, pg_default_tags,
|
531 |
+
pg_roles, pg_hairstyles, pg_clothing, pg_pose, pg_additional_details]:
|
532 |
+
updates[dropdown] = gr.update(value="disabled")
|
533 |
+
for dropdown in [pg_artform, pg_place, pg_lighting, pg_composition,
|
534 |
+
pg_background, pg_photography_styles, pg_device, pg_photographer,
|
535 |
+
pg_artist, pg_digital_artform]:
|
536 |
+
updates[dropdown] = gr.update(value="random")
|
537 |
+
return updates
|
538 |
+
|
539 |
+
pg_global_option.change(
|
540 |
+
update_all_options,
|
541 |
+
inputs=[pg_global_option],
|
542 |
+
outputs=[
|
543 |
+
pg_artform, pg_photo_type, pg_body_types, pg_default_tags,
|
544 |
+
pg_roles, pg_hairstyles, pg_clothing,
|
545 |
+
pg_place, pg_lighting, pg_composition, pg_pose, pg_background, pg_additional_details,
|
546 |
+
pg_photography_styles, pg_device, pg_photographer, pg_artist, pg_digital_artform
|
547 |
+
]
|
548 |
+
)
|
549 |
+
|
550 |
+
return demo
|
551 |
+
|
552 |
+
if __name__ == "__main__":
|
553 |
+
demo = create_interface()
|
554 |
+
demo.launch()
|
prompts/A close-up movie still of a young woman with a mix.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
A close-up movie still of a young woman with a mix of determination and awe in her teary eyes, adorned in a worn metallic helmet with steampunk goggles dripping with water. Her olive skin is sprinkled with freckles and raindrops, and her expression is intense yet serene. Around her neck hangs a mysterious pendant, intricately crafted with metal filigree encasing a crystal sphere, reflecting a forest and amber hues of a twilight sky. The scene, bathed in soft blue and golden sunlight, features impeccable film grain and sharp focus elements, a merger of gritty realism with mystical allure.
|
prompts/A surreal movie still featuring a vibrant green tr.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
A surreal movie still featuring a vibrant green tree frog clinging to a leaf, adorned with glistening dew drops under dramatic diffused lighting. In the backdrop, a mystical woman with tan skin gazes towards an ethereal, fiery eclipse. Her long dark hair flows against a deep blue gown sparkling with starlit patterns. The scene merges dreamy aquatic and cosmic elements in a hyper-detailed, fantasy setting. The lighting is a soft bioluminescence contrasted by intense, fiery hues of the eclipse, captured with vivid, high-resolution imagery and a subtle film grain.
|
prompts/prompt_20240804_001736.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
A lone figure in a dark cloak stands solemnly in a vast, muddy field, staring at enormous, floating, mechanical octopus-like creatures with glowing yellow eyes. Nearby, a green tractor is half-submerged in mud. Blurred, misty grey clouds loom overhead, casting a dreary atmosphere. In the distance, a massive, ethereal tree with swirling branches glows brilliantly against a vibrant, magical sky filled with hues of purple, pink, and turquoise. The contrasting elements of muddy realism and fantastical colors create a surreal composition, capturing a moment of awe and mystery in a hyper-detailed movie still. The image has film grain and analog characteristics, with a low saturation for the muddy field and high saturation for the vibrant sky.
|
requirements.txt
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
-
torch
|
2 |
-
git+https://github.com/huggingface/diffusers
|
3 |
-
spaces
|
4 |
-
transformers
|
5 |
-
peft
|
6 |
-
sentencepiece
|
|
|
|
1 |
+
torch
|
2 |
+
git+https://github.com/huggingface/diffusers
|
3 |
+
spaces
|
4 |
+
transformers
|
5 |
+
peft
|
6 |
+
sentencepiece
|
7 |
+
timm
|
tagger/character_series_dict.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
tagger/danbooru_e621.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
tagger/fl2cog.py
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import AutoProcessor, AutoModelForCausalLM
|
2 |
+
import spaces
|
3 |
+
from PIL import Image
|
4 |
+
import torch
|
5 |
+
import re
|
6 |
+
import numpy as np
|
7 |
+
|
8 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
9 |
+
|
10 |
+
import subprocess
|
11 |
+
subprocess.run('pip install flash-attn --no-build-isolation', env={'FLASH_ATTENTION_SKIP_CUDA_BUILD': "TRUE"}, shell=True)
|
12 |
+
|
13 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
14 |
+
fl_model = AutoModelForCausalLM.from_pretrained('thwri/CogFlorence-2.1-Large', trust_remote_code=True).eval().to("cpu").eval()
|
15 |
+
fl_processor = AutoProcessor.from_pretrained('thwri/CogFlorence-2.1-Large', trust_remote_code=True)
|
16 |
+
|
17 |
+
def modify_caption(caption: str) -> str:
|
18 |
+
special_patterns = [
|
19 |
+
(r'the image is ', ''),
|
20 |
+
(r'the image captures ', ''),
|
21 |
+
(r'the image showcases ', ''),
|
22 |
+
(r'the image shows ', ''),
|
23 |
+
(r'the image ', ''),
|
24 |
+
]
|
25 |
+
|
26 |
+
for pattern, replacement in special_patterns:
|
27 |
+
caption = re.sub(pattern, replacement, caption, flags=re.IGNORECASE)
|
28 |
+
|
29 |
+
caption = caption.replace('\n', '').replace('\r', '')
|
30 |
+
caption = re.sub(r'(?<=[.,?!])(?=[^\s])', r' ', caption)
|
31 |
+
caption = ' '.join(caption.strip().splitlines())
|
32 |
+
|
33 |
+
return caption
|
34 |
+
|
35 |
+
@spaces.GPU(duration=30)
|
36 |
+
def process_image(image):
|
37 |
+
if isinstance(image, np.ndarray):
|
38 |
+
image = Image.fromarray(image)
|
39 |
+
elif isinstance(image, str):
|
40 |
+
image = Image.open(image)
|
41 |
+
if image.mode != "RGB":
|
42 |
+
image = image.convert("RGB")
|
43 |
+
|
44 |
+
prompt = "<MORE_DETAILED_CAPTION>"
|
45 |
+
|
46 |
+
fl_model.to(device)
|
47 |
+
inputs = fl_processor(text=prompt, images=image, return_tensors="pt").to(device)
|
48 |
+
generated_ids = fl_model.generate(
|
49 |
+
input_ids=inputs["input_ids"],
|
50 |
+
pixel_values=inputs["pixel_values"],
|
51 |
+
max_new_tokens=1024,
|
52 |
+
num_beams=3,
|
53 |
+
do_sample=True
|
54 |
+
)
|
55 |
+
fl_model.to("cpu")
|
56 |
+
generated_text = fl_processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
|
57 |
+
parsed_answer = fl_processor.post_process_generation(generated_text, task=prompt, image_size=(image.width, image.height))
|
58 |
+
return modify_caption(parsed_answer["<MORE_DETAILED_CAPTION>"])
|
59 |
+
|
60 |
+
def predict_tags_fl2_cog(image: Image.Image, input_tags: str, algo: list[str]):
|
61 |
+
def to_list(s):
|
62 |
+
return [x.strip() for x in s.split(",") if not s == ""]
|
63 |
+
|
64 |
+
def list_uniq(l):
|
65 |
+
return sorted(set(l), key=l.index)
|
66 |
+
|
67 |
+
if not "Use CogFlorence-2.1-Large" in algo:
|
68 |
+
return input_tags
|
69 |
+
tag_list = list_uniq(to_list(input_tags) + to_list(process_image(image) + ", "))
|
70 |
+
tag_list.remove("")
|
71 |
+
return ", ".join(tag_list)
|
tagger/fl2flux.py
ADDED
@@ -0,0 +1,79 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from transformers import AutoProcessor, AutoModelForCausalLM
|
2 |
+
import spaces
|
3 |
+
import re
|
4 |
+
from PIL import Image
|
5 |
+
import torch
|
6 |
+
|
7 |
+
import subprocess
|
8 |
+
subprocess.run('pip install flash-attn --no-build-isolation', env={'FLASH_ATTENTION_SKIP_CUDA_BUILD': "TRUE"}, shell=True)
|
9 |
+
|
10 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
11 |
+
fl_model = AutoModelForCausalLM.from_pretrained('gokaygokay/Florence-2-Flux', trust_remote_code=True).to("cpu").eval()
|
12 |
+
fl_processor = AutoProcessor.from_pretrained('gokaygokay/Florence-2-Flux', trust_remote_code=True)
|
13 |
+
|
14 |
+
|
15 |
+
def fl_modify_caption(caption: str) -> str:
|
16 |
+
"""
|
17 |
+
Removes specific prefixes from captions if present, otherwise returns the original caption.
|
18 |
+
Args:
|
19 |
+
caption (str): A string containing a caption.
|
20 |
+
Returns:
|
21 |
+
str: The caption with the prefix removed if it was present, or the original caption.
|
22 |
+
"""
|
23 |
+
# Define the prefixes to remove
|
24 |
+
prefix_substrings = [
|
25 |
+
('captured from ', ''),
|
26 |
+
('captured at ', '')
|
27 |
+
]
|
28 |
+
|
29 |
+
# Create a regex pattern to match any of the prefixes
|
30 |
+
pattern = '|'.join([re.escape(opening) for opening, _ in prefix_substrings])
|
31 |
+
replacers = {opening.lower(): replacer for opening, replacer in prefix_substrings}
|
32 |
+
|
33 |
+
# Function to replace matched prefix with its corresponding replacement
|
34 |
+
def replace_fn(match):
|
35 |
+
return replacers[match.group(0).lower()]
|
36 |
+
|
37 |
+
# Apply the regex to the caption
|
38 |
+
modified_caption = re.sub(pattern, replace_fn, caption, count=1, flags=re.IGNORECASE)
|
39 |
+
|
40 |
+
# If the caption was modified, return the modified version; otherwise, return the original
|
41 |
+
return modified_caption if modified_caption != caption else caption
|
42 |
+
|
43 |
+
|
44 |
+
@spaces.GPU(duration=30)
|
45 |
+
def fl_run_example(image):
|
46 |
+
task_prompt = "<MORE_DETAILED_CAPTION>"
|
47 |
+
#prompt = task_prompt + "Describe this image in great detail."
|
48 |
+
prompt = task_prompt
|
49 |
+
|
50 |
+
# Ensure the image is in RGB mode
|
51 |
+
if image.mode != "RGB":
|
52 |
+
image = image.convert("RGB")
|
53 |
+
|
54 |
+
fl_model.to(device)
|
55 |
+
inputs = fl_processor(text=prompt, images=image, return_tensors="pt").to(device)
|
56 |
+
generated_ids = fl_model.generate(
|
57 |
+
input_ids=inputs["input_ids"],
|
58 |
+
pixel_values=inputs["pixel_values"],
|
59 |
+
max_new_tokens=1024,
|
60 |
+
num_beams=3
|
61 |
+
)
|
62 |
+
fl_model.to("cpu")
|
63 |
+
generated_text = fl_processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
|
64 |
+
parsed_answer = fl_processor.post_process_generation(generated_text, task=task_prompt, image_size=(image.width, image.height))
|
65 |
+
return fl_modify_caption(parsed_answer["<MORE_DETAILED_CAPTION>"])
|
66 |
+
|
67 |
+
|
68 |
+
def predict_tags_fl2_flux(image: Image.Image, input_tags: str, algo: list[str]):
|
69 |
+
def to_list(s):
|
70 |
+
return [x.strip() for x in s.split(",") if not s == ""]
|
71 |
+
|
72 |
+
def list_uniq(l):
|
73 |
+
return sorted(set(l), key=l.index)
|
74 |
+
|
75 |
+
if not "Use Florence-2-Flux" in algo:
|
76 |
+
return input_tags
|
77 |
+
tag_list = list_uniq(to_list(input_tags) + to_list(fl_run_example(image) + ", "))
|
78 |
+
tag_list.remove("")
|
79 |
+
return ", ".join(tag_list)
|
tagger/output.py
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dataclasses import dataclass
|
2 |
+
|
3 |
+
|
4 |
+
@dataclass
|
5 |
+
class UpsamplingOutput:
|
6 |
+
upsampled_tags: str
|
7 |
+
|
8 |
+
copyright_tags: str
|
9 |
+
character_tags: str
|
10 |
+
general_tags: str
|
11 |
+
rating_tag: str
|
12 |
+
aspect_ratio_tag: str
|
13 |
+
length_tag: str
|
14 |
+
identity_tag: str
|
15 |
+
|
16 |
+
elapsed_time: float = 0.0
|
tagger/tag_group.csv
ADDED
The diff for this file is too large to render.
See raw diff
|
|
tagger/tagger.py
ADDED
@@ -0,0 +1,552 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from PIL import Image
|
2 |
+
import torch
|
3 |
+
import gradio as gr
|
4 |
+
import spaces
|
5 |
+
from transformers import (
|
6 |
+
AutoImageProcessor,
|
7 |
+
AutoModelForImageClassification,
|
8 |
+
)
|
9 |
+
from pathlib import Path
|
10 |
+
|
11 |
+
|
12 |
+
WD_MODEL_NAMES = ["p1atdev/wd-swinv2-tagger-v3-hf"]
|
13 |
+
WD_MODEL_NAME = WD_MODEL_NAMES[0]
|
14 |
+
|
15 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
16 |
+
default_device = device
|
17 |
+
wd_model = AutoModelForImageClassification.from_pretrained(WD_MODEL_NAME, trust_remote_code=True).to(default_device).eval()
|
18 |
+
wd_processor = AutoImageProcessor.from_pretrained(WD_MODEL_NAME, trust_remote_code=True)
|
19 |
+
|
20 |
+
|
21 |
+
def _people_tag(noun: str, minimum: int = 1, maximum: int = 5):
|
22 |
+
return (
|
23 |
+
[f"1{noun}"]
|
24 |
+
+ [f"{num}{noun}s" for num in range(minimum + 1, maximum + 1)]
|
25 |
+
+ [f"{maximum+1}+{noun}s"]
|
26 |
+
)
|
27 |
+
|
28 |
+
|
29 |
+
PEOPLE_TAGS = (
|
30 |
+
_people_tag("girl") + _people_tag("boy") + _people_tag("other") + ["no humans"]
|
31 |
+
)
|
32 |
+
|
33 |
+
|
34 |
+
RATING_MAP = {
|
35 |
+
"sfw": "safe",
|
36 |
+
"general": "safe",
|
37 |
+
"sensitive": "sensitive",
|
38 |
+
"questionable": "nsfw",
|
39 |
+
"explicit": "explicit, nsfw",
|
40 |
+
}
|
41 |
+
DANBOORU_TO_E621_RATING_MAP = {
|
42 |
+
"sfw": "rating_safe",
|
43 |
+
"general": "rating_safe",
|
44 |
+
"safe": "rating_safe",
|
45 |
+
"sensitive": "rating_safe",
|
46 |
+
"nsfw": "rating_explicit",
|
47 |
+
"explicit, nsfw": "rating_explicit",
|
48 |
+
"explicit": "rating_explicit",
|
49 |
+
"rating:safe": "rating_safe",
|
50 |
+
"rating:general": "rating_safe",
|
51 |
+
"rating:sensitive": "rating_safe",
|
52 |
+
"rating:questionable, nsfw": "rating_explicit",
|
53 |
+
"rating:explicit, nsfw": "rating_explicit",
|
54 |
+
}
|
55 |
+
|
56 |
+
|
57 |
+
# https://github.com/toriato/stable-diffusion-webui-wd14-tagger/blob/a9eacb1eff904552d3012babfa28b57e1d3e295c/tagger/ui.py#L368
|
58 |
+
kaomojis = [
|
59 |
+
"0_0",
|
60 |
+
"(o)_(o)",
|
61 |
+
"+_+",
|
62 |
+
"+_-",
|
63 |
+
"._.",
|
64 |
+
"<o>_<o>",
|
65 |
+
"<|>_<|>",
|
66 |
+
"=_=",
|
67 |
+
">_<",
|
68 |
+
"3_3",
|
69 |
+
"6_9",
|
70 |
+
">_o",
|
71 |
+
"@_@",
|
72 |
+
"^_^",
|
73 |
+
"o_o",
|
74 |
+
"u_u",
|
75 |
+
"x_x",
|
76 |
+
"|_|",
|
77 |
+
"||_||",
|
78 |
+
]
|
79 |
+
|
80 |
+
|
81 |
+
def replace_underline(x: str):
|
82 |
+
return x.strip().replace("_", " ") if x not in kaomojis else x.strip()
|
83 |
+
|
84 |
+
|
85 |
+
def to_list(s):
|
86 |
+
return [x.strip() for x in s.split(",") if not s == ""]
|
87 |
+
|
88 |
+
|
89 |
+
def list_sub(a, b):
|
90 |
+
return [e for e in a if e not in b]
|
91 |
+
|
92 |
+
|
93 |
+
def list_uniq(l):
|
94 |
+
return sorted(set(l), key=l.index)
|
95 |
+
|
96 |
+
|
97 |
+
def load_dict_from_csv(filename):
|
98 |
+
dict = {}
|
99 |
+
if not Path(filename).exists():
|
100 |
+
if Path('./tagger/', filename).exists(): filename = str(Path('./tagger/', filename))
|
101 |
+
else: return dict
|
102 |
+
try:
|
103 |
+
with open(filename, 'r', encoding="utf-8") as f:
|
104 |
+
lines = f.readlines()
|
105 |
+
except Exception:
|
106 |
+
print(f"Failed to open dictionary file: {filename}")
|
107 |
+
return dict
|
108 |
+
for line in lines:
|
109 |
+
parts = line.strip().split(',')
|
110 |
+
dict[parts[0]] = parts[1]
|
111 |
+
return dict
|
112 |
+
|
113 |
+
|
114 |
+
anime_series_dict = load_dict_from_csv('character_series_dict.csv')
|
115 |
+
|
116 |
+
|
117 |
+
def character_list_to_series_list(character_list):
|
118 |
+
output_series_tag = []
|
119 |
+
series_tag = ""
|
120 |
+
series_dict = anime_series_dict
|
121 |
+
for tag in character_list:
|
122 |
+
series_tag = series_dict.get(tag, "")
|
123 |
+
if tag.endswith(")"):
|
124 |
+
tags = tag.split("(")
|
125 |
+
character_tag = "(".join(tags[:-1])
|
126 |
+
if character_tag.endswith(" "):
|
127 |
+
character_tag = character_tag[:-1]
|
128 |
+
series_tag = tags[-1].replace(")", "")
|
129 |
+
|
130 |
+
if series_tag:
|
131 |
+
output_series_tag.append(series_tag)
|
132 |
+
|
133 |
+
return output_series_tag
|
134 |
+
|
135 |
+
|
136 |
+
def select_random_character(series: str, character: str):
|
137 |
+
from random import seed, randrange
|
138 |
+
seed()
|
139 |
+
character_list = list(anime_series_dict.keys())
|
140 |
+
character = character_list[randrange(len(character_list) - 1)]
|
141 |
+
series = anime_series_dict.get(character.split(",")[0].strip(), "")
|
142 |
+
return series, character
|
143 |
+
|
144 |
+
|
145 |
+
def danbooru_to_e621(dtag, e621_dict):
|
146 |
+
def d_to_e(match, e621_dict):
|
147 |
+
dtag = match.group(0)
|
148 |
+
etag = e621_dict.get(replace_underline(dtag), "")
|
149 |
+
if etag:
|
150 |
+
return etag
|
151 |
+
else:
|
152 |
+
return dtag
|
153 |
+
|
154 |
+
import re
|
155 |
+
tag = re.sub(r'[\w ]+', lambda wrapper: d_to_e(wrapper, e621_dict), dtag, 2)
|
156 |
+
return tag
|
157 |
+
|
158 |
+
|
159 |
+
danbooru_to_e621_dict = load_dict_from_csv('danbooru_e621.csv')
|
160 |
+
|
161 |
+
|
162 |
+
def convert_danbooru_to_e621_prompt(input_prompt: str = "", prompt_type: str = "danbooru"):
|
163 |
+
if prompt_type == "danbooru": return input_prompt
|
164 |
+
tags = input_prompt.split(",") if input_prompt else []
|
165 |
+
people_tags: list[str] = []
|
166 |
+
other_tags: list[str] = []
|
167 |
+
rating_tags: list[str] = []
|
168 |
+
|
169 |
+
e621_dict = danbooru_to_e621_dict
|
170 |
+
for tag in tags:
|
171 |
+
tag = replace_underline(tag)
|
172 |
+
tag = danbooru_to_e621(tag, e621_dict)
|
173 |
+
if tag in PEOPLE_TAGS:
|
174 |
+
people_tags.append(tag)
|
175 |
+
elif tag in DANBOORU_TO_E621_RATING_MAP.keys():
|
176 |
+
rating_tags.append(DANBOORU_TO_E621_RATING_MAP.get(tag.replace(" ",""), ""))
|
177 |
+
else:
|
178 |
+
other_tags.append(tag)
|
179 |
+
|
180 |
+
rating_tags = sorted(set(rating_tags), key=rating_tags.index)
|
181 |
+
rating_tags = [rating_tags[0]] if rating_tags else []
|
182 |
+
rating_tags = ["explicit, nsfw"] if rating_tags and rating_tags[0] == "explicit" else rating_tags
|
183 |
+
|
184 |
+
output_prompt = ", ".join(people_tags + other_tags + rating_tags)
|
185 |
+
|
186 |
+
return output_prompt
|
187 |
+
|
188 |
+
|
189 |
+
def translate_prompt(prompt: str = ""):
|
190 |
+
def translate_to_english(prompt):
|
191 |
+
import httpcore
|
192 |
+
setattr(httpcore, 'SyncHTTPTransport', 'AsyncHTTPProxy')
|
193 |
+
from googletrans import Translator
|
194 |
+
translator = Translator()
|
195 |
+
try:
|
196 |
+
translated_prompt = translator.translate(prompt, src='auto', dest='en').text
|
197 |
+
return translated_prompt
|
198 |
+
except Exception as e:
|
199 |
+
print(e)
|
200 |
+
return prompt
|
201 |
+
|
202 |
+
def is_japanese(s):
|
203 |
+
import unicodedata
|
204 |
+
for ch in s:
|
205 |
+
name = unicodedata.name(ch, "")
|
206 |
+
if "CJK UNIFIED" in name or "HIRAGANA" in name or "KATAKANA" in name:
|
207 |
+
return True
|
208 |
+
return False
|
209 |
+
|
210 |
+
def to_list(s):
|
211 |
+
return [x.strip() for x in s.split(",")]
|
212 |
+
|
213 |
+
prompts = to_list(prompt)
|
214 |
+
outputs = []
|
215 |
+
for p in prompts:
|
216 |
+
p = translate_to_english(p) if is_japanese(p) else p
|
217 |
+
outputs.append(p)
|
218 |
+
|
219 |
+
return ", ".join(outputs)
|
220 |
+
|
221 |
+
|
222 |
+
def translate_prompt_to_ja(prompt: str = ""):
|
223 |
+
def translate_to_japanese(prompt):
|
224 |
+
import httpcore
|
225 |
+
setattr(httpcore, 'SyncHTTPTransport', 'AsyncHTTPProxy')
|
226 |
+
from googletrans import Translator
|
227 |
+
translator = Translator()
|
228 |
+
try:
|
229 |
+
translated_prompt = translator.translate(prompt, src='en', dest='ja').text
|
230 |
+
return translated_prompt
|
231 |
+
except Exception as e:
|
232 |
+
print(e)
|
233 |
+
return prompt
|
234 |
+
|
235 |
+
def is_japanese(s):
|
236 |
+
import unicodedata
|
237 |
+
for ch in s:
|
238 |
+
name = unicodedata.name(ch, "")
|
239 |
+
if "CJK UNIFIED" in name or "HIRAGANA" in name or "KATAKANA" in name:
|
240 |
+
return True
|
241 |
+
return False
|
242 |
+
|
243 |
+
def to_list(s):
|
244 |
+
return [x.strip() for x in s.split(",")]
|
245 |
+
|
246 |
+
prompts = to_list(prompt)
|
247 |
+
outputs = []
|
248 |
+
for p in prompts:
|
249 |
+
p = translate_to_japanese(p) if not is_japanese(p) else p
|
250 |
+
outputs.append(p)
|
251 |
+
|
252 |
+
return ", ".join(outputs)
|
253 |
+
|
254 |
+
|
255 |
+
def tags_to_ja(itag, dict):
|
256 |
+
def t_to_j(match, dict):
|
257 |
+
tag = match.group(0)
|
258 |
+
ja = dict.get(replace_underline(tag), "")
|
259 |
+
if ja:
|
260 |
+
return ja
|
261 |
+
else:
|
262 |
+
return tag
|
263 |
+
|
264 |
+
import re
|
265 |
+
tag = re.sub(r'[\w ]+', lambda wrapper: t_to_j(wrapper, dict), itag, 2)
|
266 |
+
|
267 |
+
return tag
|
268 |
+
|
269 |
+
|
270 |
+
def convert_tags_to_ja(input_prompt: str = ""):
|
271 |
+
tags = input_prompt.split(",") if input_prompt else []
|
272 |
+
out_tags = []
|
273 |
+
|
274 |
+
tags_to_ja_dict = load_dict_from_csv('all_tags_ja_ext.csv')
|
275 |
+
dict = tags_to_ja_dict
|
276 |
+
for tag in tags:
|
277 |
+
tag = replace_underline(tag)
|
278 |
+
tag = tags_to_ja(tag, dict)
|
279 |
+
out_tags.append(tag)
|
280 |
+
|
281 |
+
return ", ".join(out_tags)
|
282 |
+
|
283 |
+
|
284 |
+
enable_auto_recom_prompt = True
|
285 |
+
|
286 |
+
|
287 |
+
animagine_ps = to_list("masterpiece, best quality, very aesthetic, absurdres")
|
288 |
+
animagine_nps = to_list("lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]")
|
289 |
+
pony_ps = to_list("score_9, score_8_up, score_7_up, masterpiece, best quality, very aesthetic, absurdres")
|
290 |
+
pony_nps = to_list("source_pony, score_6, score_5, score_4, busty, ugly face, mutated hands, low res, blurry face, black and white, the simpsons, overwatch, apex legends")
|
291 |
+
other_ps = to_list("anime artwork, anime style, studio anime, highly detailed, cinematic photo, 35mm photograph, film, bokeh, professional, 4k, highly detailed")
|
292 |
+
other_nps = to_list("photo, deformed, black and white, realism, disfigured, low contrast, drawing, painting, crayon, sketch, graphite, impressionist, noisy, blurry, soft, deformed, ugly")
|
293 |
+
default_ps = to_list("highly detailed, masterpiece, best quality, very aesthetic, absurdres")
|
294 |
+
default_nps = to_list("score_6, score_5, score_4, lowres, (bad), text, error, fewer, extra, missing, worst quality, jpeg artifacts, low quality, watermark, unfinished, displeasing, oldest, early, chromatic aberration, signature, extra digits, artistic error, username, scan, [abstract]")
|
295 |
+
def insert_recom_prompt(prompt: str = "", neg_prompt: str = "", type: str = "None"):
|
296 |
+
global enable_auto_recom_prompt
|
297 |
+
prompts = to_list(prompt)
|
298 |
+
neg_prompts = to_list(neg_prompt)
|
299 |
+
|
300 |
+
prompts = list_sub(prompts, animagine_ps + pony_ps)
|
301 |
+
neg_prompts = list_sub(neg_prompts, animagine_nps + pony_nps)
|
302 |
+
|
303 |
+
last_empty_p = [""] if not prompts and type != "None" else []
|
304 |
+
last_empty_np = [""] if not neg_prompts and type != "None" else []
|
305 |
+
|
306 |
+
if type == "Auto":
|
307 |
+
enable_auto_recom_prompt = True
|
308 |
+
else:
|
309 |
+
enable_auto_recom_prompt = False
|
310 |
+
if type == "Animagine":
|
311 |
+
prompts = prompts + animagine_ps
|
312 |
+
neg_prompts = neg_prompts + animagine_nps
|
313 |
+
elif type == "Pony":
|
314 |
+
prompts = prompts + pony_ps
|
315 |
+
neg_prompts = neg_prompts + pony_nps
|
316 |
+
|
317 |
+
prompt = ", ".join(list_uniq(prompts) + last_empty_p)
|
318 |
+
neg_prompt = ", ".join(list_uniq(neg_prompts) + last_empty_np)
|
319 |
+
|
320 |
+
return prompt, neg_prompt
|
321 |
+
|
322 |
+
|
323 |
+
def load_model_prompt_dict():
|
324 |
+
import json
|
325 |
+
dict = {}
|
326 |
+
path = 'model_dict.json' if Path('model_dict.json').exists() else './tagger/model_dict.json'
|
327 |
+
try:
|
328 |
+
with open('model_dict.json', encoding='utf-8') as f:
|
329 |
+
dict = json.load(f)
|
330 |
+
except Exception:
|
331 |
+
pass
|
332 |
+
return dict
|
333 |
+
|
334 |
+
|
335 |
+
model_prompt_dict = load_model_prompt_dict()
|
336 |
+
|
337 |
+
|
338 |
+
def insert_model_recom_prompt(prompt: str = "", neg_prompt: str = "", model_name: str = "None"):
|
339 |
+
if not model_name or not enable_auto_recom_prompt: return prompt, neg_prompt
|
340 |
+
prompts = to_list(prompt)
|
341 |
+
neg_prompts = to_list(neg_prompt)
|
342 |
+
prompts = list_sub(prompts, animagine_ps + pony_ps + other_ps)
|
343 |
+
neg_prompts = list_sub(neg_prompts, animagine_nps + pony_nps + other_nps)
|
344 |
+
last_empty_p = [""] if not prompts and type != "None" else []
|
345 |
+
last_empty_np = [""] if not neg_prompts and type != "None" else []
|
346 |
+
ps = []
|
347 |
+
nps = []
|
348 |
+
if model_name in model_prompt_dict.keys():
|
349 |
+
ps = to_list(model_prompt_dict[model_name]["prompt"])
|
350 |
+
nps = to_list(model_prompt_dict[model_name]["negative_prompt"])
|
351 |
+
else:
|
352 |
+
ps = default_ps
|
353 |
+
nps = default_nps
|
354 |
+
prompts = prompts + ps
|
355 |
+
neg_prompts = neg_prompts + nps
|
356 |
+
prompt = ", ".join(list_uniq(prompts) + last_empty_p)
|
357 |
+
neg_prompt = ", ".join(list_uniq(neg_prompts) + last_empty_np)
|
358 |
+
return prompt, neg_prompt
|
359 |
+
|
360 |
+
|
361 |
+
tag_group_dict = load_dict_from_csv('tag_group.csv')
|
362 |
+
|
363 |
+
|
364 |
+
def remove_specific_prompt(input_prompt: str = "", keep_tags: str = "all"):
|
365 |
+
def is_dressed(tag):
|
366 |
+
import re
|
367 |
+
p = re.compile(r'dress|cloth|uniform|costume|vest|sweater|coat|shirt|jacket|blazer|apron|leotard|hood|sleeve|skirt|shorts|pant|loafer|ribbon|necktie|bow|collar|glove|sock|shoe|boots|wear|emblem')
|
368 |
+
return p.search(tag)
|
369 |
+
|
370 |
+
def is_background(tag):
|
371 |
+
import re
|
372 |
+
p = re.compile(r'background|outline|light|sky|build|day|screen|tree|city')
|
373 |
+
return p.search(tag)
|
374 |
+
|
375 |
+
un_tags = ['solo']
|
376 |
+
group_list = ['groups', 'body_parts', 'attire', 'posture', 'objects', 'creatures', 'locations', 'disambiguation_pages', 'commonly_misused_tags', 'phrases', 'verbs_and_gerunds', 'subjective', 'nudity', 'sex_objects', 'sex', 'sex_acts', 'image_composition', 'artistic_license', 'text', 'year_tags', 'metatags']
|
377 |
+
keep_group_dict = {
|
378 |
+
"body": ['groups', 'body_parts'],
|
379 |
+
"dress": ['groups', 'body_parts', 'attire'],
|
380 |
+
"all": group_list,
|
381 |
+
}
|
382 |
+
|
383 |
+
def is_necessary(tag, keep_tags, group_dict):
|
384 |
+
if keep_tags == "all":
|
385 |
+
return True
|
386 |
+
elif tag in un_tags or group_dict.get(tag, "") in explicit_group:
|
387 |
+
return False
|
388 |
+
elif keep_tags == "body" and is_dressed(tag):
|
389 |
+
return False
|
390 |
+
elif is_background(tag):
|
391 |
+
return False
|
392 |
+
else:
|
393 |
+
return True
|
394 |
+
|
395 |
+
if keep_tags == "all": return input_prompt
|
396 |
+
keep_group = keep_group_dict.get(keep_tags, keep_group_dict["body"])
|
397 |
+
explicit_group = list(set(group_list) ^ set(keep_group))
|
398 |
+
|
399 |
+
tags = input_prompt.split(",") if input_prompt else []
|
400 |
+
people_tags: list[str] = []
|
401 |
+
other_tags: list[str] = []
|
402 |
+
|
403 |
+
group_dict = tag_group_dict
|
404 |
+
for tag in tags:
|
405 |
+
tag = replace_underline(tag)
|
406 |
+
if tag in PEOPLE_TAGS:
|
407 |
+
people_tags.append(tag)
|
408 |
+
elif is_necessary(tag, keep_tags, group_dict):
|
409 |
+
other_tags.append(tag)
|
410 |
+
|
411 |
+
output_prompt = ", ".join(people_tags + other_tags)
|
412 |
+
|
413 |
+
return output_prompt
|
414 |
+
|
415 |
+
|
416 |
+
def sort_taglist(tags: list[str]):
|
417 |
+
if not tags: return []
|
418 |
+
character_tags: list[str] = []
|
419 |
+
series_tags: list[str] = []
|
420 |
+
people_tags: list[str] = []
|
421 |
+
group_list = ['groups', 'body_parts', 'attire', 'posture', 'objects', 'creatures', 'locations', 'disambiguation_pages', 'commonly_misused_tags', 'phrases', 'verbs_and_gerunds', 'subjective', 'nudity', 'sex_objects', 'sex', 'sex_acts', 'image_composition', 'artistic_license', 'text', 'year_tags', 'metatags']
|
422 |
+
group_tags = {}
|
423 |
+
other_tags: list[str] = []
|
424 |
+
rating_tags: list[str] = []
|
425 |
+
|
426 |
+
group_dict = tag_group_dict
|
427 |
+
group_set = set(group_dict.keys())
|
428 |
+
character_set = set(anime_series_dict.keys())
|
429 |
+
series_set = set(anime_series_dict.values())
|
430 |
+
rating_set = set(DANBOORU_TO_E621_RATING_MAP.keys()) | set(DANBOORU_TO_E621_RATING_MAP.values())
|
431 |
+
|
432 |
+
for tag in tags:
|
433 |
+
tag = replace_underline(tag)
|
434 |
+
if tag in PEOPLE_TAGS:
|
435 |
+
people_tags.append(tag)
|
436 |
+
elif tag in rating_set:
|
437 |
+
rating_tags.append(tag)
|
438 |
+
elif tag in group_set:
|
439 |
+
elem = group_dict[tag]
|
440 |
+
group_tags[elem] = group_tags[elem] + [tag] if elem in group_tags else [tag]
|
441 |
+
elif tag in character_set:
|
442 |
+
character_tags.append(tag)
|
443 |
+
elif tag in series_set:
|
444 |
+
series_tags.append(tag)
|
445 |
+
else:
|
446 |
+
other_tags.append(tag)
|
447 |
+
|
448 |
+
output_group_tags: list[str] = []
|
449 |
+
for k in group_list:
|
450 |
+
output_group_tags.extend(group_tags.get(k, []))
|
451 |
+
|
452 |
+
rating_tags = [rating_tags[0]] if rating_tags else []
|
453 |
+
rating_tags = ["explicit, nsfw"] if rating_tags and rating_tags[0] == "explicit" else rating_tags
|
454 |
+
|
455 |
+
output_tags = character_tags + series_tags + people_tags + output_group_tags + other_tags + rating_tags
|
456 |
+
|
457 |
+
return output_tags
|
458 |
+
|
459 |
+
|
460 |
+
def sort_tags(tags: str):
|
461 |
+
if not tags: return ""
|
462 |
+
taglist: list[str] = []
|
463 |
+
for tag in tags.split(","):
|
464 |
+
taglist.append(tag.strip())
|
465 |
+
taglist = list(filter(lambda x: x != "", taglist))
|
466 |
+
return ", ".join(sort_taglist(taglist))
|
467 |
+
|
468 |
+
|
469 |
+
def postprocess_results(results: dict[str, float], general_threshold: float, character_threshold: float):
|
470 |
+
results = {
|
471 |
+
k: v for k, v in sorted(results.items(), key=lambda item: item[1], reverse=True)
|
472 |
+
}
|
473 |
+
|
474 |
+
rating = {}
|
475 |
+
character = {}
|
476 |
+
general = {}
|
477 |
+
|
478 |
+
for k, v in results.items():
|
479 |
+
if k.startswith("rating:"):
|
480 |
+
rating[k.replace("rating:", "")] = v
|
481 |
+
continue
|
482 |
+
elif k.startswith("character:"):
|
483 |
+
character[k.replace("character:", "")] = v
|
484 |
+
continue
|
485 |
+
|
486 |
+
general[k] = v
|
487 |
+
|
488 |
+
character = {k: v for k, v in character.items() if v >= character_threshold}
|
489 |
+
general = {k: v for k, v in general.items() if v >= general_threshold}
|
490 |
+
|
491 |
+
return rating, character, general
|
492 |
+
|
493 |
+
|
494 |
+
def gen_prompt(rating: list[str], character: list[str], general: list[str]):
|
495 |
+
people_tags: list[str] = []
|
496 |
+
other_tags: list[str] = []
|
497 |
+
rating_tag = RATING_MAP[rating[0]]
|
498 |
+
|
499 |
+
for tag in general:
|
500 |
+
if tag in PEOPLE_TAGS:
|
501 |
+
people_tags.append(tag)
|
502 |
+
else:
|
503 |
+
other_tags.append(tag)
|
504 |
+
|
505 |
+
all_tags = people_tags + other_tags
|
506 |
+
|
507 |
+
return ", ".join(all_tags)
|
508 |
+
|
509 |
+
|
510 |
+
@spaces.GPU(duration=30)
|
511 |
+
def predict_tags(image: Image.Image, general_threshold: float = 0.3, character_threshold: float = 0.8):
|
512 |
+
inputs = wd_processor.preprocess(image, return_tensors="pt")
|
513 |
+
|
514 |
+
outputs = wd_model(**inputs.to(wd_model.device, wd_model.dtype))
|
515 |
+
logits = torch.sigmoid(outputs.logits[0]) # take the first logits
|
516 |
+
|
517 |
+
# get probabilities
|
518 |
+
if device != default_device: wd_model.to(device=device)
|
519 |
+
results = {
|
520 |
+
wd_model.config.id2label[i]: float(logit.float()) for i, logit in enumerate(logits)
|
521 |
+
}
|
522 |
+
if device != default_device: wd_model.to(device=default_device)
|
523 |
+
# rating, character, general
|
524 |
+
rating, character, general = postprocess_results(
|
525 |
+
results, general_threshold, character_threshold
|
526 |
+
)
|
527 |
+
prompt = gen_prompt(
|
528 |
+
list(rating.keys()), list(character.keys()), list(general.keys())
|
529 |
+
)
|
530 |
+
output_series_tag = ""
|
531 |
+
output_series_list = character_list_to_series_list(character.keys())
|
532 |
+
if output_series_list:
|
533 |
+
output_series_tag = output_series_list[0]
|
534 |
+
else:
|
535 |
+
output_series_tag = ""
|
536 |
+
return output_series_tag, ", ".join(character.keys()), prompt, gr.update(interactive=True)
|
537 |
+
|
538 |
+
|
539 |
+
def predict_tags_wd(image: Image.Image, input_tags: str, algo: list[str], general_threshold: float = 0.3,
|
540 |
+
character_threshold: float = 0.8, input_series: str = "", input_character: str = ""):
|
541 |
+
if not "Use WD Tagger" in algo and len(algo) != 0:
|
542 |
+
return input_series, input_character, input_tags, gr.update(interactive=True)
|
543 |
+
return predict_tags(image, general_threshold, character_threshold)
|
544 |
+
|
545 |
+
|
546 |
+
def compose_prompt_to_copy(character: str, series: str, general: str):
|
547 |
+
characters = character.split(",") if character else []
|
548 |
+
serieses = series.split(",") if series else []
|
549 |
+
generals = general.split(",") if general else []
|
550 |
+
tags = characters + serieses + generals
|
551 |
+
cprompt = ",".join(tags) if tags else ""
|
552 |
+
return cprompt
|
tagger/utils.py
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
from dartrs.v2 import AspectRatioTag, LengthTag, RatingTag, IdentityTag
|
3 |
+
|
4 |
+
|
5 |
+
V2_ASPECT_RATIO_OPTIONS: list[AspectRatioTag] = [
|
6 |
+
"ultra_wide",
|
7 |
+
"wide",
|
8 |
+
"square",
|
9 |
+
"tall",
|
10 |
+
"ultra_tall",
|
11 |
+
]
|
12 |
+
V2_RATING_OPTIONS: list[RatingTag] = [
|
13 |
+
"sfw",
|
14 |
+
"general",
|
15 |
+
"sensitive",
|
16 |
+
"nsfw",
|
17 |
+
"questionable",
|
18 |
+
"explicit",
|
19 |
+
]
|
20 |
+
V2_LENGTH_OPTIONS: list[LengthTag] = [
|
21 |
+
"very_short",
|
22 |
+
"short",
|
23 |
+
"medium",
|
24 |
+
"long",
|
25 |
+
"very_long",
|
26 |
+
]
|
27 |
+
V2_IDENTITY_OPTIONS: list[IdentityTag] = [
|
28 |
+
"none",
|
29 |
+
"lax",
|
30 |
+
"strict",
|
31 |
+
]
|
32 |
+
|
33 |
+
|
34 |
+
# ref: https://qiita.com/tregu148/items/fccccbbc47d966dd2fc2
|
35 |
+
def gradio_copy_text(_text: None):
|
36 |
+
gr.Info("Copied!")
|
37 |
+
|
38 |
+
|
39 |
+
COPY_ACTION_JS = """\
|
40 |
+
(inputs, _outputs) => {
|
41 |
+
// inputs is the string value of the input_text
|
42 |
+
if (inputs.trim() !== "") {
|
43 |
+
navigator.clipboard.writeText(inputs);
|
44 |
+
}
|
45 |
+
}"""
|
46 |
+
|
47 |
+
|
48 |
+
def gradio_copy_prompt(prompt: str):
|
49 |
+
gr.Info("Copied!")
|
50 |
+
return prompt
|
tagger/v2.py
ADDED
@@ -0,0 +1,260 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import time
|
2 |
+
import torch
|
3 |
+
from typing import Callable
|
4 |
+
from pathlib import Path
|
5 |
+
|
6 |
+
from dartrs.v2 import (
|
7 |
+
V2Model,
|
8 |
+
MixtralModel,
|
9 |
+
MistralModel,
|
10 |
+
compose_prompt,
|
11 |
+
LengthTag,
|
12 |
+
AspectRatioTag,
|
13 |
+
RatingTag,
|
14 |
+
IdentityTag,
|
15 |
+
)
|
16 |
+
from dartrs.dartrs import DartTokenizer
|
17 |
+
from dartrs.utils import get_generation_config
|
18 |
+
|
19 |
+
|
20 |
+
import gradio as gr
|
21 |
+
from gradio.components import Component
|
22 |
+
|
23 |
+
|
24 |
+
try:
|
25 |
+
from output import UpsamplingOutput
|
26 |
+
except:
|
27 |
+
from .output import UpsamplingOutput
|
28 |
+
|
29 |
+
|
30 |
+
V2_ALL_MODELS = {
|
31 |
+
"dart-v2-moe-sft": {
|
32 |
+
"repo": "p1atdev/dart-v2-moe-sft",
|
33 |
+
"type": "sft",
|
34 |
+
"class": MixtralModel,
|
35 |
+
},
|
36 |
+
"dart-v2-sft": {
|
37 |
+
"repo": "p1atdev/dart-v2-sft",
|
38 |
+
"type": "sft",
|
39 |
+
"class": MistralModel,
|
40 |
+
},
|
41 |
+
}
|
42 |
+
|
43 |
+
|
44 |
+
def prepare_models(model_config: dict):
|
45 |
+
model_name = model_config["repo"]
|
46 |
+
tokenizer = DartTokenizer.from_pretrained(model_name)
|
47 |
+
model = model_config["class"].from_pretrained(model_name)
|
48 |
+
|
49 |
+
return {
|
50 |
+
"tokenizer": tokenizer,
|
51 |
+
"model": model,
|
52 |
+
}
|
53 |
+
|
54 |
+
|
55 |
+
def normalize_tags(tokenizer: DartTokenizer, tags: str):
|
56 |
+
"""Just remove unk tokens."""
|
57 |
+
return ", ".join([tag for tag in tokenizer.tokenize(tags) if tag != "<|unk|>"])
|
58 |
+
|
59 |
+
|
60 |
+
@torch.no_grad()
|
61 |
+
def generate_tags(
|
62 |
+
model: V2Model,
|
63 |
+
tokenizer: DartTokenizer,
|
64 |
+
prompt: str,
|
65 |
+
ban_token_ids: list[int],
|
66 |
+
):
|
67 |
+
output = model.generate(
|
68 |
+
get_generation_config(
|
69 |
+
prompt,
|
70 |
+
tokenizer=tokenizer,
|
71 |
+
temperature=1,
|
72 |
+
top_p=0.9,
|
73 |
+
top_k=100,
|
74 |
+
max_new_tokens=256,
|
75 |
+
ban_token_ids=ban_token_ids,
|
76 |
+
),
|
77 |
+
)
|
78 |
+
|
79 |
+
return output
|
80 |
+
|
81 |
+
|
82 |
+
def _people_tag(noun: str, minimum: int = 1, maximum: int = 5):
|
83 |
+
return (
|
84 |
+
[f"1{noun}"]
|
85 |
+
+ [f"{num}{noun}s" for num in range(minimum + 1, maximum + 1)]
|
86 |
+
+ [f"{maximum+1}+{noun}s"]
|
87 |
+
)
|
88 |
+
|
89 |
+
|
90 |
+
PEOPLE_TAGS = (
|
91 |
+
_people_tag("girl") + _people_tag("boy") + _people_tag("other") + ["no humans"]
|
92 |
+
)
|
93 |
+
|
94 |
+
|
95 |
+
def gen_prompt_text(output: UpsamplingOutput):
|
96 |
+
# separate people tags (e.g. 1girl)
|
97 |
+
people_tags = []
|
98 |
+
other_general_tags = []
|
99 |
+
|
100 |
+
for tag in output.general_tags.split(","):
|
101 |
+
tag = tag.strip()
|
102 |
+
if tag in PEOPLE_TAGS:
|
103 |
+
people_tags.append(tag)
|
104 |
+
else:
|
105 |
+
other_general_tags.append(tag)
|
106 |
+
|
107 |
+
return ", ".join(
|
108 |
+
[
|
109 |
+
part.strip()
|
110 |
+
for part in [
|
111 |
+
*people_tags,
|
112 |
+
output.character_tags,
|
113 |
+
output.copyright_tags,
|
114 |
+
*other_general_tags,
|
115 |
+
output.upsampled_tags,
|
116 |
+
output.rating_tag,
|
117 |
+
]
|
118 |
+
if part.strip() != ""
|
119 |
+
]
|
120 |
+
)
|
121 |
+
|
122 |
+
|
123 |
+
def elapsed_time_format(elapsed_time: float) -> str:
|
124 |
+
return f"Elapsed: {elapsed_time:.2f} seconds"
|
125 |
+
|
126 |
+
|
127 |
+
def parse_upsampling_output(
|
128 |
+
upsampler: Callable[..., UpsamplingOutput],
|
129 |
+
):
|
130 |
+
def _parse_upsampling_output(*args) -> tuple[str, str, dict]:
|
131 |
+
output = upsampler(*args)
|
132 |
+
|
133 |
+
return (
|
134 |
+
gen_prompt_text(output),
|
135 |
+
elapsed_time_format(output.elapsed_time),
|
136 |
+
gr.update(interactive=True),
|
137 |
+
gr.update(interactive=True),
|
138 |
+
)
|
139 |
+
|
140 |
+
return _parse_upsampling_output
|
141 |
+
|
142 |
+
|
143 |
+
class V2UI:
|
144 |
+
model_name: str | None = None
|
145 |
+
model: V2Model
|
146 |
+
tokenizer: DartTokenizer
|
147 |
+
|
148 |
+
input_components: list[Component] = []
|
149 |
+
generate_btn: gr.Button
|
150 |
+
|
151 |
+
def on_generate(
|
152 |
+
self,
|
153 |
+
model_name: str,
|
154 |
+
copyright_tags: str,
|
155 |
+
character_tags: str,
|
156 |
+
general_tags: str,
|
157 |
+
rating_tag: RatingTag,
|
158 |
+
aspect_ratio_tag: AspectRatioTag,
|
159 |
+
length_tag: LengthTag,
|
160 |
+
identity_tag: IdentityTag,
|
161 |
+
ban_tags: str,
|
162 |
+
*args,
|
163 |
+
) -> UpsamplingOutput:
|
164 |
+
if self.model_name is None or self.model_name != model_name:
|
165 |
+
models = prepare_models(V2_ALL_MODELS[model_name])
|
166 |
+
self.model = models["model"]
|
167 |
+
self.tokenizer = models["tokenizer"]
|
168 |
+
self.model_name = model_name
|
169 |
+
|
170 |
+
# normalize tags
|
171 |
+
# copyright_tags = normalize_tags(self.tokenizer, copyright_tags)
|
172 |
+
# character_tags = normalize_tags(self.tokenizer, character_tags)
|
173 |
+
# general_tags = normalize_tags(self.tokenizer, general_tags)
|
174 |
+
|
175 |
+
ban_token_ids = self.tokenizer.encode(ban_tags.strip())
|
176 |
+
|
177 |
+
prompt = compose_prompt(
|
178 |
+
prompt=general_tags,
|
179 |
+
copyright=copyright_tags,
|
180 |
+
character=character_tags,
|
181 |
+
rating=rating_tag,
|
182 |
+
aspect_ratio=aspect_ratio_tag,
|
183 |
+
length=length_tag,
|
184 |
+
identity=identity_tag,
|
185 |
+
)
|
186 |
+
|
187 |
+
start = time.time()
|
188 |
+
upsampled_tags = generate_tags(
|
189 |
+
self.model,
|
190 |
+
self.tokenizer,
|
191 |
+
prompt,
|
192 |
+
ban_token_ids,
|
193 |
+
)
|
194 |
+
elapsed_time = time.time() - start
|
195 |
+
|
196 |
+
return UpsamplingOutput(
|
197 |
+
upsampled_tags=upsampled_tags,
|
198 |
+
copyright_tags=copyright_tags,
|
199 |
+
character_tags=character_tags,
|
200 |
+
general_tags=general_tags,
|
201 |
+
rating_tag=rating_tag,
|
202 |
+
aspect_ratio_tag=aspect_ratio_tag,
|
203 |
+
length_tag=length_tag,
|
204 |
+
identity_tag=identity_tag,
|
205 |
+
elapsed_time=elapsed_time,
|
206 |
+
)
|
207 |
+
|
208 |
+
|
209 |
+
def parse_upsampling_output_simple(upsampler: UpsamplingOutput):
|
210 |
+
return gen_prompt_text(upsampler)
|
211 |
+
|
212 |
+
|
213 |
+
v2 = V2UI()
|
214 |
+
|
215 |
+
|
216 |
+
def v2_upsampling_prompt(model: str = "dart-v2-moe-sft", copyright: str = "", character: str = "",
|
217 |
+
general_tags: str = "", rating: str = "nsfw", aspect_ratio: str = "square",
|
218 |
+
length: str = "very_long", identity: str = "lax", ban_tags: str = "censored"):
|
219 |
+
raw_prompt = parse_upsampling_output_simple(v2.on_generate(model, copyright, character, general_tags,
|
220 |
+
rating, aspect_ratio, length, identity, ban_tags))
|
221 |
+
return raw_prompt
|
222 |
+
|
223 |
+
|
224 |
+
def load_dict_from_csv(filename):
|
225 |
+
dict = {}
|
226 |
+
if not Path(filename).exists():
|
227 |
+
if Path('./tagger/', filename).exists(): filename = str(Path('./tagger/', filename))
|
228 |
+
else: return dict
|
229 |
+
try:
|
230 |
+
with open(filename, 'r', encoding="utf-8") as f:
|
231 |
+
lines = f.readlines()
|
232 |
+
except Exception:
|
233 |
+
print(f"Failed to open dictionary file: {filename}")
|
234 |
+
return dict
|
235 |
+
for line in lines:
|
236 |
+
parts = line.strip().split(',')
|
237 |
+
dict[parts[0]] = parts[1]
|
238 |
+
return dict
|
239 |
+
|
240 |
+
|
241 |
+
anime_series_dict = load_dict_from_csv('character_series_dict.csv')
|
242 |
+
|
243 |
+
|
244 |
+
def select_random_character(series: str, character: str):
|
245 |
+
from random import seed, randrange
|
246 |
+
seed()
|
247 |
+
character_list = list(anime_series_dict.keys())
|
248 |
+
character = character_list[randrange(len(character_list) - 1)]
|
249 |
+
series = anime_series_dict.get(character.split(",")[0].strip(), "")
|
250 |
+
return series, character
|
251 |
+
|
252 |
+
|
253 |
+
def v2_random_prompt(general_tags: str = "", copyright: str = "", character: str = "", rating: str = "nsfw",
|
254 |
+
aspect_ratio: str = "square", length: str = "very_long", identity: str = "lax",
|
255 |
+
ban_tags: str = "censored", model: str = "dart-v2-moe-sft"):
|
256 |
+
if copyright == "" and character == "":
|
257 |
+
copyright, character = select_random_character("", "")
|
258 |
+
raw_prompt = v2_upsampling_prompt(model, copyright, character, general_tags, rating,
|
259 |
+
aspect_ratio, length, identity, ban_tags)
|
260 |
+
return raw_prompt, copyright, character
|