MogensR commited on
Commit
b47d3c0
Β·
1 Parent(s): 4d9f1d8

Rename ui_components.py to ui/ui_components.py

Browse files
ui_components.py β†’ ui/ui_components.py RENAMED
@@ -3,9 +3,12 @@
3
  UI Components for BackgroundFX Pro
4
  - Layout only (no heavy logic here)
5
  - Delegates callbacks to ui/callbacks.py
 
6
  """
7
 
 
8
  import gradio as gr
 
9
  from ui.callbacks import (
10
  cb_load_models,
11
  cb_process_video,
@@ -14,10 +17,9 @@
14
  cb_clear,
15
  cb_generate_bg,
16
  cb_use_gen_bg,
17
- cb_video_changed,
18
- cb_custom_bg_preview,
19
  )
20
- from utils.bg_generator import generate_ai_background
21
 
22
  CSS = """
23
  :root { --radius: 16px; }
@@ -29,11 +31,26 @@
29
  .footer-note { opacity: 0.7; font-size: 12px; }
30
  .sm { font-size: 13px; opacity: 0.85; }
31
  #statusbox { min-height: 120px; }
 
32
  """
33
 
 
 
 
 
 
 
 
 
 
 
34
  def create_interface() -> gr.Blocks:
35
- with gr.Blocks(title="🎬 BackgroundFX Pro", css=CSS, analytics_enabled=False,
36
- theme=gr.themes.Soft()) as demo:
 
 
 
 
37
 
38
  # ---------- HERO ----------
39
  with gr.Row(elem_id="hero"):
@@ -46,29 +63,56 @@ def create_interface() -> gr.Blocks:
46
  # ---------- QUICK START ----------
47
  with gr.Tab("🏁 Quick Start"):
48
  with gr.Row():
 
49
  with gr.Column(scale=1):
50
- video = gr.Video(label="Upload Video")
 
 
 
 
 
 
 
51
  bg_style = gr.Dropdown(
52
  label="Background Style",
53
- choices=["minimalist", "office", "studio", "ocean", "forest",
54
- "sunset", "royal", "warm", "cool"],
55
  value="minimalist",
 
 
 
 
 
 
 
 
 
 
 
 
56
  )
57
- custom_bg = gr.File(label="Custom Background (Optional)", file_types=["image"])
58
 
59
  with gr.Accordion("Advanced", open=False):
60
  use_two_stage = gr.Checkbox(label="Use Two-Stage Pipeline", value=False)
61
  chroma_preset = gr.Dropdown(
62
- label="Chroma Preset", choices=["standard"], value="standard"
 
 
 
 
 
 
 
 
 
 
63
  )
64
- preview_mask = gr.Checkbox(label="Preview Mask (no audio remix)", value=False)
65
- preview_greenscreen = gr.Checkbox(label="Preview Greenscreen (no audio remix)", value=False)
66
 
67
  with gr.Row():
68
  btn_load = gr.Button("πŸ”„ Load Models", variant="secondary")
69
  btn_run = gr.Button("🎬 Process Video", variant="primary")
70
  btn_cancel = gr.Button("⏹️ Cancel", variant="secondary")
71
 
 
72
  with gr.Column(scale=1):
73
  out_video = gr.Video(label="Processed Output", interactive=False)
74
  statusbox = gr.Textbox(label="Status", lines=8, elem_id="statusbox")
@@ -80,7 +124,11 @@ def create_interface() -> gr.Blocks:
80
  with gr.Tab("🧠 AI Background (Lightweight)"):
81
  with gr.Row():
82
  with gr.Column(scale=1):
83
- prompt = gr.Textbox(label="Describe vibe", value="modern office")
 
 
 
 
84
  with gr.Row():
85
  gen_width = gr.Slider(640, 1920, value=1280, step=10, label="Width")
86
  gen_height = gr.Slider(360, 1080, value=720, step=10, label="Height")
@@ -92,7 +140,7 @@ def create_interface() -> gr.Blocks:
92
  btn_gen_bg = gr.Button("✨ Generate Background", variant="primary")
93
 
94
  with gr.Column(scale=1):
95
- gen_preview = gr.Image(label="Generated Background", interactive=False)
96
  gen_path = gr.Textbox(label="Saved Path", interactive=False)
97
  use_gen_as_custom = gr.Button("πŸ“Œ Use As Custom Background", variant="secondary")
98
 
@@ -103,9 +151,13 @@ def create_interface() -> gr.Blocks:
103
  model_status = gr.JSON(label="Model Status")
104
  with gr.Column(scale=1, elem_classes=["card"]):
105
  cache_status = gr.JSON(label="Cache / System Status")
106
- gr.Markdown("<div class='footer-note'>If models fail to load, fallbacks keep the UI responsive. Check logs for details.</div>")
 
 
 
107
 
108
- # ---------- CALLBACKS WIRING ----------
 
109
  btn_load.click(cb_load_models, outputs=statusbox)
110
  btn_run.click(
111
  cb_process_video,
@@ -116,6 +168,7 @@ def create_interface() -> gr.Blocks:
116
  btn_refresh.click(cb_status, outputs=[model_status, cache_status])
117
  btn_clear.click(cb_clear, outputs=[out_video, statusbox, gen_preview, gen_path])
118
 
 
119
  btn_gen_bg.click(
120
  cb_generate_bg,
121
  inputs=[prompt, gen_width, gen_height, bokeh, vignette, contrast],
@@ -123,8 +176,11 @@ def create_interface() -> gr.Blocks:
123
  )
124
  use_gen_as_custom.click(cb_use_gen_bg, inputs=[gen_path], outputs=[custom_bg])
125
 
126
- # Previews
127
- video.change(cb_video_changed, inputs=[video], outputs=[]) # can later output a preview img
128
- custom_bg.change(cb_custom_bg_preview, inputs=[custom_bg], outputs=[])
 
 
 
129
 
130
  return demo
 
3
  UI Components for BackgroundFX Pro
4
  - Layout only (no heavy logic here)
5
  - Delegates callbacks to ui/callbacks.py
6
+ - Adds previews for uploaded video (first frame) and custom background image
7
  """
