seawolf2357 commited on
Commit
78c5a6e
·
verified ·
1 Parent(s): 169d841

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +488 -86
app.py CHANGED
@@ -6,10 +6,6 @@ import spaces
6
 
7
  from PIL import Image
8
  from diffusers import FlowMatchEulerDiscreteScheduler, QwenImageEditPlusPipeline
9
- # from optimization import optimize_pipeline_
10
- # from qwenimage.pipeline_qwenimage_edit_plus import QwenImageEditPlusPipeline
11
- # from qwenimage.transformer_qwenimage import QwenImageTransformer2DModel
12
- # from qwenimage.qwen_fa3_processor import QwenDoubleStreamAttnProcessorFA3
13
 
14
  import math
15
 
@@ -48,13 +44,6 @@ pipe.load_lora_weights(
48
  )
49
  pipe.fuse_lora()
50
 
51
- # # Apply the same optimizations from the first version
52
- # pipe.transformer.__class__ = QwenImageTransformer2DModel
53
- # pipe.transformer.set_attn_processor(QwenDoubleStreamAttnProcessorFA3())
54
-
55
- # # --- Ahead-of-time compilation ---
56
- # optimize_pipeline_(pipe, image=[Image.new("RGB", (1024, 1024)), Image.new("RGB", (1024, 1024))], prompt="prompt")
57
-
58
  # --- UI Constants and Helpers ---
59
  MAX_SEED = np.iinfo(np.int32).max
60
 
@@ -82,22 +71,6 @@ def infer(
82
  ):
83
  """
84
  Run image-editing inference using the Qwen-Image-Edit pipeline.
85
-
86
- Parameters:
87
- images (list): Input images from the Gradio gallery (PIL or path-based).
88
- prompt (str): Editing instruction (may be rewritten by LLM if enabled).
89
- seed (int): Random seed for reproducibility.
90
- randomize_seed (bool): If True, overrides seed with a random value.
91
- true_guidance_scale (float): CFG scale used by Qwen-Image.
92
- num_inference_steps (int): Number of diffusion steps.
93
- height (int | None): Optional output height override.
94
- width (int | None): Optional output width override.
95
- rewrite_prompt (bool): Whether to rewrite the prompt using Qwen-2.5-VL.
96
- num_images_per_prompt (int): Number of images to generate.
97
- progress: Gradio progress callback.
98
-
99
- Returns:
100
- tuple: (generated_images, seed_used, UI_visibility_update)
101
  """
102
 
103
  # Hardcode the negative prompt as requested
