Jonny001 commited on
Commit
52b3f9a
·
verified ·
1 Parent(s): a7f634c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -189
app.py CHANGED
@@ -12,17 +12,19 @@ from roop.processors.frame.core import get_frame_processors_modules
12
  from roop.utilities import normalize_output_path
13
  import os
14
  from PIL import Image
15
- import time
16
 
17
  def swap_face_image(source_file, target_file, doFaceEnhancer):
18
  source_path = "input.jpg"
19
  target_path = "target.jpg"
20
- output_path = f"output_{int(time.time())}.jpg"
21
 
22
  # Save source and target images
23
  Image.fromarray(source_file).save(source_path)
24
  Image.fromarray(target_file).save(target_path)
25
 
 
 
 
26
  # Set globals
27
  roop.globals.source_path = source_path
28
  roop.globals.target_path = target_path
@@ -35,225 +37,137 @@ def swap_face_image(source_file, target_file, doFaceEnhancer):
35
  roop.globals.execution_providers = decode_execution_providers(["cuda"])
36
  roop.globals.execution_threads = suggest_execution_threads()
37
 
 
 
38
  # Ensure processors are ready
39
  for frame_processor in get_frame_processors_modules(roop.globals.frame_processors):
40
  if not frame_processor.pre_check():
41
  return None
42
 
43
  start()
44
-
45
  # Return output image
46
- if os.path.exists(output_path):
47
- return Image.open(output_path)
48
- else:
49
- return None
50
 
51
- # Custom CSS for clean UI
52
  custom_css = """
53
- :root {
54
- --neon-primary: #00d9ff;
55
- --neon-secondary: #ff00c8;
56
- --dark-bg: #0a0e17;
57
- --dark-surface: #131a2a;
58
- --dark-card: #1a243b;
59
- --dark-border: #253556;
60
- --text-primary: #ffffff;
61
- --text-secondary: #a0b3e5;
62
- }
63
-
64
- body {
65
- background-color: var(--dark-bg);
66
- color: var(--text-primary);
67
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
68
- }
69
-
70
  #title {
71
  text-align: center;
72
  font-weight: 800;
73
  font-size: 2.5em;
74
- margin: 0;
75
- padding: 20px 0;
76
- color: var(--neon-primary);
77
- text-shadow: 0 0 10px rgba(0, 217, 255, 0.7);
78
- }
79
-
80
- .gradio-container {
81
- background: var(--dark-bg) !important;
82
- color: var(--text-primary) !important;
83
  }
84
 
85
- .column {
86
- background: var(--dark-card) !important;
87
- border-radius: 8px;
88
- padding: 20px;
89
- border: 1px solid var(--dark-border);
90
- }
91
-
92
- .image-container {
93
- border: 2px dashed var(--dark-border);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  border-radius: 8px;
95
- padding: 15px;
96
- background: var(--dark-surface);
97
- min-height: 300px;
98
- display: flex;
99
- flex-direction: column;
100
  }
101
 
102
- .image-container:hover {
103
- border-color: var(--neon-primary);
104
- }
105
-
106
- .primary-button {
107
- background: linear-gradient(45deg, var(--neon-primary), var(--neon-secondary)) !important;
108
- color: white !important;
109
- font-weight: bold !important;
110
  border: none !important;
111
- border-radius: 6px !important;
112
- padding: 12px 24px !important;
113
- margin-top: 15px;
114
- }
115
-
116
- .primary-button:hover {
117
- background: linear-gradient(45deg, var(--neon-secondary), var(--neon-primary)) !important;
118
- }
119
-
120
- label {
121
- color: var(--text-primary) !important;
122
  }
123
 
124
- .gr-box {
125
- background: var(--dark-surface) !important;
126
- color: var(--text-primary) !important;
127
- border: 1px solid var(--dark-border) !important;
128
- border-radius: 6px !important;
129
  }
130
 
131
- .gr-markdown h3 {
132
- color: var(--text-primary) !important;
133
- margin-top: 0;
134
- margin-bottom: 15px;
135
- }
136
-
137
- .download-button {
138
- background: linear-gradient(45deg, #9600ff, var(--neon-secondary)) !important;
139
- color: white !important;
140
- font-weight: bold !important;
141
- border: none !important;
142
- border-radius: 6px !important;
143
- padding: 12px 24px !important;
144
- margin-top: 15px;
145
- }
146
-
147
- .download-button:hover {
148
- background: linear-gradient(45deg, var(--neon-secondary), #9600ff) !important;
149
- }
150
-
151
- .image-preview {
152
- flex-grow: 1;
153
- display: flex;
154
- align-items: center;
155
- justify-content: center;
156
- min-height: 250px;
157
- }
158
-
159
- .checkbox-container {
160
- display: flex;
161
- align-items: center;
162
- justify-content: center;
163
- margin: 15px 0;
164
  }
165
 
166
- .checkbox-container label {
167
- margin-left: 10px;
168
- font-size: 1.1em;
 
 
169
  }
170
  """