8
 
9
+ from __future__ import annotations
10
  import gradio as gr
11
+
12
  from ui.callbacks import (
13
  cb_load_models,
14
  cb_process_video,
 
17
  cb_clear,
18
  cb_generate_bg,
19
  cb_use_gen_bg,
20
+ cb_video_changed, # should return a preview image (or None)
21
+ cb_custom_bg_preview, # should return a preview image (or None)
22
  )
 
23
 
24
  CSS = """
25
  :root { --radius: 16px; }
 
31
  .footer-note { opacity: 0.7; font-size: 12px; }
32
  .sm { font-size: 13px; opacity: 0.85; }
33
  #statusbox { min-height: 120px; }
34
+ .preview-img { border-radius: var(--radius); border: 1px solid rgba(0,0,0,.08); }
35
  """
36
 
37
+ # NOTE: Keep these keys in sync with utils/cv_processing.PROFESSIONAL_BACKGROUNDS
38
+ _BG_CHOICES = [
39
+ "minimalist",
40
+ "office_modern",
41
+ "studio_blue",
42
+ "studio_green",
43
+ "warm_gradient",
44
+ "tech_dark",
45
+ ]
46
+
47
  def create_interface() -> gr.Blocks:
48
+ with gr.Blocks(
49
+ title="🎬 BackgroundFX Pro",
50
+ css=CSS,
51
+ analytics_enabled=False,
52
+ theme=gr.themes.Soft()
53
+ ) as demo:
54
 
55
  # ---------- HERO ----------
56
  with gr.Row(elem_id="hero"):
 
63
  # ---------- QUICK START ----------
64
  with gr.Tab("🏁 Quick Start"):
65
  with gr.Row():
66
+ # Left column: inputs & controls
67
  with gr.Column(scale=1):
68
+ video = gr.Video(label="Upload Video", interactive=True)
69
+ # Small live preview (first frame)
70
+ video_preview = gr.Image(
71
+ label="Video Preview (first frame)",
72
+ interactive=False,
73
+ elem_classes=["preview-img"]
74
+ )
75
+
76
  bg_style = gr.Dropdown(
77
  label="Background Style",
78
+ choices=_BG_CHOICES,
 
79
  value="minimalist",
80
+ info="Matches built-in PROFESSIONAL_BACKGROUNDS keys."
81
+ )
82
+ custom_bg = gr.File(
83
+ label="Custom Background (Optional)",
84
+ file_types=["image"],
85
+ interactive=True
86
+ )
87
+ # Custom background preview
88
+ custom_bg_preview_img = gr.Image(
89
+ label="Custom Background Preview",
90
+ interactive=False,
91
+ elem_classes=["preview-img"]
92
  )
 