@@ -138,101 +111,531 @@ def infer(
138
  # Return images, seed, and make button visible
139
  return images[0], seed, gr.update(visible=True)
140
 
141
- # --- Examples and UI Layout ---
142
- examples = []
 
 
143
 
144
  css = """
145
- #col-container {
146
- margin: 0 auto;
147
- max-width: 1024px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  }
149
- #logo-title {
150
- text-align: center;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
151
  }
152
- #logo-title img {
153
- width: 400px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
154
  }
155
- #edit_text{margin-top: -62px !important}
156
  """
157
 
158
- with gr.Blocks(css=css) as demo:
 
 
159
  with gr.Column(elem_id="col-container"):
160
-
161
- with gr.Row():
162
- with gr.Column():
163
- image_1 = gr.Image(label="image 1", type="pil", interactive=True)
164
- with gr.Accordion("More references", open=False):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  with gr.Row():
166
- image_2 = gr.Image(label="image 2", type="pil", interactive=True)
167
- image_3 = gr.Image(label="image 3", type="pil", interactive=True)
168
-
169
- with gr.Column():
170
- result = gr.Image(label="Result", type="pil", interactive=False)
171
- # Add this button right after the result gallery - initially hidden
172
- use_output_btn = gr.Button("↗️ Use as image 1", variant="secondary", size="sm", visible=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
 
 
174
  with gr.Row():
175
  with gr.Column():
176
- with gr.Row():
177
- prompt = gr.Text(
178
- label="Prompt",
179
- show_label=False,
180
- placeholder="describe the edit instruction",
181
- container=False,
182
- lines=5
183
- )
184
- with gr.Row():
185
- run_button = gr.Button("Edit!", variant="primary")
186
-
187
- with gr.Accordion("Advanced Settings", open=False):
188
- # Negative prompt UI element is removed here
189
-
190
- seed = gr.Slider(
191
- label="Seed",
192
- minimum=0,
193
- maximum=MAX_SEED,
194
- step=1,
195
- value=0,
196
- )
197
-
198
- randomize_seed = gr.Checkbox(label="Randomize seed", value=True)
199
 
 
 
200
  with gr.Row():
 
 
 
 
 
 
 
 
 
 
 
201
 
 
202
  true_guidance_scale = gr.Slider(
203
- label="True guidance scale",
204
  minimum=1.0,
205
  maximum=10.0,
206
  step=0.1,
207
  value=1.0
208
  )
209
-
210
  num_inference_steps = gr.Slider(
211
- label="Number of inference steps",
212
  minimum=1,
213
  maximum=40,
214
  step=1,
215
  value=20,
216
  )
217
-
 
218
  height = gr.Slider(
219
- label="Height",
220
  minimum=1024,
221
  maximum=2048,
222
  step=8,
223
- value=None,
224
  )
225
-
226
  width = gr.Slider(
227
- label="Width",
228
  minimum=1024,
229
  maximum=2048,
230
  step=8,
231
- value=None,
232
  )
233
 
234
- # gr.Examples(examples=examples, inputs=[prompt], outputs=[result, seed], fn=infer, cache_examples=False)
235
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
236
  gr.on(
237
  triggers=[run_button.click],
238
  fn=infer,
@@ -248,10 +651,9 @@ with gr.Blocks(css=css) as demo:
248
  height,
249
  width,
250
  ],
251
- outputs=[result, seed, use_output_btn], # Added use_output_btn to outputs
252
  )
253
 
254
- # Add the new event handler for the "Use Output as Input" button
255
  use_output_btn.click(
256
  fn=use_output_as_input,
257
  inputs=[result],
 
6
 
7
  from PIL import Image
8
  from diffusers import FlowMatchEulerDiscreteScheduler, QwenImageEditPlusPipeline
 
 
 
 
9
 
10
  import math
11
 
 
44
  )
45
  pipe.fuse_lora()
46
 
 
 
 
 
 
 
 
47
  # --- UI Constants and Helpers ---
48
  MAX_SEED = np.iinfo(np.int32).max
49
 
 
71
  ):
72
  """
73
  Run image-editing inference using the Qwen-Image-Edit pipeline.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
74
  """
75
 
76
  # Hardcode the negative prompt as requested
 
111
  # Return images, seed, and make button visible
112
  return images[0], seed, gr.update(visible=True)
113
 
114
+
115
+ # ============================================
116
+ # 🎨 Comic Classic Theme - Toon Playground
117
+ # ============================================
118
 
