Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
@@ -1,334 +1,175 @@
|
|
1 |
-
import requests
|
2 |
-
from bs4 import BeautifulSoup
|
3 |
-
import os
|
4 |
-
import json
|
5 |
import gradio as gr
|
6 |
-
from datasets import Dataset
|
7 |
-
from PIL import Image
|
8 |
-
from huggingface_hub import HfApi, HfFolder, Repository, create_repo
|
9 |
-
import io
|
10 |
-
import uuid
|
11 |
-
import time
|
12 |
import random
|
13 |
-
import
|
14 |
-
import
|
15 |
|
16 |
DATA_DIR = "/data"
|
17 |
-
IMAGES_DIR =
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
24 |
-
|
25 |
-
|
26 |
-
"
|
27 |
-
"
|
28 |
-
"Accept-Language": "en-US,en;q=0.5",
|
29 |
-
"Referer": "https://www.google.com/",
|
30 |
-
"DNT": "1",
|
31 |
-
"Connection": "keep-alive",
|
32 |
-
"Upgrade-Insecure-Requests": "1"
|
33 |
}
|
34 |
-
if cookies:
|
35 |
-
headers["Cookie"] = cookies
|
36 |
-
return headers
|
37 |
|
38 |
-
def
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
-
|
46 |
-
if script:
|
47 |
-
try:
|
48 |
-
js_object_str = script.string.split('=', 1)[1].strip().rstrip(';')
|
49 |
-
js_object_str = js_object_str.replace("'", '"')
|
50 |
-
image_data = json.loads(js_object_str)
|
51 |
-
return f"{image_data['domain']}{image_data['base_dir']}/{image_data['dir']}/{image_data['img']}"
|
52 |
-
except json.JSONDecodeError as e:
|
53 |
-
raise Exception(f"Failed to decode JSON: {str(e)}")
|
54 |
|
55 |
-
|
56 |
-
|
57 |
-
|
|
|
|
|
58 |
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
101 |
|
102 |
-
|
103 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
104 |
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
109 |
-
resized_dataset_name = f"{self.dataset_name} (resized)"
|
110 |
-
resized_dataset_builder = DatasetBuilder(resized_dataset_name)
|
111 |
-
resized_dataset_builder.dataset = self.dataset
|
112 |
-
resized_dataset_builder.resize_images()
|
113 |
-
resized_dataset_builder.save_dataset()
|
114 |
-
return f"Resized dataset '{self.dataset_name}' to '{resized_dataset_name}'."
|
115 |
-
|
116 |
-
def create_downloadable_dataset(self):
|
117 |
-
if not self.dataset:
|
118 |
-
return None, "Dataset is empty. Add some images first."
|
119 |
-
|
120 |
-
try:
|
121 |
-
# Create a temporary ZIP file
|
122 |
-
zip_filename = f"{self.dataset_name}.zip"
|
123 |
-
zip_path = os.path.join(DATA_DIR, zip_filename)
|
124 |
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
133 |
-
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
-
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
150 |
-
|
151 |
-
|
152 |
-
if not image_url:
|
153 |
-
raise Exception("Failed to extract image URL")
|
154 |
-
|
155 |
-
tags = extract_tags(html_content)
|
156 |
-
image = download_image(image_url, cookies)
|
157 |
-
|
158 |
-
filename = f"{uuid.uuid4()}.jpg"
|
159 |
-
filepath = os.path.join(IMAGES_DIR, filename)
|
160 |
-
|
161 |
-
image.save(filepath)
|
162 |
-
|
163 |
-
self.dataset.append({
|
164 |
-
'image': filename,
|
165 |
-
'text': tags
|
166 |
-
})
|
167 |
-
|
168 |
-
self.save_dataset()
|
169 |
-
return f"Added image with tags: {tags}"
|
170 |
-
except Exception as e:
|
171 |
-
return f"Error: {str(e)}"
|
172 |
-
|
173 |
-
def build_huggingface_dataset(self):
|
174 |
-
if not self.dataset:
|
175 |
-
return "Dataset is empty. Add some images first."
|
176 |
-
|
177 |
-
try:
|
178 |
-
hf_dataset = Dataset.from_dict({
|
179 |
-
'image': [os.path.join(IMAGES_DIR, item['image']) for item in self.dataset],
|
180 |
-
'text': [item['tags'] for item in self.dataset]
|
181 |
-
})
|
182 |
-
return "HuggingFace Dataset created successfully!"
|
183 |
-
except Exception as e:
|
184 |
-
return f"Error creating HuggingFace Dataset: {str(e)}"
|
185 |
-
|
186 |
-
def get_dataset_info(self):
|
187 |
-
return f"Current dataset size ({self.dataset_name}): {len(self.dataset)} images"
|
188 |
-
|
189 |
-
def get_dataset_preview(self, num_images=5):
|
190 |
-
preview = []
|
191 |
-
for item in self.dataset[-num_images:]:
|
192 |
-
image_path = os.path.join(IMAGES_DIR, item['image'])
|
193 |
-
preview.append((image_path, item['tags']))
|
194 |
-
return preview
|
195 |
-
|
196 |
-
def upload_to_huggingface(self, private=True):
|
197 |
-
if not self.dataset:
|
198 |
-
return "Dataset is empty. Add some images first."
|
199 |
-
|
200 |
-
if not self.hf_token:
|
201 |
-
return "Error: Hugging Face Token not found. Please make sure the token is correctly set as an environment variable."
|
202 |
-
|
203 |
-
try:
|
204 |
-
hf_api = HfApi(token=self.hf_token) # Use the token
|
205 |
-
hf_user = hf_api.whoami()["name"]
|
206 |
-
repo_id = f"{hf_user}/{self.dataset_name}"
|
207 |
-
|
208 |
-
# Create or update the repository
|
209 |
-
repo_url = create_repo(repo_id, token=self.hf_token, private=private, exist_ok=True)
|
210 |
-
|
211 |
-
# Save the dataset locally as a JSON file
|
212 |
-
dataset_file = self.get_dataset_file()
|
213 |
-
self.save_dataset()
|
214 |
-
|
215 |
-
# Initialize a local repository
|
216 |
-
repo = Repository(local_dir=DATA_DIR, clone_from=repo_id, use_auth_token=self.hf_token)
|
217 |
-
|
218 |
-
# Copy dataset files to the repository directory
|
219 |
-
repo.git_pull(lfs=True) # Pull the latest changes
|
220 |
-
os.makedirs(os.path.join(DATA_DIR, "images"), exist_ok=True)
|
221 |
-
|
222 |
-
for item in self.dataset:
|
223 |
-
src_image_path = os.path.join(IMAGES_DIR, item['image'])
|
224 |
-
dst_image_path = os.path.join(repo.local_dir, "images", item['image'])
|
225 |
-
if not os.path.exists(dst_image_path):
|
226 |
-
os.makedirs(os.path.dirname(dst_image_path), exist_ok=True)
|
227 |
-
os.system(f"cp {src_image_path} {dst_image_path}")
|
228 |
-
|
229 |
-
# Add files to the repository and push
|
230 |
-
repo.git_add(pattern=".")
|
231 |
-
repo.git_commit("Add dataset and images")
|
232 |
-
repo.git_push()
|
233 |
-
|
234 |
-
return f"Dataset '{self.dataset_name}' successfully uploaded to Hugging Face Hub as a {'private' if private else 'public'} repository."
|
235 |
-
|
236 |
-
except Exception as e:
|
237 |
-
return f"Error uploading dataset to Hugging Face: {str(e)}"
|
238 |
-
|
239 |
-
def add_image_to_dataset(url, cookies, dataset_name):
|
240 |
-
builder = DatasetBuilder(dataset_name)
|
241 |
-
result = builder.add_image(url, cookies)
|
242 |
-
return result, builder.get_dataset_info(), builder.get_dataset_preview()
|
243 |
-
|
244 |
-
def create_huggingface_dataset(dataset_name):
|
245 |
-
builder = DatasetBuilder(dataset_name)
|
246 |
-
return builder.build_huggingface_dataset()
|
247 |
-
|
248 |
-
def view_dataset(dataset_name):
|
249 |
-
builder = DatasetBuilder(dataset_name)
|
250 |
-
return builder.get_dataset_preview(num_images=60)
|
251 |
-
|
252 |
-
def upload_huggingface_dataset(dataset_name, privacy):
|
253 |
-
builder = DatasetBuilder(dataset_name)
|
254 |
-
return builder.upload_to_huggingface(private=privacy)
|
255 |
-
|
256 |
-
def download_dataset(dataset_name):
|
257 |
-
builder = DatasetBuilder(dataset_name)
|
258 |
-
zip_path, message = builder.create_downloadable_dataset()
|
259 |
-
return zip_path, message
|
260 |
-
|
261 |
-
def resize_dataset(dataset_name):
|
262 |
-
builder = DatasetBuilder(dataset_name)
|
263 |
-
return builder.resize_dataset()
|
264 |
-
|
265 |
-
def download_resized_dataset(dataset_name):
|
266 |
-
builder = DatasetBuilder(f"{dataset_name} (resized)")
|
267 |
-
zip_path, message = builder.create_downloadable_dataset()
|
268 |
-
return zip_path, message
|
269 |
-
|
270 |
-
# Create Gradio interface
|
271 |
-
with gr.Blocks(theme="huggingface") as iface:
|
272 |
-
gr.Markdown("# Image Dataset Builder")
|
273 |
-
gr.Markdown("Enter a URL to add an image and its tags to the dataset. Progress is saved automatically.")
|
274 |
-
|
275 |
-
with gr.Row():
|
276 |
-
dataset_name_input = gr.Textbox(lines=1, label="Dataset Name", placeholder="Enter dataset name...", value="default_dataset")
|
277 |
-
url_input = gr.Textbox(lines=2, label="URL", placeholder="Enter image URL here...")
|
278 |
-
cookies_input = gr.Textbox(lines=2, label="Cookies (optional)", placeholder="Enter cookies")
|
279 |
-
add_button = gr.Button("Add Image")
|
280 |
-
|
281 |
-
result_output = gr.Textbox(label="Result")
|
282 |
-
dataset_info = gr.Textbox(label="Dataset Info")
|
283 |
-
|
284 |
-
gr.Markdown("## Dataset Preview")
|
285 |
-
preview_gallery = gr.Gallery(label="Recent Additions", show_label=False, elem_id="preview_gallery", columns=5, rows=1, height="auto")
|
286 |
-
|
287 |
-
add_button.click(add_image_to_dataset, inputs=[url_input, cookies_input, dataset_name_input], outputs=[result_output, dataset_info, preview_gallery])
|
288 |
-
|
289 |
-
create_hf_button = gr.Button("Create HuggingFace Dataset")
|
290 |
-
hf_result = gr.Textbox(label="Dataset Creation Result")
|
291 |
-
create_hf_button.click(create_huggingface_dataset, inputs=[dataset_name_input], outputs=hf_result)
|
292 |
-
|
293 |
-
view_dataset_button = gr.Button("View Dataset")
|
294 |
-
dataset_gallery = gr.Gallery(label="Dataset Contents", show_label=False, elem_id="dataset_gallery", columns=5, rows=4, height="auto")
|
295 |
-
view_dataset_button.click(view_dataset, inputs=[dataset_name_input], outputs=dataset_gallery)
|
296 |
-
|
297 |
-
gr.Markdown("## Upload Dataset to Hugging Face")
|
298 |
-
privacy_radio = gr.Radio(choices=["private", "public"], value="private", label="Repository Privacy")
|
299 |
-
upload_hf_button = gr.Button("Upload to Hugging Face")
|
300 |
-
hf_upload_result = gr.Textbox(label="Upload Result")
|
301 |
-
upload_hf_button.click(upload_huggingface_dataset, inputs=[dataset_name_input, privacy_radio], outputs=hf_upload_result)
|
302 |
-
|
303 |
-
gr.Markdown("## Download Dataset")
|
304 |
-
download_button = gr.Button("Download Dataset")
|
305 |
-
download_output = gr.File(label="Download")
|
306 |
-
download_message = gr.Textbox(label="Download Status")
|
307 |
-
|
308 |
-
download_button.click(
|
309 |
-
download_dataset,
|
310 |
-
inputs=[dataset_name_input],
|
311 |
-
outputs=[download_output, download_message]
|
312 |
-
)
|
313 |
-
|
314 |
-
gr.Markdown("## Resize Dataset")
|
315 |
-
resize_button = gr.Button("Resize Dataset")
|
316 |
-
resize_result = gr.Textbox(label="Resize Result")
|
317 |
-
resize_button.click(
|
318 |
-
resize_dataset,
|
319 |
-
inputs=[dataset_name_input],
|
320 |
-
outputs=resize_result
|
321 |
-
)
|
322 |
-
|
323 |
-
gr.Markdown("## Download Resized Dataset")
|
324 |
-
download_resized_button = gr.Button("Download Resized Dataset")
|
325 |
-
download_resized_output = gr.File(label="Download Resized")
|
326 |
-
download_resized_message = gr.Textbox(label="Resized Download Status")
|
327 |
-
download_resized_button.click(
|
328 |
-
download_resized_dataset,
|
329 |
-
inputs=[dataset_name_input],
|
330 |
-
outputs=[download_resized_output, download_resized_message]
|
331 |
-
)
|
332 |
-
|
333 |
-
# Launch the interface
|
334 |
-
iface.launch()
|
|
|
|
|
|
|
|
|
|
|
1 |
import gradio as gr
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import random
|
3 |
+
import json
|
4 |
+
import os
|
5 |
|
6 |
DATA_DIR = "/data"
|
7 |
+
IMAGES_DIR = "/images"
|
8 |
+
DATA_FILE = os.path.join(DATA_DIR, "saved_data.json")
|
9 |
+
|
10 |
+
def load_data():
|
11 |
+
if os.path.exists(DATA_FILE):
|
12 |
+
with open(DATA_FILE, 'r') as f:
|
13 |
+
return json.load(f)
|
14 |
+
return {
|
15 |
+
"scene_tags": [], "position_tags": [], "outfit_tags": [],
|
16 |
+
"camera_tags": [], "concept_tags": [], "lora_tags": [],
|
17 |
+
"characters": {}
|
|
|
|
|
|
|
|
|
|
|
18 |
}
|
|
|
|
|
|
|
19 |
|
20 |
+
def save_data(data):
|
21 |
+
os.makedirs(DATA_DIR, exist_ok=True)
|
22 |
+
with open(DATA_FILE, 'w') as f:
|
23 |
+
json.dump(data, f)
|
24 |
+
|
25 |
+
def save_character_image(name, image):
|
26 |
+
os.makedirs(IMAGES_DIR, exist_ok=True)
|
27 |
+
image_path = os.path.join(IMAGES_DIR, f"{name}.png")
|
28 |
+
image.save(image_path)
|
29 |
+
return image_path
|
30 |
+
|
31 |
+
def generate_prompt(scene_tags, num_people, position_tags, selected_characters, outfit_tags, camera_tags, concept_tags, lora_tags, tag_counts, data):
|
32 |
+
all_tags = {
|
33 |
+
"scene": scene_tags.split(','),
|
34 |
+
"position": position_tags.split(','),
|
35 |
+
"outfit": outfit_tags.split(','),
|
36 |
+
"camera": camera_tags.split(','),
|
37 |
+
"concept": concept_tags.split(','),
|
38 |
+
}
|
39 |
|
40 |
+
all_tags = {k: [tag.strip() for tag in v if tag.strip()] for k, v in all_tags.items()}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
+
character_prompts = [
|
43 |
+
f"{char_name}, " + ", ".join(random.sample(data["characters"][char_name]["traits"],
|
44 |
+
min(tag_counts["character"], len(data["characters"][char_name]["traits"]))))
|
45 |
+
for char_name in selected_characters if char_name in data["characters"]
|
46 |
+
]
|
47 |
|
48 |
+
selected_tags = [
|
49 |
+
f"{tag}:{random.uniform(0.8, 1.2):.2f}"
|
50 |
+
for category, tags in all_tags.items()
|
51 |
+
for tag in random.sample(tags, min(tag_counts[category], len(tags)))
|
52 |
+
]
|
53 |
+
|
54 |
+
if num_people.strip():
|
55 |
+
selected_tags.append(f"{num_people} people:1.1")
|
56 |
+
|
57 |
+
prompt_parts = character_prompts + selected_tags
|
58 |
+
random.shuffle(prompt_parts)
|
59 |
+
main_prompt = ", ".join(prompt_parts)
|
60 |
+
|
61 |
+
lora_list = [lora.strip() for lora in lora_tags.split(',') if lora.strip()]
|
62 |
+
lora_prompt = " ".join(f"<lora:{lora}:1>" for lora in lora_list)
|
63 |
+
|
64 |
+
fixed_tags = "source_anime, score_9, score_8_up, score_7_up, masterpiece, best quality, very aesthetic, absurdres, anime artwork, anime style, vibrant, studio anime, highly detailed"
|
65 |
+
|
66 |
+
return f"{main_prompt}, {fixed_tags} {lora_prompt}".strip()
|
67 |
+
|
68 |
+
def update_data(data, key, value):
|
69 |
+
data[key] = list(set(data[key] + [v.strip() for v in value.split(',') if v.strip()]))
|
70 |
+
save_data(data)
|
71 |
+
return data
|
72 |
+
|
73 |
+
def create_character(name, traits, image, data):
|
74 |
+
if name:
|
75 |
+
data["characters"][name] = {
|
76 |
+
"traits": [trait.strip() for trait in traits.split(',') if trait.strip()],
|
77 |
+
"image": save_character_image(name, image) if image else None
|
78 |
+
}
|
79 |
+
save_data(data)
|
80 |
+
return data, gr.update(choices=list(data["characters"].keys()))
|
81 |
+
|
82 |
+
def create_ui():
|
83 |
+
data = load_data()
|
84 |
+
|
85 |
+
with gr.Blocks() as demo:
|
86 |
+
gr.Markdown("# Advanced Pony SDXL Prompt Generator with Character Creation")
|
87 |
+
|
88 |
+
with gr.Tabs():
|
89 |
+
with gr.TabItem("Prompt Generator"):
|
90 |
+
with gr.Row():
|
91 |
+
with gr.Column():
|
92 |
+
scene_input = gr.Textbox(label="Scene Tags (comma-separated)", value=", ".join(data["scene_tags"]))
|
93 |
+
scene_count = gr.Slider(minimum=1, maximum=10, step=1, value=3, label="Number of scene tags")
|
94 |
+
|
95 |
+
num_people_input = gr.Textbox(label="Number of People")
|
96 |
+
|
97 |
+
position_input = gr.Textbox(label="Position Tags (comma-separated)", value=", ".join(data["position_tags"]))
|
98 |
+
position_count = gr.Slider(minimum=1, maximum=10, step=1, value=3, label="Number of position tags")
|
99 |
+
|
100 |
+
character_select = gr.CheckboxGroup(label="Select Characters", choices=list(data["characters"].keys()))
|
101 |
+
character_count = gr.Slider(minimum=1, maximum=10, step=1, value=3, label="Number of character traits")
|
102 |
+
|
103 |
+
outfit_input = gr.Textbox(label="Outfit Tags (comma-separated)", value=", ".join(data["outfit_tags"]))
|
104 |
+
outfit_count = gr.Slider(minimum=1, maximum=10, step=1, value=3, label="Number of outfit tags")
|
105 |
+
|
106 |
+
camera_input = gr.Textbox(label="Camera View/Angle Tags (comma-separated)", value=", ".join(data["camera_tags"]))
|
107 |
+
camera_count = gr.Slider(minimum=1, maximum=10, step=1, value=3, label="Number of camera tags")
|
108 |
+
|
109 |
+
concept_input = gr.Textbox(label="Concept Tags (comma-separated)", value=", ".join(data["concept_tags"]))
|
110 |
+
concept_count = gr.Slider(minimum=1, maximum=10, step=1, value=3, label="Number of concept tags")
|
111 |
+
|
112 |
+
lora_input = gr.Textbox(label="LORA Tags (comma-separated)", value=", ".join(data["lora_tags"]))
|
113 |
+
lora_count = gr.Slider(minimum=1, maximum=10, step=1, value=3, label="Number of LORA tags")
|
114 |
+
|
115 |
+
generate_button = gr.Button("Generate Prompt")
|
116 |
+
|
117 |
+
with gr.Column():
|
118 |
+
output = gr.Textbox(label="Generated Prompt", lines=5)
|
119 |
+
|
120 |
+
char_images = [char_data["image"] for char_data in data["characters"].values() if char_data["image"]]
|
121 |
+
gr.Gallery(value=char_images, label="Character Images", show_label=True, elem_id="char_gallery", columns=2, rows=2, height="auto")
|
122 |
|
123 |
+
with gr.TabItem("Character Creation"):
|
124 |
+
with gr.Row():
|
125 |
+
with gr.Column():
|
126 |
+
char_name_input = gr.Textbox(label="Character Name")
|
127 |
+
char_traits_input = gr.Textbox(label="Character Traits (comma-separated)")
|
128 |
+
char_image_input = gr.Image(label="Character Image", type="pil")
|
129 |
+
create_char_button = gr.Button("Create/Update Character")
|
130 |
+
|
131 |
+
with gr.Column():
|
132 |
+
char_gallery = gr.Gallery(label="Existing Characters", show_label=True, elem_id="char_gallery", columns=2, rows=2, height="auto")
|
133 |
+
|
134 |
+
def update_and_generate(*args):
|
135 |
+
nonlocal data
|
136 |
+
scene_tags, num_people, position_tags, selected_characters, outfit_tags, camera_tags, concept_tags, lora_tags, *tag_counts = args
|
137 |
+
data = update_data(data, "scene_tags", scene_tags)
|
138 |
+
data = update_data(data, "position_tags", position_tags)
|
139 |
+
data = update_data(data, "outfit_tags", outfit_tags)
|
140 |
+
data = update_data(data, "camera_tags", camera_tags)
|
141 |
+
data = update_data(data, "concept_tags", concept_tags)
|
142 |
+
data = update_data(data, "lora_tags", lora_tags)
|
143 |
|
144 |
+
tag_count_dict = {
|
145 |
+
"scene": tag_counts[0], "position": tag_counts[1], "character": tag_counts[2],
|
146 |
+
"outfit": tag_counts[3], "camera": tag_counts[4], "concept": tag_counts[5], "lora": tag_counts[6]
|
147 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
148 |
|
149 |
+
return generate_prompt(scene_tags, num_people, position_tags, selected_characters, outfit_tags, camera_tags, concept_tags, lora_tags, tag_count_dict, data)
|
150 |
+
|
151 |
+
generate_button.click(
|
152 |
+
update_and_generate,
|
153 |
+
inputs=[scene_input, num_people_input, position_input, character_select, outfit_input, camera_input, concept_input, lora_input,
|
154 |
+
scene_count, position_count, character_count, outfit_count, camera_count, concept_count, lora_count],
|
155 |
+
outputs=[output]
|
156 |
+
)
|
157 |
+
|
158 |
+
def update_char_gallery():
|
159 |
+
char_images = [char_data["image"] for char_data in data["characters"].values() if char_data["image"]]
|
160 |
+
return gr.Gallery(value=char_images)
|
161 |
+
|
162 |
+
create_char_button.click(
|
163 |
+
create_character,
|
164 |
+
inputs=[char_name_input, char_traits_input, char_image_input],
|
165 |
+
outputs=[gr.State(data), character_select]
|
166 |
+
).then(
|
167 |
+
update_char_gallery,
|
168 |
+
outputs=[char_gallery]
|
169 |
+
)
|
170 |
+
|
171 |
+
return demo
|
172 |
+
|
173 |
+
if __name__ == "__main__":
|
174 |
+
demo = create_ui()
|
175 |
+
demo.launch()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|