93
 
94
  with gr.Accordion("Advanced", open=False):
95
  use_two_stage = gr.Checkbox(label="Use Two-Stage Pipeline", value=False)
96
  chroma_preset = gr.Dropdown(
97
+ label="Chroma Preset",
98
+ choices=["standard"],
99
+ value="standard"
100
+ )
101
+ preview_mask = gr.Checkbox(
102
+ label="Preview Mask (no audio remix)",
103
+ value=False
104
+ )
105
+ preview_greenscreen = gr.Checkbox(
106
+ label="Preview Greenscreen (no audio remix)",
107
+ value=False
108
  )
 
 
109
 
110
  with gr.Row():
111
  btn_load = gr.Button("πŸ”„ Load Models", variant="secondary")
112
  btn_run = gr.Button("🎬 Process Video", variant="primary")
113
  btn_cancel = gr.Button("⏹️ Cancel", variant="secondary")
114
 
115
+ # Right column: outputs & status
116
  with gr.Column(scale=1):
117
  out_video = gr.Video(label="Processed Output", interactive=False)
118
  statusbox = gr.Textbox(label="Status", lines=8, elem_id="statusbox")
 
124
  with gr.Tab("🧠 AI Background (Lightweight)"):
125
  with gr.Row():
126
  with gr.Column(scale=1):
127
+ prompt = gr.Textbox(
128
+ label="Describe vibe",
129
+ value="modern office",
130
+ info="Examples: 'modern office', 'soft sunset studio', 'cool tech dark', 'forest ambience'"
131
+ )
132
  with gr.Row():
133
  gen_width = gr.Slider(640, 1920, value=1280, step=10, label="Width")
134
  gen_height = gr.Slider(360, 1080, value=720, step=10, label="Height")
 
140
  btn_gen_bg = gr.Button("✨ Generate Background", variant="primary")
141
 
142
  with gr.Column(scale=1):
143
+ gen_preview = gr.Image(label="Generated Background", interactive=False, elem_classes=["preview-img"])
144
  gen_path = gr.Textbox(label="Saved Path", interactive=False)
145
  use_gen_as_custom = gr.Button("πŸ“Œ Use As Custom Background", variant="secondary")
146
 
 
151
  model_status = gr.JSON(label="Model Status")
152
  with gr.Column(scale=1, elem_classes=["card"]):
153
  cache_status = gr.JSON(label="Cache / System Status")
154
+ gr.Markdown(
155
+ "<div class='footer-note'>If models fail to load, fallbacks keep the UI responsive. "
156
+ "Check logs for details.</div>"
157
+ )
158
 
159
+ # ---------- CALLBACK WIRING ----------
160
+ # Core actions
161
  btn_load.click(cb_load_models, outputs=statusbox)
162
  btn_run.click(
163
  cb_process_video,
 
168
  btn_refresh.click(cb_status, outputs=[model_status, cache_status])
169
  btn_clear.click(cb_clear, outputs=[out_video, statusbox, gen_preview, gen_path])
170
 
171
+ # AI background generation
172
  btn_gen_bg.click(
173
  cb_generate_bg,
174
  inputs=[prompt, gen_width, gen_height, bokeh, vignette, contrast],
 
176
  )
177
  use_gen_as_custom.click(cb_use_gen_bg, inputs=[gen_path], outputs=[custom_bg])
178
 
179
+ # Live previews
180
+ # Expectation:
181
+ # - cb_video_changed(video_path) -> PIL.Image | numpy array | None
182
+ # - cb_custom_bg_preview(file_obj) -> PIL.Image | numpy array | None
183
+ video.change(cb_video_changed, inputs=[video], outputs=[video_preview])
184
+ custom_bg.change(cb_custom_bg_preview, inputs=[custom_bg], outputs=[custom_bg_preview_img])
185
 
186
  return demo