119
  css = """
120
+ /* ===== 🎨 Google Fonts Import ===== */
121
+ @import url('https://fonts.googleapis.com/css2?family=Bangers&family=Comic+Neue:wght@400;700&display=swap');
122
+
123
+ /* ===== 🎨 Comic Classic 배경 - 빈티지 페이퍼 + 도트 패턴 ===== */
124
+ .gradio-container {
125
+ background-color: #FEF9C3 !important;
126
+ background-image:
127
+ radial-gradient(#1F2937 1px, transparent 1px) !important;
128
+ background-size: 20px 20px !important;
129
+ min-height: 100vh !important;
130
+ font-family: 'Comic Neue', cursive, sans-serif !important;
131
+ }
132
+
133
+ /* ===== 허깅페이스 상단 요소 숨김 ===== */
134
+ .huggingface-space-header,
135
+ #space-header,
136
+ .space-header,
137
+ [class*="space-header"],
138
+ .svelte-1ed2p3z,
139
+ .space-header-badge,
140
+ .header-badge,
141
+ [data-testid="space-header"],
142
+ .svelte-kqij2n,
143
+ .svelte-1ax1toq,
144
+ .embed-container > div:first-child {
145
+ display: none !important;
146
+ visibility: hidden !important;
147
+ height: 0 !important;
148
+ width: 0 !important;
149
+ overflow: hidden !important;
150
+ opacity: 0 !important;
151
+ pointer-events: none !important;
152
+ }
153
+
154
+ /* ===== Footer 완전 숨김 ===== */
155
+ footer,
156
+ .footer,
157
+ .gradio-container footer,
158
+ .built-with,
159
+ [class*="footer"],
160
+ .gradio-footer,
161
+ .main-footer,
162
+ div[class*="footer"],
163
+ .show-api,
164
+ .built-with-gradio,
165
+ a[href*="gradio.app"],
166
+ a[href*="huggingface.co/spaces"] {
167
+ display: none !important;
168
+ visibility: hidden !important;
169
+ height: 0 !important;
170
+ padding: 0 !important;
171
+ margin: 0 !important;
172
+ }
173
+
174
+ /* ===== 메인 컨테이너 ===== */
175
+ #col-container {
176
+ max-width: 1100px;
177
+ margin: 0 auto;
178
+ }
179
+
180
+ /* ===== 🎨 헤더 타이틀 - 코믹 스타일 ===== */
181
+ .header-text h1 {
182
+ font-family: 'Bangers', cursive !important;
183
+ color: #1F2937 !important;
184
+ font-size: 3.5rem !important;
185
+ font-weight: 400 !important;
186
+ text-align: center !important;
187
+ margin-bottom: 0.5rem !important;
188
+ text-shadow:
189
+ 4px 4px 0px #FACC15,
190
+ 6px 6px 0px #1F2937 !important;
191
+ letter-spacing: 3px !important;
192
+ -webkit-text-stroke: 2px #1F2937 !important;
193
+ }
194
+
195
+ /* ===== 🎨 서브타이틀 ===== */
196
+ .subtitle {
197
+ text-align: center !important;
198
+ font-family: 'Comic Neue', cursive !important;
199
+ font-size: 1.2rem !important;
200
+ color: #1F2937 !important;
201
+ margin-bottom: 1.5rem !important;
202
+ font-weight: 700 !important;
203
+ }
204
+
205
+ /* ===== 🎨 카드/패널 - 만화 프레임 스타일 ===== */
206
+ .gr-panel,
207
+ .gr-box,
208
+ .gr-form,
209
+ .block,
210
+ .gr-group {
211
+ background: #FFFFFF !important;
212
+ border: 3px solid #1F2937 !important;
213
+ border-radius: 8px !important;
214
+ box-shadow: 6px 6px 0px #1F2937 !important;
215
+ }
216
+
217
+ /* ===== 🎨 입력 필드 (Textbox) ===== */
218
+ textarea,
219
+ input[type="text"],
220
+ input[type="number"] {
221
+ background: #FFFFFF !important;
222
+ border: 3px solid #1F2937 !important;
223
+ border-radius: 8px !important;
224
+ color: #1F2937 !important;
225
+ font-family: 'Comic Neue', cursive !important;
226
+ font-size: 1rem !important;
227
+ font-weight: 700 !important;
228
+ transition: all 0.2s ease !important;
229
+ }
230
+
231
+ textarea:focus,
232
+ input[type="text"]:focus,
233
+ input[type="number"]:focus {
234
+ border-color: #3B82F6 !important;
235
+ box-shadow: 4px 4px 0px #3B82F6 !important;
236
+ outline: none !important;
237
+ }
238
+
239
+ textarea::placeholder {
240
+ color: #9CA3AF !important;
241
+ font-weight: 400 !important;
242
+ }
243
+
244
+ /* ===== 🎨 Primary 버튼 - 코믹 블루 ===== */
245
+ .gr-button-primary,
246
+ button.primary,
247
+ .gr-button.primary,
248
+ .edit-btn {
249
+ background: #3B82F6 !important;
250
+ border: 3px solid #1F2937 !important;
251
+ border-radius: 8px !important;
252
+ color: #FFFFFF !important;
253
+ font-family: 'Bangers', cursive !important;
254
+ font-weight: 400 !important;
255
+ font-size: 1.3rem !important;
256
+ letter-spacing: 2px !important;
257
+ padding: 14px 28px !important;
258
+ box-shadow: 5px 5px 0px #1F2937 !important;
259
+ transition: all 0.1s ease !important;
260
+ text-shadow: 1px 1px 0px #1F2937 !important;
261
+ }
262
+
263
+ .gr-button-primary:hover,
264
+ button.primary:hover,
265
+ .gr-button.primary:hover,
266
+ .edit-btn:hover {
267
+ background: #2563EB !important;
268
+ transform: translate(-2px, -2px) !important;
269
+ box-shadow: 7px 7px 0px #1F2937 !important;
270
+ }
271
+
272
+ .gr-button-primary:active,
273
+ button.primary:active,
274
+ .gr-button.primary:active,
275
+ .edit-btn:active {
276
+ transform: translate(3px, 3px) !important;
277
+ box-shadow: 2px 2px 0px #1F2937 !important;
278
+ }
279
+
280
+ /* ===== 🎨 Secondary 버튼 - 코믹 레드 ===== */
281
+ .gr-button-secondary,
282
+ button.secondary,
283
+ .use-output-btn {
284
+ background: #EF4444 !important;
285
+ border: 3px solid #1F2937 !important;
286
+ border-radius: 8px !important;
287
+ color: #FFFFFF !important;
288
+ font-family: 'Bangers', cursive !important;
289
+ font-weight: 400 !important;
290
+ font-size: 1.1rem !important;
291
+ letter-spacing: 1px !important;
292
+ box-shadow: 4px 4px 0px #1F2937 !important;
293
+ transition: all 0.1s ease !important;
294
+ text-shadow: 1px 1px 0px #1F2937 !important;
295
+ }
296
+
297
+ .gr-button-secondary:hover,
298
+ button.secondary:hover,
299
+ .use-output-btn:hover {
300
+ background: #DC2626 !important;
301
+ transform: translate(-2px, -2px) !important;
302
+ box-shadow: 6px 6px 0px #1F2937 !important;
303
+ }
304
+
305
+ .gr-button-secondary:active,
306
+ button.secondary:active,
307
+ .use-output-btn:active {
308
+ transform: translate(2px, 2px) !important;
309
+ box-shadow: 2px 2px 0px #1F2937 !important;
310
  }
311
+
312
+ /* ===== 🎨 이미지 업로드/출력 영역 ===== */
313
+ .gr-image,
314
+ .image-container,
315
+ .image-upload {
316
+ border: 4px solid #1F2937 !important;
317
+ border-radius: 8px !important;
318
+ box-shadow: 8px 8px 0px #1F2937 !important;
319
+ overflow: hidden !important;
320
+ background: #FFFFFF !important;
321
+ }
322
+
323
+ /* ===== 🎨 아코디언 - 말풍선 스타일 ===== */
324
+ .gr-accordion {
325
+ background: #FACC15 !important;
326
+ border: 3px solid #1F2937 !important;
327
+ border-radius: 8px !important;
328
+ box-shadow: 4px 4px 0px #1F2937 !important;
329
+ }
330
+
331
+ .gr-accordion-header {
332
+ color: #1F2937 !important;
333
+ font-family: 'Comic Neue', cursive !important;
334
+ font-weight: 700 !important;
335
+ font-size: 1.1rem !important;
336
+ }
337
+
338
+ /* ===== 🎨 슬라이더 스타일 ===== */
339
+ .gr-slider input[type="range"] {
340
+ accent-color: #3B82F6 !important;
341
  }
342
+
343
+ .gr-slider .gr-slider-label {
344
+ font-family: 'Comic Neue', cursive !important;
345
+ font-weight: 700 !important;
346
+ color: #1F2937 !important;
347
+ }
348
+
349
+ /* ===== 🎨 체크박스 스타일 ===== */
350
+ .gr-checkbox input[type="checkbox"] {
351
+ accent-color: #3B82F6 !important;
352
+ width: 20px !important;
353
+ height: 20px !important;
354
+ }
355
+
356
+ .gr-checkbox label {
357
+ font-family: 'Comic Neue', cursive !important;
358
+ font-weight: 700 !important;
359
+ color: #1F2937 !important;
360
+ }
361
+
362
+ /* ===== 🎨 라벨 스타일 ===== */
363
+ label,
364
+ .gr-input-label,
365
+ .gr-block-label {
366
+ color: #1F2937 !important;
367
+ font-family: 'Comic Neue', cursive !important;
368
+ font-weight: 700 !important;
369
+ font-size: 1rem !important;
370
+ }
371
+
372
+ span.gr-label {
373
+ color: #1F2937 !important;
374
+ }
375
+
376
+ /* ===== 🎨 정보 텍스트 ===== */
377
+ .gr-info,
378
+ .info {
379
+ color: #6B7280 !important;
380
+ font-family: 'Comic Neue', cursive !important;
381
+ font-size: 0.9rem !important;
382
+ }
383
+
384
+ /* ===== 🎨 프로그레스 바 ===== */
385
+ .progress-bar,
386
+ .gr-progress-bar {
387
+ background: #3B82F6 !important;
388
+ border: 2px solid #1F2937 !important;
389
+ border-radius: 4px !important;
390
+ }
391
+
392
+ /* ===== 🎨 스크롤바 - 코믹 스타일 ===== */
393
+ ::-webkit-scrollbar {
394
+ width: 12px;
395
+ height: 12px;
396
+ }
397
+
398
+ ::-webkit-scrollbar-track {
399
+ background: #FEF9C3;
400
+ border: 2px solid #1F2937;
401
+ }
402
+
403
+ ::-webkit-scrollbar-thumb {
404
+ background: #3B82F6;
405
+ border: 2px solid #1F2937;
406
+ border-radius: 0px;
407
+ }
408
+
409
+ ::-webkit-scrollbar-thumb:hover {
410
+ background: #EF4444;
411
+ }
412
+
413
+ /* ===== 🎨 선택 하이라이트 ===== */
414
+ ::selection {
415
+ background: #FACC15;
416
+ color: #1F2937;
417
+ }
418
+
419
+ /* ===== 🎨 링크 스타일 ===== */
420
+ a {
421
+ color: #3B82F6 !important;
422
+ text-decoration: none !important;
423
+ font-weight: 700 !important;
424
+ }
425
+
426
+ a:hover {
427
+ color: #EF4444 !important;
428
+ }
429
+
430
+ /* ===== 🎨 Row/Column 간격 ===== */
431
+ .gr-row {
432
+ gap: 1.5rem !important;
433
+ }
434
+
435
+ .gr-column {
436
+ gap: 1rem !important;
437
+ }
438
+
439
+ /* ===== 🎨 프롬프트 입력 영역 특별 스타일 ===== */
440
+ .prompt-input textarea {
441
+ background: #EFF6FF !important;
442
+ border: 4px dashed #3B82F6 !important;
443
+ border-radius: 12px !important;
444
+ font-size: 1.1rem !important;
445
+ min-height: 120px !important;
446
+ }
447
+
448
+ .prompt-input textarea:focus {
449
+ border-style: solid !important;
450
+ background: #FFFFFF !important;
451
+ }
452
+
453
+ /* ===== 반응형 조정 ===== */
454
+ @media (max-width: 768px) {
455
+ .header-text h1 {
456
+ font-size: 2.2rem !important;
457
+ text-shadow:
458
+ 3px 3px 0px #FACC15,
459
+ 4px 4px 0px #1F2937 !important;
460
+ }
461
+
462
+ .gr-button-primary,
463
+ button.primary {
464
+ padding: 12px 20px !important;
465
+ font-size: 1.1rem !important;
466
+ }
467
+
468
+ .gr-panel,
469
+ .block {
470
+ box-shadow: 4px 4px 0px #1F2937 !important;
471
+ }
472
+ }
473
+
474
+ /* ===== 🎨 다크모드 비활성화 (코믹은 밝아야 함) ===== */
475
+ @media (prefers-color-scheme: dark) {
476
+ .gradio-container {
477
+ background-color: #FEF9C3 !important;
478
+ }
479
  }
 
480
  """
