Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -108,6 +108,7 @@ def character_creation_app(data_manager):
|
|
108 |
character['image'] = None
|
109 |
|
110 |
data_manager.add_character(character)
|
|
|
111 |
return f"Character '{name}' saved successfully."
|
112 |
|
113 |
save_button.click(save_character, inputs=[name_input, traits_input, image_input, gender_input], outputs=output)
|
@@ -137,12 +138,37 @@ def prompt_generator_app(data_manager):
|
|
137 |
with gr.Group():
|
138 |
gr.Markdown("### Character Selection")
|
139 |
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
146 |
|
147 |
random_characters = gr.Checkbox(label="Select Random Characters")
|
148 |
num_characters = gr.Slider(minimum=0, maximum=10, step=1, value=1, label="Number of Characters (if random)")
|
@@ -150,60 +176,7 @@ def prompt_generator_app(data_manager):
|
|
150 |
generate_button = gr.Button("Generate Prompt")
|
151 |
prompt_output = gr.Textbox(label="Generated Prompt", lines=5)
|
152 |
|
153 |
-
# Function to display characters with images and selection checkboxes
|
154 |
-
def display_characters():
|
155 |
-
characters = data_manager.get_characters()
|
156 |
-
if not characters:
|
157 |
-
return "<p>No characters available. Please add characters in the Character Creation tab.</p>"
|
158 |
-
|
159 |
-
# Build HTML content for characters display
|
160 |
-
html_content = "<div style='display: flex; flex-wrap: wrap;'>"
|
161 |
-
for idx, char in enumerate(characters):
|
162 |
-
image_path = char.get('image_path', '')
|
163 |
-
image_url = ''
|
164 |
-
if image_path and os.path.exists(image_path):
|
165 |
-
with open(image_path, "rb") as img_file:
|
166 |
-
image_data = base64.b64encode(img_file.read()).decode('utf-8')
|
167 |
-
image_url = f"data:image/png;base64,{image_data}"
|
168 |
-
else:
|
169 |
-
image_url = ""
|
170 |
-
|
171 |
-
# Each character card
|
172 |
-
html_content += f"""
|
173 |
-
<div style='margin: 10px; text-align: center; width: 150px;'>
|
174 |
-
<img src='{image_url}' style='width: 100%; height: auto;'/>
|
175 |
-
<p>{char['name']}</p>
|
176 |
-
<input type='checkbox' name='character_select' value='{char['name']}' onchange='updateSelectedCharacters()'/>
|
177 |
-
</div>
|
178 |
-
"""
|
179 |
-
html_content += "</div>"
|
180 |
-
|
181 |
-
# JavaScript function to update selected characters
|
182 |
-
html_content += """
|
183 |
-
<script>
|
184 |
-
function updateSelectedCharacters() {
|
185 |
-
let selected = [];
|
186 |
-
let checkboxes = document.getElementsByName('character_select');
|
187 |
-
for (let i = 0; i < checkboxes.length; i++) {
|
188 |
-
if (checkboxes[i].checked) {
|
189 |
-
selected.push(checkboxes[i].value);
|
190 |
-
}
|
191 |
-
}
|
192 |
-
document.getElementById('selected_character_names').value = JSON.stringify(selected);
|
193 |
-
}
|
194 |
-
</script>
|
195 |
-
"""
|
196 |
-
|
197 |
-
return html_content
|
198 |
-
|
199 |
-
# Initialize characters_display with the HTML content
|
200 |
-
characters_display.value = display_characters()
|
201 |
-
|
202 |
-
# When refresh_characters_button is clicked, update characters_display
|
203 |
-
refresh_characters_button.click(fn=display_characters, outputs=characters_display)
|
204 |
-
|
205 |
def generate_prompt(*args):
|
206 |
-
# args correspond to inputs in the order they are defined
|
207 |
arg_idx = 0
|
208 |
|
209 |
prompt_tags = []
|
@@ -218,22 +191,21 @@ def prompt_generator_app(data_manager):
|
|
218 |
prompt_tags.extend(selected_tags)
|
219 |
|
220 |
# Handle Characters
|
221 |
-
|
|
|
222 |
random_chars = args[arg_idx + 1]
|
223 |
num_random_chars = args[arg_idx + 2]
|
224 |
|
225 |
arg_idx += 3
|
226 |
|
227 |
-
selected_character_names_list = json.loads(selected_characters_json) if selected_characters_json else []
|
228 |
-
|
229 |
characters = data_manager.get_characters()
|
230 |
|
231 |
-
selected_chars = []
|
232 |
if random_chars:
|
233 |
num = min(len(characters), int(num_random_chars))
|
234 |
selected_chars = random.sample(characters, num)
|
235 |
else:
|
236 |
-
selected_chars
|
|
|
237 |
|
238 |
# Determine the number of boys and girls
|
239 |
num_girls = sum(1 for char in selected_chars if char.get('gender') == 'Girl')
|
@@ -246,7 +218,10 @@ def prompt_generator_app(data_manager):
|
|
246 |
if num_boys > 0:
|
247 |
character_count_tags.append(f"{num_boys}boy" if num_boys == 1 else f"{num_boys}boys")
|
248 |
|
249 |
-
|
|
|
|
|
|
|
250 |
|
251 |
# Build character descriptions
|
252 |
character_descriptions = []
|
@@ -254,30 +229,32 @@ def prompt_generator_app(data_manager):
|
|
254 |
# Get traits for the character
|
255 |
traits = ', '.join(char['traits'])
|
256 |
# Create a description for each character
|
257 |
-
|
|
|
|
|
258 |
character_descriptions.append(character_description)
|
259 |
|
260 |
-
#
|
261 |
if character_descriptions:
|
262 |
character_descriptions_str = ' AND '.join(character_descriptions)
|
263 |
-
|
264 |
-
else:
|
265 |
-
prompt_string = f"{prompt_string}"
|
266 |
|
267 |
# Append selected prompt tags from categories
|
268 |
if prompt_tags:
|
269 |
-
prompt_tags_str = ', '.join(
|
270 |
-
|
271 |
|
272 |
# Load persistent tags
|
273 |
persistent_tags = data_manager.get_persistent_tags()
|
274 |
if persistent_tags:
|
275 |
-
persistent_tags_str = ', '.join(
|
276 |
-
|
277 |
|
278 |
# Add ending tags
|
279 |
ending_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"
|
280 |
-
|
|
|
|
|
281 |
|
282 |
return prompt_string
|
283 |
|
@@ -285,7 +262,8 @@ def prompt_generator_app(data_manager):
|
|
285 |
inputs_list = []
|
286 |
for var_name in inputs:
|
287 |
inputs_list.append(inputs[var_name])
|
288 |
-
|
|
|
289 |
|
290 |
generate_button.click(generate_prompt, inputs=inputs_list, outputs=prompt_output)
|
291 |
|
|
|
108 |
character['image'] = None
|
109 |
|
110 |
data_manager.add_character(character)
|
111 |
+
# Clear inputs after saving
|
112 |
return f"Character '{name}' saved successfully."
|
113 |
|
114 |
save_button.click(save_character, inputs=[name_input, traits_input, image_input, gender_input], outputs=output)
|
|
|
138 |
with gr.Group():
|
139 |
gr.Markdown("### Character Selection")
|
140 |
|
141 |
+
characters = data_manager.get_characters()
|
142 |
+
if not characters:
|
143 |
+
gr.Markdown("No characters available. Please add characters in the Character Creation tab.")
|
144 |
+
else:
|
145 |
+
# Display characters in a gallery
|
146 |
+
character_images = []
|
147 |
+
character_labels = []
|
148 |
+
for idx, char in enumerate(characters):
|
149 |
+
image_path = char.get('image_path', '')
|
150 |
+
image_url = ''
|
151 |
+
if image_path and os.path.exists(image_path):
|
152 |
+
image_url = image_path
|
153 |
+
else:
|
154 |
+
image_url = None # Or a placeholder image
|
155 |
+
character_images.append(image_url)
|
156 |
+
character_labels.append(f"{char['name']} ({char['gender']})")
|
157 |
+
character_select = gr.Gallery(label="Select Characters").style(grid=[3], height='auto')
|
158 |
+
|
159 |
+
selected_characters_state = gr.State([])
|
160 |
+
|
161 |
+
# Function to update selected characters
|
162 |
+
def update_selected_characters(selected_indices):
|
163 |
+
selected_indices = selected_indices or []
|
164 |
+
selected_chars = [characters[i] for i in selected_indices]
|
165 |
+
selected_char_names = [char['name'] for char in selected_chars]
|
166 |
+
return selected_characters_state.update(value=selected_chars)
|
167 |
+
|
168 |
+
# Update the gallery
|
169 |
+
character_select.render(character_images)
|
170 |
+
|
171 |
+
character_select.select(fn=update_selected_characters, inputs=[character_select], outputs=[selected_characters_state])
|
172 |
|
173 |
random_characters = gr.Checkbox(label="Select Random Characters")
|
174 |
num_characters = gr.Slider(minimum=0, maximum=10, step=1, value=1, label="Number of Characters (if random)")
|
|
|
176 |
generate_button = gr.Button("Generate Prompt")
|
177 |
prompt_output = gr.Textbox(label="Generated Prompt", lines=5)
|
178 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
179 |
def generate_prompt(*args):
|
|
|
180 |
arg_idx = 0
|
181 |
|
182 |
prompt_tags = []
|
|
|
191 |
prompt_tags.extend(selected_tags)
|
192 |
|
193 |
# Handle Characters
|
194 |
+
# Since Gradio's State cannot be passed directly, we retrieve it via args
|
195 |
+
selected_chars = args[arg_idx]
|
196 |
random_chars = args[arg_idx + 1]
|
197 |
num_random_chars = args[arg_idx + 2]
|
198 |
|
199 |
arg_idx += 3
|
200 |
|
|
|
|
|
201 |
characters = data_manager.get_characters()
|
202 |
|
|
|
203 |
if random_chars:
|
204 |
num = min(len(characters), int(num_random_chars))
|
205 |
selected_chars = random.sample(characters, num)
|
206 |
else:
|
207 |
+
# selected_chars is already set from the selected characters in the gallery
|
208 |
+
pass
|
209 |
|
210 |
# Determine the number of boys and girls
|
211 |
num_girls = sum(1 for char in selected_chars if char.get('gender') == 'Girl')
|
|
|
218 |
if num_boys > 0:
|
219 |
character_count_tags.append(f"{num_boys}boy" if num_boys == 1 else f"{num_boys}boys")
|
220 |
|
221 |
+
prompt_parts = []
|
222 |
+
|
223 |
+
if character_count_tags:
|
224 |
+
prompt_parts.append(', '.join(character_count_tags))
|
225 |
|
226 |
# Build character descriptions
|
227 |
character_descriptions = []
|
|
|
229 |
# Get traits for the character
|
230 |
traits = ', '.join(char['traits'])
|
231 |
# Create a description for each character
|
232 |
+
# For SDXL models, use the format "[char1] AND [char2]"
|
233 |
+
# Each character's description is enclosed in parentheses
|
234 |
+
character_description = f"({traits})"
|
235 |
character_descriptions.append(character_description)
|
236 |
|
237 |
+
# Join character descriptions appropriately for SDXL models
|
238 |
if character_descriptions:
|
239 |
character_descriptions_str = ' AND '.join(character_descriptions)
|
240 |
+
prompt_parts.append(character_descriptions_str)
|
|
|
|
|
241 |
|
242 |
# Append selected prompt tags from categories
|
243 |
if prompt_tags:
|
244 |
+
prompt_tags_str = ', '.join(prompt_tags)
|
245 |
+
prompt_parts.append(prompt_tags_str)
|
246 |
|
247 |
# Load persistent tags
|
248 |
persistent_tags = data_manager.get_persistent_tags()
|
249 |
if persistent_tags:
|
250 |
+
persistent_tags_str = ', '.join(persistent_tags)
|
251 |
+
prompt_parts.append(persistent_tags_str)
|
252 |
|
253 |
# Add ending tags
|
254 |
ending_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"
|
255 |
+
prompt_parts.append(ending_tags)
|
256 |
+
|
257 |
+
prompt_string = ', '.join(prompt_parts)
|
258 |
|
259 |
return prompt_string
|
260 |
|
|
|
262 |
inputs_list = []
|
263 |
for var_name in inputs:
|
264 |
inputs_list.append(inputs[var_name])
|
265 |
+
# Add selected characters state to inputs
|
266 |
+
inputs_list.extend([selected_characters_state, random_characters, num_characters])
|
267 |
|
268 |
generate_button.click(generate_prompt, inputs=inputs_list, outputs=prompt_output)
|
269 |
|