Ephemeral182 commited on
Commit
83ebc4c
Β·
verified Β·
1 Parent(s): 3664d7c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +171 -34
app.py CHANGED
@@ -207,45 +207,182 @@ def generate_poster(
207
  def create_interface():
208
  """Create Gradio interface"""
209
 
210
- with gr.Blocks(
211
- theme=gr.themes.Soft(),
212
- css="""
213
- .preserve-aspect-ratio img {
214
- object-fit: contain !important;
215
- width: auto !important;
216
- max-height: 512px !important;
217
- }
218
- """
219
- ) as demo:
220
- gr.HTML("<div style='text-align: center; width: 100%; margin: 20px 0;'><h1 style='margin: 0; font-size: 2.5em;'>PosterCraft-v1_RL</h1></div>")
221
-
222
- with gr.Row():
223
- with gr.Column(scale=1):
224
- gr.Markdown("### 1. Configuration")
225
- prompt_input = gr.Textbox(label="Prompt", lines=3, placeholder="Enter your creative prompt...")
226
- enable_recap_checkbox = gr.Checkbox(label="Enable Prompt Recap", value=True, info=f"Uses {DEFAULT_QWEN_MODEL_PATH} for rewriting.")
227
-
228
- with gr.Row():
229
- width_input = gr.Slider(label="Width", minimum=256, maximum=2048, value=832, step=64)
230
- height_input = gr.Slider(label="Height", minimum=256, maximum=2048, value=1216, step=64)
231
- gr.Markdown("Tip: Recommended size is 832x1216 for best results.")
232
-
233
- num_inference_steps_input = gr.Slider(label="Inference Steps", minimum=1, maximum=100, value=28, step=1)
234
- guidance_scale_input = gr.Slider(label="Guidance Scale (CFG)", minimum=0.0, maximum=20.0, value=3.5, step=0.1)
235
- seed_number_input = gr.Number(label="Seed", value=-1, minimum=-1, step=1, info="Leave blank or set to -1 for a random seed.")
236
- generate_button = gr.Button("Generate Image", variant="primary")
237
-
238
- with gr.Column(scale=1):
239
- gr.Markdown("### 2. Results")
240
- image_output = gr.Image(label="Generated Image", type="pil", show_download_button=True, height=512, container=False, elem_classes=["preserve-aspect-ratio"])
241
- recapped_prompt_output = gr.Textbox(label="Final Prompt Used", lines=5, interactive=False)
242
- status_output = gr.Textbox(label="Status Log", lines=4, interactive=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
243
 
244
  inputs_list = [
245
  prompt_input, enable_recap_checkbox, height_input, width_input,
246
  num_inference_steps_input, guidance_scale_input, seed_number_input
247
  ]
248
- outputs_list = [image_output, recapped_prompt_output, status_output]
249
 
250
  generate_button.click(fn=generate_poster, inputs=inputs_list, outputs=outputs_list)
251
 
 
207
  def create_interface():
208
  """Create Gradio interface"""
209
 
210
+ custom_css = """
211
+ .gradio-container {
212
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
213
+ }
214
+
215
+ .contain {
216
+ background: rgba(255, 255, 255, 0.95);
217
+ border-radius: 15px;
218
+ padding: 25px;
219
+ margin: 15px auto;
220
+ max-width: 1200px;
221
+ box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
222
+ }
223
+
224
+ .title-container {
225
+ text-align: center;
226
+ margin-bottom: 25px;
227
+ padding: 20px;
228
+ background: linear-gradient(135deg, #ff6b6b, #ee5a52);
229
+ border-radius: 12px;
230
+ box-shadow: 0 5px 20px rgba(255, 107, 107, 0.3);
231
+ }
232
+
233
+ .title-container h1 {
234
+ color: white;
235
+ font-size: 2.2em;
236
+ font-weight: bold;
237
+ margin: 0;
238
+ text-shadow: 1px 1px 3px rgba(0, 0, 0, 0.3);
239
+ }
240
+
241
+ .section-header {
242
+ background: linear-gradient(135deg, #a8edea, #fed6e3);
243
+ padding: 12px;
244
+ border-radius: 8px;
245
+ margin-bottom: 15px;
246
+ border-left: 4px solid #ff6b6b;
247
+ }
248
+
249
+ .section-header h3 {
250
+ margin: 0;
251
+ color: #333;
252
+ font-weight: 600;
253
+ }
254
+
255
+ .input-group {
256
+ background: rgba(255, 255, 255, 0.8);
257
+ padding: 18px;
258
+ border-radius: 12px;
259
+ margin-bottom: 15px;
260
+ border: 1px solid rgba(0, 0, 0, 0.1);
261
+ box-shadow: 0 3px 12px rgba(0, 0, 0, 0.05);
262
+ }
263
+
264
+ .result-section {
265
+ background: rgba(255, 255, 255, 0.9);
266
+ padding: 18px;
267
+ border-radius: 12px;
268
+ border: 1px solid rgba(0, 0, 0, 0.1);
269
+ box-shadow: 0 3px 12px rgba(0, 0, 0, 0.05);
270
+ }
271
+
272
+ .tip-box {
273
+ background: linear-gradient(135deg, #ffeaa7, #fdcb6e);
274
+ padding: 10px;
275
+ border-radius: 6px;
276
+ margin: 8px 0;
277
+ border-left: 3px solid #f39c12;
278
+ color: #8b4513;
279
+ font-weight: 500;
280
+ }
281
+
282
+ button.primary {
283
+ background: linear-gradient(135deg, #ff6b6b, #ee5a52) !important;
284
+ border: none !important;
285
+ border-radius: 20px !important;
286
+ padding: 12px 25px !important;
287
+ color: white !important;
288
+ font-weight: bold !important;
289
+ font-size: 15px !important;
290
+ box-shadow: 0 5px 15px rgba(255, 107, 107, 0.4) !important;
291
+ transition: all 0.2s ease-in-out;
292
+ }
293
+
294
+ button.primary:hover {
295
+ box-shadow: 0 8px 25px rgba(255, 107, 107, 0.6) !important;
296
+ transform: translateY(-2px);
297
+ opacity: 0.95 !important;
298
+ }
299
+
300
+ .examples .gallery {
301
+ gap: 8px !important;
302
+ }
303
+
304
+ .examples .gallery-item {
305
+ border-radius: 8px !important;
306
+ background-color: #f0f0f0 !important;
307
+ border: 1px solid #ddd !important;
308
+ padding: 10px !important;
309
+ text-align: left !important;
310
+ transition: background-color 0.2s, border-color 0.2s;
311
+ }
312
+
313
+ .examples .gallery-item:hover {
314
+ background-color: #e0e0e0 !important;
315
+ border-color: #ccc !important;
316
+ }
317
+
318
+ .examples .gallery-item span {
319
+ font-size: 14px !important;
320
+ white-space: normal !important;
321
+ width: 100% !important;
322
+ }
323
+
324
+ .image-output-container {
325
+ display: flex;
326
+ justify-content: center;
327
+ align-items: center;
328
+ min-height: 512px;
329
+ background: #f0f2f5;
330
+ border-radius: 12px;
331
+ overflow: hidden;
332
+ }
333
+
334
+ .image-output-container img {
335
+ max-height: 512px;
336
+ max-width: 100%;
337
+ object-fit: contain;
338
+ }
339
+ """
340
+
341
+ with gr.Blocks(theme=gr.themes.Soft(), css=custom_css) as demo:
342
+ with gr.Column(elem_classes="contain"):
343
+ gr.HTML('<div class="title-container"><h1>🎨 PosterCraft-v1.0</h1></div>')
344
+
345
+ with gr.Row(equal_height=False):
346
+ with gr.Column(scale=1, elem_classes="input-group"):
347
+ gr.HTML('<div class="section-header"><h3>βš™οΈ 1. Configuration</h3></div>')
348
+ prompt_input = gr.Textbox(label="πŸ’‘ Prompt", lines=3, placeholder="Enter your creative prompt...")
349
+
350
+ enable_recap_checkbox = gr.Checkbox(label="πŸ”„ Enable Prompt Recap", value=True, info=f"Uses {DEFAULT_QWEN_MODEL_PATH} for rewriting.")
351
+
352
+ gr.Examples(
353
+ examples=[
354
+ ["Urban Canvas Street Art Expo poster with bold graffiti-style lettering and dynamic colorful splashes"],
355
+ ["This poster for 'PixelPlay Retro Game Console' features the console with classic 8-bit game graphics, evoking nostalgia and fun with a vibrant, playful, and retro-gaming aesthetic."],
356
+ ["Poster about Mars Tourism Campaign, text:\"NEXT STOP MARS\\nBOOK YOUR TICKET NOW\", astronaut_on_red_planet, rocket_launch, sunrise_horizon_glow, retro_futurism_style, dust_clouds, panoramic_view, bold_headline_text, sci-fi_palette, highres, 16x9_ratio"],
357
+ ["This intriguing poster for \"CODE OF THE SAMURAI\" presents a stark contrast. On one side, a traditional samurai warrior in full armor, holding a katana, is depicted in a sepia-toned, historical style. On the other side, a futuristic cyborg warrior with glowing blue optics and sleek armor is shown in a cool, modern, digital style. The two figures are back-to-back, divided by a shimmering energy line. The title \"CODE OF THE SAMURAI\" is written in a font that blends traditional Japanese calligraphy with modern digital elements, in a metallic silver, positioned horizontally across the center where the two styles meet. The tagline, \"HONOR IS TIMELESS,\" is in a smaller, clean white sans-serif font at the bottom. The layout highlights the duality and the clash or merging of ancient traditions with future technology."]
358
+ ],
359
+ inputs=[prompt_input],
360
+ label="πŸ“ Example Prompts",
361
+ examples_per_page=5,
362
+ )
363
+
364
+ with gr.Row():
365
+ width_input = gr.Slider(label="πŸ“ Width", minimum=256, maximum=2048, value=832, step=64)
366
+ height_input = gr.Slider(label="πŸ“ Height", minimum=256, maximum=2048, value=1216, step=64)
367
+ gr.HTML('<div class="tip-box">πŸ’‘ Tip: Recommended size is 832x1216 for best results.</div>')
368
+
369
+ num_inference_steps_input = gr.Slider(label="πŸ”„ Inference Steps", minimum=1, maximum=100, value=28, step=1)
370
+ guidance_scale_input = gr.Slider(label="🎯 Guidance Scale (CFG)", minimum=0.0, maximum=20.0, value=3.5, step=0.1)
371
+ seed_number_input = gr.Number(label="🎲 Seed", value=-1, minimum=-1, step=1, info="Leave blank or set to -1 for a random seed.")
372
+ generate_button = gr.Button("πŸš€ Generate Image", variant="primary")
373
+
374
+ with gr.Column(scale=1, elem_classes="result-section"):
375
+ gr.HTML('<div class="section-header"><h3>🎨 2. Results</h3></div>')
376
+ with gr.Box(elem_classes=["image-output-container"]):
377
+ image_output = gr.Image(label="πŸ–ΌοΈ Generated Image", type="pil", show_download_button=True, show_label=False, elem_classes=["image-output"])
378
+ recapped_prompt_output = gr.Textbox(label="πŸ“ Final Prompt Used", lines=5, interactive=False)
379
+ status_output = gr.Textbox(label="πŸ“Š Status Log", lines=4, interactive=False)
380
 
381
  inputs_list = [
382
  prompt_input, enable_recap_checkbox, height_input, width_input,
383
  num_inference_steps_input, guidance_scale_input, seed_number_input
384
  ]
385
+ outputs_list = [image_output, status_output, recapped_prompt_output]
386
 
387
  generate_button.click(fn=generate_poster, inputs=inputs_list, outputs=outputs_list)
388