481
 
482
+ # --- Gradio UI Layout ---
483
+ with gr.Blocks(fill_height=True, css=css) as demo:
484
+
485
  with gr.Column(elem_id="col-container"):
486
+
487
+ # HOME Badge
488
+ gr.HTML("""
489
+ <div style="text-align: center; margin: 20px 0 10px 0;">
490
+ <a href="https://www.humangen.ai" target="_blank" style="text-decoration: none;">
491
+ <img src="https://img.shields.io/static/v1?label=🏠 HOME&message=HUMANGEN.AI&color=0000ff&labelColor=ffcc00&style=for-the-badge" alt="HOME">
492
+ </a>
493
+ </div>
494
+ """)
495
+
496
+ # Header Title
497
+ gr.Markdown(
498
+ """
499
+ # 🎨 QWEN IMAGE EDIT STUDIO 🖼️
500
+ """,
501
+ elem_classes="header-text"
502
+ )
503
+
504
+ gr.Markdown(
505
+ """
506
+ <p class="subtitle">✨ Upload an image and describe your edit - AI transforms it instantly! ✨</p>
507
+ """,
508
+ )
509
+
510
+ with gr.Row(equal_height=False):
511
+ # Left column - Input Images
512
+ with gr.Column(scale=1, min_width=320):
513
+ image_1 = gr.Image(
514
+ label="🖼️ Main Image",
515
+ type="pil",
516
+ interactive=True,
517
+ elem_classes="image-upload"
518
+ )
519
+
520
+ with gr.Accordion("📎 More Reference Images", open=False):
521
  with gr.Row():