171
 
172
- # Global variable to track the latest output file
173
- latest_output = None
174
-
175
  # Gradio UI
176
- with gr.Blocks(css=custom_css, theme=gr.themes.Default(primary_hue="blue")) as demo:
177
  gr.HTML("""
178
- <div id="title">AI FACE SWAP</div>
 
 
 
179
  """)
180
 
181
- with gr.Row():
182
- with gr.Column(scale=1):
183
- with gr.Row():
184
- with gr.Column(elem_classes="image-container"):
185
- gr.Markdown("### SOURCE")
186
- source_image = gr.Image(
187
- label="",
188
- type="numpy",
189
- height=250,
190
- elem_classes="image-preview"
191
- )
192
-
193
- with gr.Column(elem_classes="image-container"):
194
- gr.Markdown("### TARGET")
195
- target_image = gr.Image(
196
- label="",
197
- type="numpy",
198
- height=250,
199
- elem_classes="image-preview"
200
- )
201
 
202
- with gr.Row(elem_classes="checkbox-container"):
203
- face_enhancer = gr.Checkbox(
204
- label="Enhance Face",
205
- value=True
206
- )
207
-
208
  with gr.Row():
209
- submit = gr.Button(
210
- "PROCESS",
211
- variant="primary",
212
- elem_classes="primary-button",
213
- scale=1
214
- )
215
-
216
- with gr.Column(scale=1):
217
- with gr.Column(elem_classes="image-container"):
218
- gr.Markdown("### RESULT")
219
- output_image = gr.Image(
220
- label="",
221
- type="pil",
222
- height=250,
223
- elem_classes="image-preview"
224
  )
225
- download_btn = gr.Button("DOWNLOAD", visible=False, elem_classes="download-button")
226
-
227
- # Process the face swap
228
- def process_faces(source_file, target_file, doFaceEnhancer):
229
- global latest_output
230
- result = swap_face_image(source_file, target_file, doFaceEnhancer)
231
- if result is not None:
232
- # Store the output path for download
233
- output_files = [f for f in os.listdir('.') if f.startswith('output_') and f.endswith('.jpg')]
234
- if output_files:
235
- output_files.sort(key=lambda x: os.path.getctime(x), reverse=True)
236
- latest_output = output_files[0]
237
- return result, gr.Button(visible=True)
238
- return None, gr.Button(visible=False)
239
-
240
- submit.click(
241
- fn=process_faces,
242
- inputs=[source_image, target_image, face_enhancer],
243
- outputs=[output_image, download_btn]
244
- )
245
-
246
- # Handle download
247
- def download_output():
248
- global latest_output
249
- if latest_output and os.path.exists(latest_output):
250
- return latest_output
251
- return None
252
-
253
- download_btn.click(
254
- fn=download_output,
255
- outputs=gr.File(label="Download Result")
256
- )
257
-
258
- if __name__ == "__main__":
259
- demo.launch(share=True, server_name="0.0.0.0")
 
12
  from roop.utilities import normalize_output_path
13
  import os
14
  from PIL import Image
 
15
 
16
  def swap_face_image(source_file, target_file, doFaceEnhancer):
17
  source_path = "input.jpg"
18
  target_path = "target.jpg"
19
+ output_path = "output.jpg"
20
 
21
  # Save source and target images
22
  Image.fromarray(source_file).save(source_path)
23
  Image.fromarray(target_file).save(target_path)
24
 
25
+ print("source_path: ", source_path)
26
+ print("target_path: ", target_path)
27
+
28
  # Set globals
29
  roop.globals.source_path = source_path
30
  roop.globals.target_path = target_path
 
37
  roop.globals.execution_providers = decode_execution_providers(["cuda"])
38
  roop.globals.execution_threads = suggest_execution_threads()
39
 
40
+ print("start process", source_path, target_path, output_path)
41
+
42
  # Ensure processors are ready
43
  for frame_processor in get_frame_processors_modules(roop.globals.frame_processors):
44
  if not frame_processor.pre_check():
45
  return None
46
 
47
  start()
48
+
49
  # Return output image
50
+ return Image.open(output_path)
 
 
 
51
 
52
+ # Custom CSS for AI styling
53
  custom_css = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  #title {
55
  text-align: center;
56
  font-weight: 800;
57
  font-size: 2.5em;
