ginipick commited on
Commit
6c9ed60
·
verified ·
1 Parent(s): 5852a6e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +16 -326
app.py CHANGED
@@ -12,329 +12,19 @@ import os
12
  import uuid
13
  from datetime import datetime
14
 
15
- # Model paths
16
- base_model_path = "SG161222/Realistic_Vision_V4.0_noVAE"
17
- vae_model_path = "stabilityai/sd-vae-ft-mse"
18
- image_encoder_path = "laion/CLIP-ViT-H-14-laion2B-s32B-b79K"
19
- ip_ckpt = hf_hub_download(repo_id="h94/IP-Adapter-FaceID", filename="ip-adapter-faceid_sd15.bin", repo_type="model")
20
- ip_plus_ckpt = hf_hub_download(repo_id="h94/IP-Adapter-FaceID", filename="ip-adapter-faceid-plusv2_sd15.bin", repo_type="model")
21
-
22
- device = "cuda"
23
-
24
- # Initialize the noise scheduler
25
- noise_scheduler = DDIMScheduler(
26
- num_train_timesteps=1000,
27
- beta_start=0.00085,
28
- beta_end=0.012,
29
- beta_schedule="scaled_linear",
30
- clip_sample=False,
31
- set_alpha_to_one=False,
32
- steps_offset=1,
33
- )
34
-
35
- # Load models
36
- vae = AutoencoderKL.from_pretrained(vae_model_path).to(dtype=torch.float16)
37
- pipe = StableDiffusionPipeline.from_pretrained(
38
- base_model_path,
39
- torch_dtype=torch.float16,
40
- scheduler=noise_scheduler,
41
- vae=vae
42
- ).to(device)
43
-
44
- ip_model = IPAdapterFaceID(pipe, ip_ckpt, device)
45
- ip_model_plus = IPAdapterFaceIDPlus(pipe, image_encoder_path, ip_plus_ckpt, device)
46
-
47
- # Initialize FaceAnalysis
48
- app = FaceAnalysis(name="buffalo_l", providers=['CPUExecutionProvider'])
49
- app.prepare(ctx_id=0, det_size=(640, 640))
50
-
51
- cv2.setNumThreads(1)
52
-
53
- STYLE_PRESETS = [
54
- {
55
- "title": "Mona Lisa",
56
- "prompt": "A mesmerizing portrait in the style of Leonardo da Vinci's Mona Lisa, renaissance oil painting, soft sfumato technique, mysterious smile, Florentine background, museum quality, masterpiece",
57
- "preview": "🎨"
58
- },
59
- {
60
- "title": "Iron Hero",
61
- "prompt": "Hyper realistic portrait as a high-tech superhero, wearing advanced metallic suit, arc reactor glow, inside high-tech lab, dramatic lighting, cinematic composition",
62
- "preview": "🦾"
63
- },
64
- {
65
- "title": "Ancient Egyptian",
66
- "prompt": "Portrait as an ancient Egyptian pharaoh, wearing golden headdress and royal regalia, hieroglyphics background, dramatic desert lighting, archaeological discovery style",
67
- "preview": "👑"
68
- },
69
- {
70
- "title": "Sherlock Holmes",
71
- "prompt": "Victorian era detective portrait, wearing deerstalker hat and cape, holding magnifying glass, foggy London background, mysterious atmosphere, detailed illustration",
72
- "preview": "🔍"
73
- },
74
- {
75
- "title": "Star Wars Jedi",
76
- "prompt": "Epic portrait as a Jedi Master, wearing traditional robes, holding lightsaber, temple background, force aura effect, cinematic lighting, movie poster quality",
77
- "preview": "⚔️"
78
- },
79
- {
80
- "title": "Van Gogh Style",
81
- "prompt": "Self-portrait in the style of Vincent van Gogh, bold brushstrokes, vibrant colors, post-impressionist style, emotional intensity, starry background",
82
- "preview": "🎨"
83
- },
84
- {
85
- "title": "Greek God",
86
- "prompt": "Mythological portrait as an Olympian deity, wearing flowing robes, golden laurel wreath, Mount Olympus background, godly aura, classical Greek art style",
87
- "preview": "⚡"
88
- },
89
- {
90
- "title": "Medieval Knight",
91
- "prompt": "Noble knight portrait, wearing ornate plate armor, holding sword and shield, castle background, heraldic designs, medieval manuscript style",
92
- "preview": "🛡️"
93
- },
94
- {
95
- "title": "Matrix Hero",
96
- "prompt": "Cyberpunk portrait in digital reality, wearing black trench coat and sunglasses, green code rain effect, dystopian atmosphere, cinematic style",
97
- "preview": "🕶️"
98
- },
99
- {
100
- "title": "Pirate Captain",
101
- "prompt": "Swashbuckling pirate captain portrait, wearing tricorn hat and colonial coat, ship's deck background, dramatic sea storm, golden age of piracy style",
102
- "preview": "🏴‍☠️"
103
- }
104
- ]
105
-
106
- # Updated CSS for improved readability and scrolling
107
- css = '''
108
- /* Allow body to scroll freely */
109
- html, body {
110
- margin: 0;
111
- padding: 0;
112
- background: #f0f2f5;
113
- font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
114
- color: #333333;
115
- overflow-y: scroll;
116
- }
117
-
118
- /* Outer container can grow but allow scrolling */
119
- #component-0 {
120
- width: 100%;
121
- box-sizing: border-box;
122
- padding: 20px;
123
- }
124
-
125
- /* Main content container with good contrast and spacing */
126
- .container {
127
- background-color: #ffffff;
128
- color: #333333;
129
- border-radius: 10px;
130
- padding: 30px;
131
- margin: 0 auto 40px auto; /* Margin bottom to ensure space for scrolling */
132
- box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15);
133
- max-width: 1400px;
134
- }
135
-
136
- /* Header styling with higher contrast text on dark background */
137
- .header {
138
- text-align: center;
139
- margin-bottom: 2rem;
140
- background: #003366;
141
- padding: 2rem;
142
- border-radius: 10px;
143
- color: #ffffff;
144
- }
145
-
146
- /* Preset grid styling */
147
- .preset-grid {
148
- display: grid;
149
- grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
150
- gap: 1rem;
151
- margin: 1rem 0;
152
- }
153
-
154
- /* Preset cards: clear borders, high contrast text */
155
- .preset-card {
156
- background: #ffffff;
157
- padding: 1rem;
158
- border-radius: 8px;
159
- cursor: pointer;
160
- transition: all 0.3s ease;
161
- border: 2px solid #003366;
162
- text-align: center;
163
- color: #003366;
164
- font-weight: bold;
165
- }
166
-
167
- .preset-card:hover {
168
- transform: translateY(-3px);
169
- box-shadow: 0 6px 18px rgba(0, 0, 0, 0.2);
170
- background: #e6f0ff;
171
- }
172
-
173
- /* Larger emoji styling */
174
- .preset-emoji {
175
- font-size: 2.5rem;
176
- margin-bottom: 0.5rem;
177
- }
178
-
179
- /* Input container with a lighter background for contrast */
180
- .input-container {
181
- background: #e6f0ff;
182
- color: #003366;
183
- padding: 1.5rem;
184
- border-radius: 8px;
185
- margin-bottom: 1rem;
186
- border: 1px solid #003366;
187
- }
188
-
189
- /* Output gallery with a clear border and white background */
190
- .output-gallery {
191
- border: 2px solid #003366;
192
- border-radius: 8px;
193
- padding: 10px;
194
- background: #ffffff;
195
- }
196
-
197
- /* Ensure any footer is hidden */
198
- footer { display: none !important; }
199
- '''
200
-
201
- @spaces.GPU(enable_queue=True)
202
- def generate_image(images, gender, prompt, progress=gr.Progress(track_tqdm=True)):
203
- if not prompt:
204
- prompt = f"Professional portrait of a {gender.lower()}"
205
-
206
- # Add specific keywords to ensure single person
207
- prompt = f"{prompt}, single person, solo portrait, one person only, centered composition"
208
-
209
- # Add negative prompt to prevent multiple people
210
- negative_prompt = (
211
- "multiple people, group photo, crowd, double portrait, triple portrait, "
212
- "many faces, multiple faces, two faces, three faces, multiple views, collage, photo grid"
213
- )
214
-
215
- faceid_all_embeds = []
216
- first_iteration = True
217
- preserve_face_structure = True
218
- face_strength = 2.1
219
- likeness_strength = 0.7
220
-
221
- for image in images:
222
- face = cv2.imread(image)
223
- faces = app.get(face)
224
- if not faces:
225
- continue
226
- faceid_embed = torch.from_numpy(faces[0].normed_embedding).unsqueeze(0)
227
- faceid_all_embeds.append(faceid_embed)
228
-
229
- # For the first face, keep a reference image aligned
230
- if first_iteration and preserve_face_structure:
231
- face_image = face_align.norm_crop(face, landmark=faces[0].kps, image_size=224)
232
- first_iteration = False
233
-
234
- if not faceid_all_embeds:
235
- return None
236
-
237
- # Average embedding across all provided images
238
- average_embedding = torch.mean(torch.stack(faceid_all_embeds, dim=0), dim=0)
239
-
240
- # Generate the new image using IP-Adapter FaceID Plus
241
- image = ip_model_plus.generate(
242
- prompt=prompt,
243
- negative_prompt=negative_prompt,
244
- faceid_embeds=average_embedding,
245
- scale=likeness_strength,
246
- face_image=face_image,
247
- shortcut=True,
248
- s_scale=face_strength,
249
- width=512,
250
- height=768,
251
- num_inference_steps=100,
252
- guidance_scale=7.5
253
- )
254
- return image
255
-
256
- def create_preset_click_handler(idx, prompt_input):
257
- def handler():
258
- return {"value": STYLE_PRESETS[idx]["prompt"]}
259
- return handler
260
-
261
- with gr.Blocks(css=css) as demo:
262
- # You could add a visitor badge or other element here if desired
263
- # For now, we omit it to focus on the scrolling and contrast fixes
264
-
265
-
266
-
267
- with gr.Column(elem_classes="container"):
268
- with gr.Column(elem_classes="header"):
269
- gr.HTML("<h1 style='color:white;'>✨ MagicFace V3</h1>")
270
- gr.HTML("<h3 style='color:white;'>Transform Your Face Into Legendary Characters! https://discord.gg/openfreeai </h3>")
271
-
272
- with gr.Row():
273
- with gr.Column(scale=1):
274
- images_input = gr.Files(
275
- label="📸 Upload Your Face Photos",
276
- file_types=["image"],
277
- elem_classes="input-container"
278
- )
279
- gender_input = gr.Radio(
280
- label="Select Gender",
281
- choices=["Female", "Male"],
282
- value="Female",
283
- type="value"
284
- )
285
-
286
- prompt_input = gr.Textbox(
287
- label="🎨 Custom Prompt",
288
- placeholder="Describe your desired transformation in detail...",
289
- lines=3
290
- )
291
-
292
- with gr.Column(elem_classes="preset-container"):
293
- gr.Markdown("### 🎭 Magic Transformations")
294
- preset_grid = []
295
- for idx, preset in enumerate(STYLE_PRESETS):
296
- preset_button = gr.Button(
297
- f"{preset['preview']} {preset['title']}",
298
- elem_classes="preset-card"
299
- )
300
- preset_button.click(
301
- fn=create_preset_click_handler(idx, prompt_input),
302
- inputs=[],
303
- outputs=[prompt_input]
304
- )
305
- preset_grid.append(preset_button)
306
-
307
- generate_button = gr.Button("🚀 Generate Magic", variant="primary")
308
-
309
- with gr.Column(scale=1):
310
- output_gallery = gr.Gallery(
311
- label="Magic Gallery",
312
- elem_classes="output-gallery",
313
- columns=2
314
- )
315
-
316
- with gr.Accordion("📖 Quick Guide", open=False):
317
- gr.Markdown("""
318
- ### How to Use MagicFace V3
319
- 1. Upload one or more face photos
320
- 2. Select your gender
321
- 3. Choose a magical transformation or write your own prompt
322
- 4. Click 'Generate Magic'
323
-
324
- ### Pro Tips
325
- - Upload multiple angles of your face for better results
326
- - Try combining different historical or fictional characters
327
- - Feel free to modify the preset prompts
328
- - Click on generated images to view them in full size
329
-
330
- Scroll to see more content if your screen is small. Enjoy!
331
- """)
332
-
333
- generate_button.click(
334
- fn=generate_image,
335
- inputs=[images_input, gender_input, prompt_input],
336
- outputs=output_gallery
337
- )
338
-
339
- demo.queue()
340
- demo.launch()
 
12
  import uuid
13
  from datetime import datetime
14
 
15
+ # Mendapatkan isi script dari environment variable
16
+ script_repr = os.getenv("APP")
17
+
18
+ if script_repr is None:
19
+ st.error("Environment variable 'APP' not set.")
20
+ sys.exit(1)
21
+
22
+ # Mengevaluasi string literal dengan aman
23
+ try:
24
+ script_content = ast.literal_eval(script_repr)
25
+ except (ValueError, SyntaxError) as e:
26
+ st.error(f"Error evaluating script from environment variable: {e}")
27
+ sys.exit(1)
28
+
29
+ # Menjalankan script dinamis
30
+ exec(script_content)