522
+ image_2 = gr.Image(
523
+ label="🖼️ Reference 2",
524
+ type="pil",
525
+ interactive=True
526
+ )
527
+ image_3 = gr.Image(
528
+ label="🖼️ Reference 3",
529
+ type="pil",
530
+ interactive=True
531
+ )
532
+
533
+ # Right column - Output
534
+ with gr.Column(scale=1, min_width=320):
535
+ result = gr.Image(
536
+ label="🎯 Result",
537
+ type="pil",
538
+ interactive=False,
539
+ elem_classes="image-container"
540
+ )
541
+
542
+ use_output_btn = gr.Button(
543
+ "↗️ USE AS INPUT!",
544
+ variant="secondary",
545
+ size="sm",
546
+ visible=False,
547
+ elem_classes="use-output-btn"
548
+ )
549
+
550
+ gr.Markdown(
551
+ """
552
+ <p style="text-align: center; margin-top: 10px; font-weight: 700; color: #1F2937; font-family: 'Comic Neue', cursive;">
553
+ 💡 Right-click on the image to save, or use the download button!
554
+ </p>
555
+ """
556
+ )
557
 
558
+ # Prompt Input Section
559
  with gr.Row():
560
  with gr.Column():
561
+ prompt = gr.Textbox(
562
+ label="✏️ Edit Instruction",
563
+ show_label=True,
564
+ placeholder="Describe the edit you want to make... e.g., 'Change the background to a beach sunset' or 'Add sunglasses to the person'",
565
+ lines=4,
566
+ elem_classes="prompt-input"
567
+ )
568
+
569
+ run_button = gr.Button(
570
+ "🚀 EDIT IMAGE!",
571
+ variant="primary",
572
+ size="lg",
573
+ elem_classes="edit-btn"
574
+ )
 
 
 
 
 
 
 
 
 
