Update app.py
Browse files
app.py
CHANGED
@@ -1,22 +1,14 @@
|
|
1 |
import gradio as gr
|
2 |
-
import
|
|
|
3 |
import smtplib
|
4 |
from email.message import EmailMessage
|
5 |
-
from
|
6 |
-
import io
|
7 |
-
|
8 |
-
import torch
|
9 |
-
from diffusers import StableDiffusionPipeline
|
10 |
-
|
11 |
-
device = "cuda" if torch.cuda.is_available() else "cpu"
|
12 |
-
model_id = "nitrosocke/Ghibli-Diffusion"
|
13 |
|
14 |
-
# Load
|
15 |
-
pipe =
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
BACKEND_URL = "https://your-hf-space-url.hf.space/ghibli"
|
20 |
|
21 |
style_prompts = {
|
22 |
"Single Photo With Dhaka Topi - Ghibli Style": "Create a Ghibli-style portrait using the uploaded photo as the person’s face to get a magical Ghibli-style portrait, wearing a traditional Nepali Dhaka topi. The dreamy background features Mount Everest, blooming laliguras flowers, Kathmandu’s Ghanta Ghar tower, elegant Newari window patterns, and colorful Nepali prayer flags waving in the wind. The art should blend Studio Ghibli’s enchanting style with authentic Nepali culture.",
|
@@ -26,72 +18,76 @@ style_prompts = {
|
|
26 |
"Princess Mononoke Wild": "Forest warrior aesthetic, powerful gaze, nature spirit background, strong composition, Ghibli anime style",
|
27 |
"Ghibli Vintage Portrait": "Classic Ghibli portrait, soft facial features, minimal background, vintage anime color palette, watercolor ink"
|
28 |
}
|
|
|
29 |
|
30 |
-
def
|
31 |
-
|
32 |
-
|
33 |
-
|
34 |
-
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
return Image.open(io.BytesIO(response.content))
|
39 |
-
|
40 |
-
def generate_image(image, prompt):
|
41 |
-
return f"Generated Ghibli style image"
|
42 |
|
43 |
-
def
|
44 |
-
|
45 |
-
|
46 |
-
|
47 |
-
|
|
|
|
|
48 |
|
49 |
def send_email(email, image):
|
50 |
msg = EmailMessage()
|
51 |
msg["Subject"] = "Your Ghibli-style Portrait"
|
52 |
msg["From"] = "[email protected]"
|
53 |
msg["To"] = email
|
54 |
-
buf = io.BytesIO()
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
with smtplib.SMTP_SSL("smtp.example.com", 465) as server:
|
60 |
-
server.login("[email protected]", "yourpassword")
|
61 |
-
server.send_message(msg)
|
62 |
return "✅ Sent to email!"
|
63 |
|
64 |
-
with gr.Blocks(
|
65 |
-
gr.
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
|
|
|
|
72 |
|
73 |
with gr.Row():
|
74 |
-
with gr.Column():
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
image_input = gr.Image(
|
82 |
-
email_input = gr.Textbox(label="📧
|
83 |
-
|
84 |
-
|
85 |
-
|
|
|
86 |
status = gr.Textbox(label="Status")
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
|
88 |
-
|
89 |
-
prompt = style_prompts.get(style, list(style_prompts.values())[0])
|
90 |
-
# result = send_to_backend(image, prompt)
|
91 |
-
result = generate_ghibli_style(image, prompt)
|
92 |
-
# send_email(email, result)
|
93 |
-
return result, "✅ Portrait generated"
|
94 |
|
95 |
-
|
|
|
|
|
|
|
|
|
96 |
|
97 |
demo.launch()
|
|
|
1 |
import gradio as gr
|
2 |
+
import torch
|
3 |
+
import io
|
4 |
import smtplib
|
5 |
from email.message import EmailMessage
|
6 |
+
from diffusers import StableDiffusionImg2ImgPipeline
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
|
8 |
+
# Load SD3.5 pipeline
|
9 |
+
pipe = StableDiffusionImg2ImgPipeline.from_pretrained(
|
10 |
+
"stabilityai/stable-diffusion-3.5-large", torch_dtype=torch.bfloat16
|
11 |
+
).to("cuda")
|
|
|
|
|
12 |
|
13 |
style_prompts = {
|
14 |
"Single Photo With Dhaka Topi - Ghibli Style": "Create a Ghibli-style portrait using the uploaded photo as the person’s face to get a magical Ghibli-style portrait, wearing a traditional Nepali Dhaka topi. The dreamy background features Mount Everest, blooming laliguras flowers, Kathmandu’s Ghanta Ghar tower, elegant Newari window patterns, and colorful Nepali prayer flags waving in the wind. The art should blend Studio Ghibli’s enchanting style with authentic Nepali culture.",
|
|
|
18 |
"Princess Mononoke Wild": "Forest warrior aesthetic, powerful gaze, nature spirit background, strong composition, Ghibli anime style",
|
19 |
"Ghibli Vintage Portrait": "Classic Ghibli portrait, soft facial features, minimal background, vintage anime color palette, watercolor ink"
|
20 |
}
|
21 |
+
sample_keys = list(style_prompts.keys())[:5]
|
22 |
|
23 |
+
def generate_ghibli_style(image, prompt, strength=0.6):
|
24 |
+
with torch.inference_mode():
|
25 |
+
out = pipe(prompt=prompt,
|
26 |
+
image=image,
|
27 |
+
strength=strength,
|
28 |
+
guidance_scale=6.5,
|
29 |
+
num_inference_steps=25).images[0]
|
30 |
+
return out
|
|
|
|
|
|
|
|
|
31 |
|
32 |
+
def process(image, style, email):
|
33 |
+
prompt = style_prompts.get(style, "")
|
34 |
+
result = generate_ghibli_style(image, prompt)
|
35 |
+
email_status = ""
|
36 |
+
if email:
|
37 |
+
email_status = send_email(email, result)
|
38 |
+
return result, "✅ Generated", email_status
|
39 |
|
40 |
def send_email(email, image):
|
41 |
msg = EmailMessage()
|
42 |
msg["Subject"] = "Your Ghibli-style Portrait"
|
43 |
msg["From"] = "[email protected]"
|
44 |
msg["To"] = email
|
45 |
+
buf = io.BytesIO(); image.save(buf, format="PNG"); buf.seek(0)
|
46 |
+
msg.add_attachment(buf.read(), maintype="image", subtype="png", filename="portrait.png")
|
47 |
+
with smtplib.SMTP_SSL("smtp.example.com", 465) as s:
|
48 |
+
s.login("your@email.com", "password")
|
49 |
+
s.send_message(msg)
|
|
|
|
|
|
|
50 |
return "✅ Sent to email!"
|
51 |
|
52 |
+
with gr.Blocks(
|
53 |
+
theme=gr.themes.Soft(primary_hue="emerald", secondary_hue="amber", neutral_hue="stone"),
|
54 |
+
css="""
|
55 |
+
body { font-family: 'Merriweather', serif; background: #f9f5f0; }
|
56 |
+
h1 { color: #2a6f48; font-family: 'Karma', serif; }
|
57 |
+
.sample-btn { margin: 4px; background: #a4c639; color: white; border-radius:8px; }
|
58 |
+
.sample-btn:hover { background: #7fa32c; }
|
59 |
+
"""
|
60 |
+
) as demo:
|
61 |
+
gr.Markdown("## 🌸 Nepali Roots Ghibli Art Booth")
|
62 |
|
63 |
with gr.Row():
|
64 |
+
with gr.Column(scale=1):
|
65 |
+
gr.Markdown("### Choose a Ghibli prompt style:")
|
66 |
+
sample_buttons = []
|
67 |
+
for key in sample_keys:
|
68 |
+
btn = gr.Button(key, elem_classes="sample-btn")
|
69 |
+
sample_buttons.append(btn)
|
70 |
+
style_choice = gr.Dropdown(list(style_prompts.keys()), value=sample_keys[0], label="🎨 Style")
|
71 |
+
image_input = gr.Image(label="📸 Upload or take photo", type="pil", source="upload")
|
72 |
+
email_input = gr.Textbox(label="📧 Email (optional)")
|
73 |
+
generate_button = gr.Button("✨ Generate & Project")
|
74 |
+
|
75 |
+
with gr.Column(scale=1):
|
76 |
+
image_output = gr.Image(label="🌠 Result", show_fullscreen_button=True)
|
77 |
status = gr.Textbox(label="Status")
|
78 |
+
email_status = gr.Textbox(label="Email Status")
|
79 |
+
projector = gr.HTML("", elem_id="projector")
|
80 |
+
|
81 |
+
# sample button callback
|
82 |
+
for btn, key in zip(sample_buttons, sample_keys):
|
83 |
+
btn.click(lambda k=key: gr.update(value=k), inputs=None, outputs=style_choice)
|
84 |
|
85 |
+
generate_button.click(process, [image_input, style_choice, email_input], [image_output, status, email_status])
|
|
|
|
|
|
|
|
|
|
|
86 |
|
87 |
+
# projector link update
|
88 |
+
def projector_link(img):
|
89 |
+
if img is None: return ""
|
90 |
+
return '<a href="#" onclick="window.open(window.images[0].src,\'_blank\')">🔍 Open full-screen on projector</a>'
|
91 |
+
image_output.change(projector_link, inputs=[image_output], outputs=[projector])
|
92 |
|
93 |
demo.launch()
|