58
+ background: linear-gradient(90deg, #FF9A8B 0%, #FF6A88 55%, #FF99AC 100%);
59
+ -webkit-background-clip: text;
60
+ -webkit-text-fill-color: transparent;
61
+ margin-bottom: 0.5em;
 
 
 
 
 
62
  }
63
 
64
+ #subtitle {
65
+ text-align: center;
66
+ margin-bottom: 2em;
67
+ color: #94a3b8;
68
+ }
69
+
70
+ .status-indicator {
71
+ display: inline-block;
72
+ width: 12px;
73
+ height: 12px;
74
+ border-radius: 50%;
75
+ margin-right: 8px;
76
+ background: #10B981;
77
+ box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.3);
78
+ animation: pulse 2s infinite;
79
+ }
80
+
81
+ @keyframes pulse {
82
+ 0% {
83
+ box-shadow: 0 0 0 0 rgba(16, 185, 129, 0.7);
84
+ }
85
+ 70% {
86
+ box-shadow: 0 0 0 10px rgba(16, 185, 129, 0);
87
+ }
88
+ 100% {
89
+ box-shadow: 0 0 0 0 rgba(16, 185, 129, 0);
90
+ }
91
+ }
92
+
93
+ .enhancer-label {
94
+ background: rgba(255, 255, 255, 0.1);
95
+ padding: 10px;
96
  border-radius: 8px;
97
+ border-left: 4px solid #FF6A88;
 
 
 
 
98
  }
99
 
100
+ .gr-button {
101
+ background: linear-gradient(90deg, #FF9A8B 0%, #FF6A88 55%, #FF99AC 100%) !important;
 
 
 
 
 
 
102
  border: none !important;
103
+ font-weight: 600 !important;
 
 
 
 
 
 
 
 
 
 
104
  }
105
 
106
+ .gr-button:hover {
107
+ box-shadow: 0 5px 15px rgba(255, 106, 136, 0.4) !important;
 
 
 
108
  }
109
 
110
+ .container {
111
+ max-width: 1200px;
112
+ margin: 0 auto;
113
+ padding: 20px;
114
+ background: rgba(15, 23, 42, 0.7);
115
+ border-radius: 16px;
116
+ backdrop-filter: blur(10px);
117
+ border: 1px solid rgba(255, 255, 255, 0.1);
118
+ box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  }
120
 
121
+ .column {
122
+ background: rgba(255, 255, 255, 0.05);
123
+ border-radius: 12px;
124
+ padding: 20px;
125
+ border: 1px solid rgba(255, 255, 255, 0.1);
126
  }
127
  """
128
 
 
 
 
129
  # Gradio UI
130
+ with gr.Blocks(css=custom_css, theme=gr.themes.Soft(primary_hue="pink")) as demo:
131
  gr.HTML("""
132
+ <div style="text-align: center;">
133
+ <h1 id="title">AI Face Swapper</h1>
134
+ <p id="subtitle">Seamlessly swap faces between images with advanced AI technology</p>
135
+ </div>
136
  """)
137
 
138
+ with gr.Row(elem_classes="container"):
139
+ with gr.Column(scale=1, elem_classes="column"):
140
+ gr.HTML("""
141
+ <div style="display: flex; align-items: center; margin-bottom: 20px;">
142
+ <div class="status-indicator"></div>
143
+ <span style="font-weight: 500;">System Online</span>
144
+ </div>
145
+ """)
146
+
147
+ gr.Markdown("### Source Image")
148
+ source_image = gr.Image(label="Upload source face", type="numpy", height=250)
149
+
150
+ gr.Markdown("### Target Image")
151
+ target_image = gr.Image(label="Upload target face", type="numpy", height=250)
 
 
 
 
 
 
152
 
 
 
 
 
 
 
153
  with gr.Row():
154
+ face_enhancer = gr.Checkbox(
155
+ label="Enable Face Enhancer",
156
+ info="Improve face quality after swapping",
157
+ elem_classes="enhancer-label"
 
 
 
 
 
 
 
 
 
 
 
158
  )
159
+
160
+ submit = gr.Button("Swap Faces", variant="primary", size="lg")
161
+
162
+ with gr.Column(scale=1, elem_classes="column"):
163
+ gr.Markdown("### Result")
164
+ output_image = gr.Image(label="Swapped Face Result", height=500)
165
+ gr.Markdown("""
166
+ <div style="margin-top: 20px; padding: 15px; background: rgba(16, 185, 129, 0.1); border-radius: 8px; border-left: 4px solid #10B981;">
167
+ <small>Tip: For best results, use frontal face images with good lighting.</small>
168
+ </div>
169
+ """)
170
+
171
+ submit.click(swap_face_image, inputs=[source_image, target_image, face_enhancer], outputs=output_image)
172
+
173
+ demo.launch()