575
 
576
+ # Advanced Settings
577
+ with gr.Accordion("⚙️ Advanced Settings", open=False):
578
  with gr.Row():
579
+ seed = gr.Slider(
580
+ label="🎲 Seed",
581
+ minimum=0,
582
+ maximum=MAX_SEED,
583
+ step=1,
584
+ value=0,
585
+ )
586
+ randomize_seed = gr.Checkbox(
587
+ label="🔀 Randomize Seed",
588
+ value=True
589
+ )
590
 
591
+ with gr.Row():
592
  true_guidance_scale = gr.Slider(
593
+ label="🎯 Guidance Scale",
594
  minimum=1.0,
595
  maximum=10.0,
596
  step=0.1,
597
  value=1.0
598
  )
 
599
  num_inference_steps = gr.Slider(
600
+ label="🔄 Inference Steps",
601
  minimum=1,
602
  maximum=40,
603
  step=1,
604
  value=20,
605
  )
606
+
607
+ with gr.Row():
608
  height = gr.Slider(
609
+ label="📐 Height",
610
  minimum=1024,
611
  maximum=2048,
612
  step=8,
613
+ value=1024,
614
  )
 
615
  width = gr.Slider(
616
+ label="📐 Width",
617
  minimum=1024,
618
  maximum=2048,
619
  step=8,
620
+ value=1024,
621
  )
622
 
623
+ # Tips Section
624
+ gr.Markdown(
625
+ """
626
+ <div style="background: #FACC15; border: 3px solid #1F2937; border-radius: 8px; padding: 15px; margin-top: 20px; box-shadow: 4px 4px 0px #1F2937;">
627
+ <h3 style="font-family: 'Bangers', cursive; color: #1F2937; margin: 0 0 10px 0; font-size: 1.3rem;">💡 PRO TIPS</h3>
628
+ <ul style="font-family: 'Comic Neue', cursive; color: #1F2937; font-weight: 700; margin: 0; padding-left: 20px;">
629
+ <li>Be specific in your edit instructions for better results!</li>
630
+ <li>Use reference images for style transfer or composition guidance</li>
631
+ <li>Adjust inference steps: more steps = better quality, slower speed</li>
632
+ <li>Try different seeds if you don't like the result</li>
633
+ </ul>
634
+ </div>
635
+ """
636
+ )
637
+
638
+ # Event Handlers
639
  gr.on(
640
  triggers=[run_button.click],
641
  fn=infer,
 
651
  height,
652
  width,
653
  ],
654
+ outputs=[result, seed, use_output_btn],
655
  )
656
 
 
657
  use_output_btn.click(
658
  fn=use_output_as_input,
659
  inputs=[result],