Astridkraft commited on
Commit
23f631d
·
verified ·
1 Parent(s): 63bfaff

Create ui.py

Browse files
Files changed (1) hide show
  1. ui.py +435 -0
ui.py ADDED
@@ -0,0 +1,435 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Gradio UI für AI Image Generator - Mit Mock-Funktionen für CPU-Testing
3
+ """
4
+ import gradio as gr
5
+ from PIL import Image, ImageDraw
6
+ import random
7
+ import time
8
+
9
+ # ==================== MOCK-FUNKTIONEN ====================
10
+ def mock_text_to_image(prompt, model_id, steps, guidance_scale, progress=None):
11
+ """Mock für Text-zu-Bild: Erzeugt einfaches Farbbild"""
12
+ print(f"📝 Mock text_to_image aufgerufen: '{prompt[:50]}...'")
13
+
14
+ if progress:
15
+ for i in range(10): # Simuliere Fortschritt
16
+ time.sleep(0.05)
17
+ progress((i+1)/10, desc="Mock-Generierung läuft...")
18
+
19
+ # Erstelle einfaches Farbbild
20
+ colors = ["lightblue", "lightgreen", "lavender", "peachpuff"]
21
+ img = Image.new('RGB', (512, 512), color=random.choice(colors))
22
+
23
+ # Füge Text hinzu (simulierter Prompt)
24
+ draw = ImageDraw.Draw(img)
25
+ text = f"Mock: {prompt[:30]}..." if len(prompt) > 30 else f"Mock: {prompt}"
26
+ draw.text((50, 256), text, fill="black")
27
+
28
+ status = f"✅ Mock: '{prompt[:30]}...' würde mit {model_id} generiert (Steps: {steps}, CFG: {guidance_scale})"
29
+ return img, status
30
+
31
+ def mock_img_to_image(image, prompt, neg_prompt, strength, steps, guidance_scale,
32
+ mode, bbox_x1, bbox_y1, bbox_x2, bbox_y2, progress=None):
33
+ """Mock für Bild-zu-Bild: Fügt Rahmen und Text hinzu"""
34
+ print(f"🎨 Mock img_to_image aufgerufen: Modus={mode}, Prompt='{prompt[:30]}...'")
35
+
36
+ if not image:
37
+ return None, None, None, None, None
38
+
39
+ if progress:
40
+ for i in range(10):
41
+ time.sleep(0.05)
42
+ progress((i+1)/10, desc=f"Mock-{mode} läuft...")
43
+
44
+ # Kopiere Bild und füge Effekte hinzu
45
+ img = image.copy().convert("RGB")
46
+ draw = ImageDraw.Draw(img)
47
+
48
+ # Rahmen basierend auf Modus
49
+ colors = {
50
+ "environment_change": "green",
51
+ "focus_change": "orange",
52
+ "face_only_change": "red"
53
+ }
54
+ border_color = colors.get(mode, "blue")
55
+
56
+ # Zeichne Rahmen
57
+ draw.rectangle([20, 20, img.width-20, img.height-20],
58
+ outline=border_color, width=10)
59
+
60
+ # BBox visualisieren (falls angegeben)
61
+ if all(v is not None for v in [bbox_x1, bbox_y1, bbox_x2, bbox_y2]):
62
+ x1, y1 = min(bbox_x1, bbox_x2), min(bbox_y1, bbox_y2)
63
+ x2, y2 = max(bbox_x1, bbox_x2), max(bbox_y1, bbox_y2)
64
+ draw.rectangle([x1, y1, x2, y2], outline="yellow", width=5)
65
+ draw.text((x1+5, y1+5), f"{mode}", fill="white")
66
+
67
+ # Text hinzufügen
68
+ draw.text((30, 30), f"Mock: {mode}", fill=border_color)
69
+ draw.text((30, 60), f"Strength: {strength}", fill="black")
70
+
71
+ # Mock-Masken (einfache Platzhalter)
72
+ mask_preview = Image.new('RGB', (256, 256), color='gray')
73
+ controlnet_map = Image.new('RGB', (256, 256), color='darkblue')
74
+ canny_map = Image.new('RGB', (256, 256), color='black')
75
+
76
+ status = f"✅ Mock: {mode} angewendet (Strength: {strength}, Steps: {steps})"
77
+ print(status)
78
+
79
+ return img, mask_preview, mask_preview, controlnet_map, canny_map
80
+
81
+ def mock_update_live_preview(image, bbox_x1, bbox_y1, bbox_x2, bbox_y2, mode):
82
+ """Mock für Live-Vorschau"""
83
+ if not image:
84
+ return None
85
+
86
+ preview = image.copy()
87
+ draw = ImageDraw.Draw(preview)
88
+
89
+ if all(v is not None for v in [bbox_x1, bbox_y1, bbox_x2, bbox_y2]):
90
+ x1, y1 = min(bbox_x1, bbox_x2), min(bbox_y1, bbox_y2)
91
+ x2, y2 = max(bbox_x1, bbox_x2), max(bbox_y1, bbox_y2)
92
+
93
+ colors = {"environment_change": "green",
94
+ "focus_change": "orange",
95
+ "face_only_change": "red"}
96
+
97
+ draw.rectangle([x1, y1, x2, y2], outline=colors.get(mode, "blue"), width=3)
98
+ draw.text((x1+5, y1-20), f"Mock: {mode}", fill=colors.get(mode, "blue"))
99
+
100
+ return preview
101
+
102
+ def mock_process_image_upload(image):
103
+ """Mock für Bild-Upload: Setzt BBox in der Mitte"""
104
+ if not image:
105
+ return None, 100, 100, 300, 300
106
+
107
+ w, h = image.size
108
+ bbox_size = min(w, h) * 0.3
109
+ x1 = (w - bbox_size) / 2
110
+ y1 = (h - bbox_size) / 4
111
+ x2 = x1 + bbox_size
112
+ y2 = y1 + bbox_size * 1.2
113
+
114
+ preview = mock_update_live_preview(image, x1, y1, x2, y2, "environment_change")
115
+ return preview, int(x1), int(y1), int(x2), int(y2)
116
+
117
+ def mock_update_slider_for_image(image):
118
+ """Mock für Slider-Update"""
119
+ if not image:
120
+ return (
121
+ gr.update(maximum=4096),
122
+ gr.update(maximum=4096),
123
+ gr.update(maximum=4096),
124
+ gr.update(maximum=4096)
125
+ )
126
+
127
+ w, h = image.size
128
+ max_val = min(max(w, h), 4096)
129
+
130
+ print(f"📐 Mock Slider-Maxima: {max_val}")
131
+ return (
132
+ gr.update(maximum=max_val),
133
+ gr.update(maximum=max_val),
134
+ gr.update(maximum=max_val),
135
+ gr.update(maximum=max_val)
136
+ )
137
+
138
+ def mock_update_model_settings(model_id):
139
+ """Mock für Modelleinstellungen"""
140
+ configs = {
141
+ "runwayml/stable-diffusion-v1-5": (35, 7.5, "🏠 SD 1.5 Mock"),
142
+ "SG161222/Realistic_Vision_V6.0_B1_noVAE": (40, 7.0, "👤 Realistic Vision Mock")
143
+ }
144
+ steps, cfg, msg = configs.get(model_id, (35, 7.5, "Standard Mock"))
145
+ return steps, cfg, f"📊 Mock-Einstellungen: {msg}"
146
+
147
+ def mock_update_info(mode):
148
+ """Mock für Prompt-Info-Update"""
149
+ if mode == "environment_change":
150
+ return (
151
+ "`[STIL-MOTIV], [UMGEBUNG], [VOR/HINTERGRUND]`",
152
+ "`[GESICHTER/ANATOMIE], [FEHLER]`"
153
+ )
154
+ elif mode == "focus_change":
155
+ return (
156
+ "`[GESICHTSBESCHREIBUNG], [KLEIDUNG], [POSITION]`",
157
+ "`[DEFORMIERT], [UNSCHÄRFE], [ANATOMIEFEHLER]`"
158
+ )
159
+ else:
160
+ return (
161
+ "`[HAARFARBE], [AUGEN], [GESICHTSAUSDRUCK]`",
162
+ "`[UNREALISTISCH], [ASYMETRISCH]`"
163
+ )
164
+
165
+ # ==================== UI-DEFINITION ====================
166
+ def main_ui():
167
+ """Haupt-UI-Funktion (angepasst für 3 Modi)"""
168
+ with gr.Blocks(
169
+ title="AI Image Generator - Mock Version",
170
+ theme=gr.themes.Base(),
171
+ css="""
172
+ .info-box { background: #f8fafc; padding: 8px 12px; border-radius: 6px; margin-bottom: 6px; }
173
+ .model-info-box { background: #e8f4fd; padding: 12px; border-radius: 6px; margin: 10px 0; border-left: 4px solid #2196f3; }
174
+ #generate-button { background-color: #0080FF !important; margin: 20px auto !important; width: 280px; }
175
+ .radio-group { background: #f8f9fa; padding: 15px; border-radius: 8px; margin: 10px 0; }
176
+ """
177
+ ) as demo:
178
+
179
+ with gr.Tab("Text zu Bild"):
180
+ gr.Markdown("## 🎨 Text zu Bild Generator (Mock Version)")
181
+
182
+ with gr.Row():
183
+ with gr.Column(scale=2):
184
+ model_dropdown = gr.Dropdown(
185
+ choices=[
186
+ ("🏠 Stable Diffusion 1.5 (Mock)", "runwayml/stable-diffusion-v1-5"),
187
+ ("👤 Realistic Vision V6.0 (Mock)", "SG161222/Realistic_Vision_V6.0_B1_noVAE")
188
+ ],
189
+ value="runwayml/stable-diffusion-v1-5",
190
+ label="📁 Modellauswahl"
191
+ )
192
+
193
+ model_info_box = gr.Markdown(
194
+ value="<div class='model-info-box'><strong>🏠 Stable Diffusion 1.5 (Mock)</strong><br>Universal model, good all-rounder<br><em>Mock-Einstellungen: 35 Steps, CFG 7.5</em></div>",
195
+ label="Modellinformationen"
196
+ )
197
+
198
+ with gr.Column(scale=3):
199
+ txt_input = gr.Textbox(
200
+ placeholder="z.B. ultra realistic mountain landscape at sunrise...",
201
+ lines=3,
202
+ label="🎯 Prompt (Englisch)",
203
+ value="beautiful landscape sunset mountains"
204
+ )
205
+
206
+ with gr.Row():
207
+ with gr.Column():
208
+ txt_steps = gr.Slider(
209
+ minimum=10, maximum=100, value=35, step=1,
210
+ label="⚙️ Inferenz-Schritte"
211
+ )
212
+ with gr.Column():
213
+ txt_guidance = gr.Slider(
214
+ minimum=1.0, maximum=20.0, value=7.5, step=0.5,
215
+ label="🎛️ Prompt-Stärke (CFG Scale)"
216
+ )
217
+
218
+ status_output = gr.Markdown(
219
+ value="",
220
+ elem_classes="status-message"
221
+ )
222
+
223
+ generate_btn = gr.Button("🚀 Mock-Bild generieren", variant="primary", elem_id="generate-button")
224
+
225
+ with gr.Row():
226
+ txt_output = gr.Image(
227
+ label="🖼️ Generiertes Mock-Bild",
228
+ show_download_button=True,
229
+ type="pil",
230
+ height=400
231
+ )
232
+
233
+ # Event-Handler
234
+ model_dropdown.change(
235
+ fn=mock_update_model_settings,
236
+ inputs=[model_dropdown],
237
+ outputs=[txt_steps, txt_guidance, model_info_box]
238
+ )
239
+
240
+ generate_btn.click(
241
+ fn=mock_text_to_image,
242
+ inputs=[txt_input, model_dropdown, txt_steps, txt_guidance],
243
+ outputs=[txt_output, status_output],
244
+ concurrency_limit=1
245
+ )
246
+
247
+ with gr.Tab("Bild zu Bild"):
248
+ gr.Markdown("## 🖼️ Bild zu Bild Transformation (Mock Version)")
249
+
250
+ with gr.Row():
251
+ with gr.Column():
252
+ img_input = gr.Image(
253
+ type="pil",
254
+ label="📤 Eingabebild",
255
+ height=300,
256
+ sources=["upload"],
257
+ elem_id="image-upload"
258
+ )
259
+ with gr.Column():
260
+ preview_output = gr.Image(
261
+ label="🎯 Mock-Live-Vorschau",
262
+ height=300,
263
+ interactive=False
264
+ )
265
+
266
+ with gr.Row():
267
+ with gr.Column():
268
+ gr.Markdown("### 🎛️ Transformations-Modus")
269
+ mode_radio = gr.Radio(
270
+ choices=[
271
+ ("🌳 Umgebung ändern", "environment_change"),
272
+ ("🎯 Focus verändern", "focus_change"),
273
+ ("👤 Ausschließlich Gesicht", "face_only_change")
274
+ ],
275
+ value="environment_change",
276
+ label="Wähle den Transformationsmodus:",
277
+ elem_classes="radio-group"
278
+ )
279
+
280
+ with gr.Row():
281
+ gr.Markdown("### 📐 Bildelementbereich anpassen")
282
+
283
+ with gr.Row():
284
+ with gr.Column():
285
+ bbox_x1 = gr.Slider(
286
+ label="← Links (x1)",
287
+ minimum=0, maximum=4096, value=100, step=1
288
+ )
289
+ with gr.Column():
290
+ bbox_y1 = gr.Slider(
291
+ label="↑ Oben (y1)",
292
+ minimum=0, maximum=4096, value=100, step=1
293
+ )
294
+ with gr.Row():
295
+ with gr.Column():
296
+ bbox_x2 = gr.Slider(
297
+ label="→ Rechts (x2)",
298
+ minimum=0, maximum=4096, value=300, step=1
299
+ )
300
+ with gr.Column():
301
+ bbox_y2 = gr.Slider(
302
+ label="↓ Unten (y2)",
303
+ minimum=0, maximum=4096, value=300, step=1
304
+ )
305
+
306
+ with gr.Row():
307
+ with gr.Column():
308
+ pos_info = gr.Markdown(
309
+ value="`[STIL-MOTIV], [UMGEBUNG], [VOR/HINTERGRUND]`",
310
+ elem_classes=["info-box"]
311
+ )
312
+ img_prompt = gr.Textbox(
313
+ placeholder="photorealistic coastal beach, keep person unchanged...",
314
+ lines=2,
315
+ label="🎯 Transformations-Prompt",
316
+ value="change background to beach",
317
+ elem_classes=["prompt-box"]
318
+ )
319
+ with gr.Column():
320
+ neg_info = gr.Markdown(
321
+ value="`[GESICHTER/ANATOMIE], [FEHLER]`",
322
+ elem_classes=["info-box"]
323
+ )
324
+ img_neg_prompt = gr.Textbox(
325
+ placeholder="blurry face, deformed anatomy...",
326
+ lines=2,
327
+ label="🚫 Negativ-Prompt",
328
+ value="blurry, ugly",
329
+ elem_classes=["prompt-box"]
330
+ )
331
+
332
+ with gr.Row():
333
+ with gr.Column():
334
+ strength_slider = gr.Slider(
335
+ minimum=0.1, maximum=0.9, value=0.4, step=0.05,
336
+ label="💪 Veränderungs-Stärke"
337
+ )
338
+ with gr.Column():
339
+ img_steps = gr.Slider(
340
+ minimum=10, maximum=45, value=35, step=1,
341
+ label="⚙️ Inferenz-Schritte"
342
+ )
343
+ with gr.Column():
344
+ img_guidance = gr.Slider(
345
+ minimum=1.0, maximum=15.0, value=7.5, step=0.5,
346
+ label="🎛️ Prompt-Stärke"
347
+ )
348
+
349
+ gr.Markdown("### 📋 Hinweise:\n• **Mock-Version** für UI-Testing\n• **Keine echte KI-Verarbeitung**\n• **Teste alle UI-Elemente**")
350
+
351
+ transform_btn = gr.Button("🔄 Mock-Bild transformieren", variant="primary")
352
+
353
+ with gr.Row():
354
+ img_output = gr.Image(
355
+ label="✨ Transformiertes Mock-Bild",
356
+ show_download_button=True,
357
+ type="pil",
358
+ height=400
359
+ )
360
+
361
+ with gr.Row():
362
+ sam_raw_mask_output = gr.Image(
363
+ label="🔍 SAM-Rohmaske (Mock)",
364
+ type="pil",
365
+ height=250,
366
+ show_download_button=False
367
+ )
368
+ processed_mask_output = gr.Image(
369
+ label="🛠️ Nachbearbeitete Maske (Mock)",
370
+ type="pil",
371
+ height=250,
372
+ show_download_button=False
373
+ )
374
+
375
+ with gr.Row():
376
+ pose_map_output = gr.Image(
377
+ label="🎭 Pose/Depth Map (Mock)",
378
+ type="pil",
379
+ height=250,
380
+ show_download_button=False
381
+ )
382
+ canny_map_output = gr.Image(
383
+ label="📐 Canny Edge Map (Mock)",
384
+ type="pil",
385
+ height=250,
386
+ show_download_button=False
387
+ )
388
+
389
+ # Event-Handler
390
+ img_input.upload(
391
+ fn=mock_process_image_upload,
392
+ inputs=[img_input],
393
+ outputs=[preview_output, bbox_x1, bbox_y1, bbox_x2, bbox_y2]
394
+ ).then(
395
+ fn=mock_update_slider_for_image,
396
+ inputs=[img_input],
397
+ outputs=[bbox_x1, bbox_y1, bbox_x2, bbox_y2]
398
+ )
399
+
400
+ coordinate_inputs = [img_input, bbox_x1, bbox_y1, bbox_x2, bbox_y2, mode_radio]
401
+
402
+ for slider in [bbox_x1, bbox_y1, bbox_x2, bbox_y2]:
403
+ slider.release(
404
+ fn=mock_update_live_preview,
405
+ inputs=coordinate_inputs,
406
+ outputs=preview_output
407
+ )
408
+
409
+ mode_radio.change(
410
+ fn=mock_update_info,
411
+ inputs=[mode_radio],
412
+ outputs=[pos_info, neg_info]
413
+ ).then(
414
+ fn=mock_update_live_preview,
415
+ inputs=coordinate_inputs,
416
+ outputs=preview_output
417
+ )
418
+
419
+ transform_btn.click(
420
+ fn=mock_img_to_image,
421
+ inputs=[
422
+ img_input, img_prompt, img_neg_prompt,
423
+ strength_slider, img_steps, img_guidance,
424
+ mode_radio, bbox_x1, bbox_y1, bbox_x2, bbox_y2
425
+ ],
426
+ outputs=[img_output, sam_raw_mask_output, processed_mask_output,
427
+ pose_map_output, canny_map_output],
428
+ concurrency_limit=1
429
+ )
430
+
431
+ return demo
432
+
433
+ if __name__ == "__main__":
434
+ demo = main_ui()
435
+ demo.launch(server_name="0.0.0.0", server_port=7860)