Spaces:
Running
on
Zero
Running
on
Zero
Create app.py
Browse files
app.py
ADDED
|
@@ -0,0 +1,463 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import gradio as gr
|
| 2 |
+
import torch
|
| 3 |
+
from diffusers import ZImagePipeline
|
| 4 |
+
import os
|
| 5 |
+
from pathlib import Path
|
| 6 |
+
|
| 7 |
+
# Initialize the pipeline
|
| 8 |
+
print("Loading Z-Image Turbo model...")
|
| 9 |
+
pipe = ZImagePipeline.from_pretrained(
|
| 10 |
+
"Tongyi-MAI/Z-Image-Turbo",
|
| 11 |
+
torch_dtype=torch.bfloat16,
|
| 12 |
+
low_cpu_mem_usage=False,
|
| 13 |
+
)
|
| 14 |
+
|
| 15 |
+
# Move to GPU if available
|
| 16 |
+
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 17 |
+
pipe.to(device)
|
| 18 |
+
|
| 19 |
+
# Optional: Enable Flash Attention for better efficiency
|
| 20 |
+
try:
|
| 21 |
+
pipe.transformer.set_attention_backend("flash")
|
| 22 |
+
print("Flash Attention enabled")
|
| 23 |
+
except:
|
| 24 |
+
print("Flash Attention not available, using default")
|
| 25 |
+
|
| 26 |
+
print("Model loaded successfully!")
|
| 27 |
+
|
| 28 |
+
def generate_image(
|
| 29 |
+
prompt,
|
| 30 |
+
negative_prompt,
|
| 31 |
+
height,
|
| 32 |
+
width,
|
| 33 |
+
num_steps,
|
| 34 |
+
seed,
|
| 35 |
+
progress=gr.Progress(track_tqdm=True)
|
| 36 |
+
):
|
| 37 |
+
"""
|
| 38 |
+
Generate an image using Z-Image Turbo model.
|
| 39 |
+
|
| 40 |
+
Args:
|
| 41 |
+
prompt: Text description of the desired image
|
| 42 |
+
negative_prompt: What to avoid in the image
|
| 43 |
+
height: Image height
|
| 44 |
+
width: Image width
|
| 45 |
+
num_steps: Number of inference steps
|
| 46 |
+
seed: Random seed for reproducibility
|
| 47 |
+
|
| 48 |
+
Returns:
|
| 49 |
+
Generated PIL Image
|
| 50 |
+
"""
|
| 51 |
+
if not prompt.strip():
|
| 52 |
+
raise gr.Error("Please enter a prompt to generate an image.")
|
| 53 |
+
|
| 54 |
+
# Set random seed for reproducibility
|
| 55 |
+
generator = torch.Generator(device).manual_seed(int(seed))
|
| 56 |
+
|
| 57 |
+
# Generate the image
|
| 58 |
+
progress(0, desc="Initializing generation...")
|
| 59 |
+
|
| 60 |
+
try:
|
| 61 |
+
result = pipe(
|
| 62 |
+
prompt=prompt,
|
| 63 |
+
negative_prompt=negative_prompt if negative_prompt.strip() else None,
|
| 64 |
+
height=int(height),
|
| 65 |
+
width=int(width),
|
| 66 |
+
num_inference_steps=int(num_steps),
|
| 67 |
+
guidance_scale=0.0, # Turbo models use 0 guidance
|
| 68 |
+
generator=generator,
|
| 69 |
+
)
|
| 70 |
+
|
| 71 |
+
image = result.images[0]
|
| 72 |
+
progress(1.0, desc="Complete!")
|
| 73 |
+
|
| 74 |
+
return image
|
| 75 |
+
|
| 76 |
+
except Exception as e:
|
| 77 |
+
raise gr.Error(f"Generation failed: {str(e)}")
|
| 78 |
+
|
| 79 |
+
# Apple-inspired CSS
|
| 80 |
+
apple_css = """
|
| 81 |
+
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');
|
| 82 |
+
|
| 83 |
+
* {
|
| 84 |
+
font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif !important;
|
| 85 |
+
}
|
| 86 |
+
|
| 87 |
+
.gradio-container {
|
| 88 |
+
max-width: 1200px !important;
|
| 89 |
+
margin: 0 auto !important;
|
| 90 |
+
background: linear-gradient(135deg, #f5f7fa 0%, #e8ecf1 100%) !important;
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
.main-header {
|
| 94 |
+
text-align: center;
|
| 95 |
+
padding: 2.5rem 1rem 1.5rem 1rem;
|
| 96 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
| 97 |
+
border-radius: 24px;
|
| 98 |
+
margin-bottom: 2rem;
|
| 99 |
+
box-shadow: 0 10px 40px rgba(102, 126, 234, 0.3);
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
.main-header h1 {
|
| 103 |
+
font-size: 2.5rem !important;
|
| 104 |
+
font-weight: 700 !important;
|
| 105 |
+
color: white !important;
|
| 106 |
+
margin: 0 0 0.5rem 0 !important;
|
| 107 |
+
letter-spacing: -0.5px;
|
| 108 |
+
}
|
| 109 |
+
|
| 110 |
+
.main-header p {
|
| 111 |
+
font-size: 1.1rem !important;
|
| 112 |
+
color: rgba(255, 255, 255, 0.9) !important;
|
| 113 |
+
margin: 0 !important;
|
| 114 |
+
font-weight: 400;
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
.attribution {
|
| 118 |
+
text-align: center;
|
| 119 |
+
margin-top: 0.5rem;
|
| 120 |
+
font-size: 0.9rem;
|
| 121 |
+
color: rgba(255, 255, 255, 0.8);
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
.attribution a {
|
| 125 |
+
color: white !important;
|
| 126 |
+
text-decoration: none;
|
| 127 |
+
font-weight: 600;
|
| 128 |
+
transition: opacity 0.2s;
|
| 129 |
+
}
|
| 130 |
+
|
| 131 |
+
.attribution a:hover {
|
| 132 |
+
opacity: 0.8;
|
| 133 |
+
}
|
| 134 |
+
|
| 135 |
+
.control-panel {
|
| 136 |
+
background: white;
|
| 137 |
+
border-radius: 20px;
|
| 138 |
+
padding: 1.5rem;
|
| 139 |
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
| 140 |
+
margin-bottom: 1.5rem;
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
.output-panel {
|
| 144 |
+
background: white;
|
| 145 |
+
border-radius: 20px;
|
| 146 |
+
padding: 1.5rem;
|
| 147 |
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
|
| 148 |
+
min-height: 600px;
|
| 149 |
+
}
|
| 150 |
+
|
| 151 |
+
.primary-btn {
|
| 152 |
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important;
|
| 153 |
+
border: none !important;
|
| 154 |
+
border-radius: 12px !important;
|
| 155 |
+
padding: 0.875rem 2rem !important;
|
| 156 |
+
font-size: 1rem !important;
|
| 157 |
+
font-weight: 600 !important;
|
| 158 |
+
color: white !important;
|
| 159 |
+
transition: all 0.3s ease !important;
|
| 160 |
+
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.3) !important;
|
| 161 |
+
}
|
| 162 |
+
|
| 163 |
+
.primary-btn:hover {
|
| 164 |
+
transform: translateY(-2px) !important;
|
| 165 |
+
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4) !important;
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
.secondary-btn {
|
| 169 |
+
background: #f3f4f6 !important;
|
| 170 |
+
border: 1px solid #e5e7eb !important;
|
| 171 |
+
border-radius: 12px !important;
|
| 172 |
+
padding: 0.875rem 2rem !important;
|
| 173 |
+
font-size: 1rem !important;
|
| 174 |
+
font-weight: 500 !important;
|
| 175 |
+
color: #374151 !important;
|
| 176 |
+
transition: all 0.3s ease !important;
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
.secondary-btn:hover {
|
| 180 |
+
background: #e5e7eb !important;
|
| 181 |
+
transform: translateY(-1px) !important;
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
textarea, input, .input-container {
|
| 185 |
+
border-radius: 12px !important;
|
| 186 |
+
border: 1.5px solid #e5e7eb !important;
|
| 187 |
+
transition: all 0.2s ease !important;
|
| 188 |
+
font-size: 0.95rem !important;
|
| 189 |
+
}
|
| 190 |
+
|
| 191 |
+
textarea:focus, input:focus {
|
| 192 |
+
border-color: #667eea !important;
|
| 193 |
+
box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1) !important;
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
.slider-container input[type="range"] {
|
| 197 |
+
accent-color: #667eea !important;
|
| 198 |
+
}
|
| 199 |
+
|
| 200 |
+
label {
|
| 201 |
+
font-weight: 600 !important;
|
| 202 |
+
color: #1f2937 !important;
|
| 203 |
+
font-size: 0.9rem !important;
|
| 204 |
+
margin-bottom: 0.5rem !important;
|
| 205 |
+
}
|
| 206 |
+
|
| 207 |
+
.example-card {
|
| 208 |
+
border-radius: 12px !important;
|
| 209 |
+
transition: all 0.3s ease !important;
|
| 210 |
+
cursor: pointer !important;
|
| 211 |
+
border: 2px solid transparent !important;
|
| 212 |
+
}
|
| 213 |
+
|
| 214 |
+
.example-card:hover {
|
| 215 |
+
border-color: #667eea !important;
|
| 216 |
+
transform: scale(1.02) !important;
|
| 217 |
+
}
|
| 218 |
+
|
| 219 |
+
.accordion {
|
| 220 |
+
border-radius: 12px !important;
|
| 221 |
+
border: 1.5px solid #e5e7eb !important;
|
| 222 |
+
overflow: hidden !important;
|
| 223 |
+
}
|
| 224 |
+
|
| 225 |
+
#output-image {
|
| 226 |
+
border-radius: 16px !important;
|
| 227 |
+
overflow: hidden !important;
|
| 228 |
+
}
|
| 229 |
+
|
| 230 |
+
.footer-note {
|
| 231 |
+
text-align: center;
|
| 232 |
+
padding: 1.5rem;
|
| 233 |
+
color: #6b7280;
|
| 234 |
+
font-size: 0.9rem;
|
| 235 |
+
margin-top: 2rem;
|
| 236 |
+
}
|
| 237 |
+
|
| 238 |
+
@media (max-width: 768px) {
|
| 239 |
+
.main-header h1 {
|
| 240 |
+
font-size: 1.75rem !important;
|
| 241 |
+
}
|
| 242 |
+
|
| 243 |
+
.main-header p {
|
| 244 |
+
font-size: 0.95rem !important;
|
| 245 |
+
}
|
| 246 |
+
|
| 247 |
+
.control-panel, .output-panel {
|
| 248 |
+
padding: 1rem;
|
| 249 |
+
}
|
| 250 |
+
}
|
| 251 |
+
"""
|
| 252 |
+
|
| 253 |
+
# Example prompts
|
| 254 |
+
examples = [
|
| 255 |
+
[
|
| 256 |
+
"Young Chinese woman in red Hanfu, intricate embroidery. Impeccable makeup, red floral forehead pattern. Elaborate high bun, golden phoenix headdress, red flowers, beads. Holds round folding fan with lady, trees, bird. Neon lightning-bolt lamp (⚡️), bright yellow glow, above extended left palm. Soft-lit outdoor night background, silhouetted tiered pagoda (西安大雁塔), blurred colorful distant lights.",
|
| 257 |
+
"",
|
| 258 |
+
1024,
|
| 259 |
+
1024,
|
| 260 |
+
9,
|
| 261 |
+
42
|
| 262 |
+
],
|
| 263 |
+
[
|
| 264 |
+
"A serene Japanese garden with cherry blossoms in full bloom, koi pond with crystal clear water, traditional wooden bridge, soft morning light filtering through trees, ultra detailed, photorealistic",
|
| 265 |
+
"blurry, low quality, distorted",
|
| 266 |
+
1024,
|
| 267 |
+
1024,
|
| 268 |
+
9,
|
| 269 |
+
123
|
| 270 |
+
],
|
| 271 |
+
[
|
| 272 |
+
"Futuristic cyberpunk city at night, neon signs reflecting on wet streets, flying cars, towering skyscrapers with holographic advertisements, rain, cinematic lighting, highly detailed",
|
| 273 |
+
"daytime, bright, low quality",
|
| 274 |
+
1024,
|
| 275 |
+
1024,
|
| 276 |
+
9,
|
| 277 |
+
456
|
| 278 |
+
],
|
| 279 |
+
[
|
| 280 |
+
"Majestic dragon soaring through clouds at sunset, scales shimmering with iridescent colors, mountains in background, fantasy art style, epic composition, dramatic lighting",
|
| 281 |
+
"cartoon, simple, flat",
|
| 282 |
+
1024,
|
| 283 |
+
1024,
|
| 284 |
+
9,
|
| 285 |
+
789
|
| 286 |
+
],
|
| 287 |
+
[
|
| 288 |
+
"Cozy coffee shop interior, warm lighting, wooden furniture, plants on shelves, barista preparing coffee, steam rising from cup, bokeh background, inviting atmosphere",
|
| 289 |
+
"empty, cold, harsh lighting",
|
| 290 |
+
1024,
|
| 291 |
+
1024,
|
| 292 |
+
9,
|
| 293 |
+
321
|
| 294 |
+
]
|
| 295 |
+
]
|
| 296 |
+
|
| 297 |
+
# Create the Gradio interface
|
| 298 |
+
with gr.Blocks(
|
| 299 |
+
theme=gr.themes.Soft(
|
| 300 |
+
primary_hue="violet",
|
| 301 |
+
secondary_hue="purple",
|
| 302 |
+
neutral_hue="slate",
|
| 303 |
+
font=gr.themes.GoogleFont("Inter")
|
| 304 |
+
),
|
| 305 |
+
css=apple_css,
|
| 306 |
+
title="Z-Image Turbo - AI Image Generator",
|
| 307 |
+
fill_height=False
|
| 308 |
+
) as demo:
|
| 309 |
+
|
| 310 |
+
# Header
|
| 311 |
+
with gr.Row():
|
| 312 |
+
with gr.Column():
|
| 313 |
+
gr.HTML("""
|
| 314 |
+
<div class="main-header">
|
| 315 |
+
<h1>✨ Z-Image Turbo</h1>
|
| 316 |
+
<p>Create stunning images from text in seconds</p>
|
| 317 |
+
<div class="attribution">
|
| 318 |
+
Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank">anycoder</a>
|
| 319 |
+
</div>
|
| 320 |
+
</div>
|
| 321 |
+
""")
|
| 322 |
+
|
| 323 |
+
with gr.Row():
|
| 324 |
+
# Left column - Controls
|
| 325 |
+
with gr.Column(scale=1, elem_classes="control-panel"):
|
| 326 |
+
prompt = gr.Textbox(
|
| 327 |
+
label="✍️ Prompt",
|
| 328 |
+
placeholder="Describe the image you want to create...",
|
| 329 |
+
lines=4,
|
| 330 |
+
max_lines=8
|
| 331 |
+
)
|
| 332 |
+
|
| 333 |
+
negative_prompt = gr.Textbox(
|
| 334 |
+
label="🚫 Negative Prompt (Optional)",
|
| 335 |
+
placeholder="What you don't want in the image...",
|
| 336 |
+
lines=2,
|
| 337 |
+
max_lines=4
|
| 338 |
+
)
|
| 339 |
+
|
| 340 |
+
with gr.Accordion("⚙️ Advanced Settings", open=False, elem_classes="accordion"):
|
| 341 |
+
with gr.Row():
|
| 342 |
+
width = gr.Slider(
|
| 343 |
+
minimum=512,
|
| 344 |
+
maximum=2048,
|
| 345 |
+
value=1024,
|
| 346 |
+
step=64,
|
| 347 |
+
label="Width",
|
| 348 |
+
elem_classes="slider-container"
|
| 349 |
+
)
|
| 350 |
+
height = gr.Slider(
|
| 351 |
+
minimum=512,
|
| 352 |
+
maximum=2048,
|
| 353 |
+
value=1024,
|
| 354 |
+
step=64,
|
| 355 |
+
label="Height",
|
| 356 |
+
elem_classes="slider-container"
|
| 357 |
+
)
|
| 358 |
+
|
| 359 |
+
num_steps = gr.Slider(
|
| 360 |
+
minimum=4,
|
| 361 |
+
maximum=20,
|
| 362 |
+
value=9,
|
| 363 |
+
step=1,
|
| 364 |
+
label="Inference Steps",
|
| 365 |
+
info="More steps = better quality but slower",
|
| 366 |
+
elem_classes="slider-container"
|
| 367 |
+
)
|
| 368 |
+
|
| 369 |
+
seed = gr.Number(
|
| 370 |
+
label="Seed",
|
| 371 |
+
value=42,
|
| 372 |
+
precision=0,
|
| 373 |
+
info="Use same seed for reproducible results"
|
| 374 |
+
)
|
| 375 |
+
|
| 376 |
+
random_seed_btn = gr.Button(
|
| 377 |
+
"🎲 Random Seed",
|
| 378 |
+
elem_classes="secondary-btn",
|
| 379 |
+
size="sm"
|
| 380 |
+
)
|
| 381 |
+
|
| 382 |
+
with gr.Row():
|
| 383 |
+
generate_btn = gr.Button(
|
| 384 |
+
"🎨 Generate Image",
|
| 385 |
+
variant="primary",
|
| 386 |
+
elem_classes="primary-btn",
|
| 387 |
+
size="lg"
|
| 388 |
+
)
|
| 389 |
+
clear_btn = gr.ClearButton(
|
| 390 |
+
[prompt, negative_prompt],
|
| 391 |
+
value="🗑️ Clear",
|
| 392 |
+
elem_classes="secondary-btn",
|
| 393 |
+
size="lg"
|
| 394 |
+
)
|
| 395 |
+
|
| 396 |
+
# Right column - Output
|
| 397 |
+
with gr.Column(scale=1, elem_classes="output-panel"):
|
| 398 |
+
output_image = gr.Image(
|
| 399 |
+
label="Generated Image",
|
| 400 |
+
type="pil",
|
| 401 |
+
elem_id="output-image",
|
| 402 |
+
show_label=False,
|
| 403 |
+
show_download_button=True,
|
| 404 |
+
show_share_button=True,
|
| 405 |
+
height=600
|
| 406 |
+
)
|
| 407 |
+
|
| 408 |
+
# Examples section
|
| 409 |
+
with gr.Row():
|
| 410 |
+
gr.Examples(
|
| 411 |
+
examples=examples,
|
| 412 |
+
inputs=[prompt, negative_prompt, height, width, num_steps, seed],
|
| 413 |
+
outputs=output_image,
|
| 414 |
+
fn=generate_image,
|
| 415 |
+
cache_examples=False,
|
| 416 |
+
label="💡 Try these examples",
|
| 417 |
+
examples_per_page=5,
|
| 418 |
+
elem_classes="example-card"
|
| 419 |
+
)
|
| 420 |
+
|
| 421 |
+
# Footer
|
| 422 |
+
gr.HTML("""
|
| 423 |
+
<div class="footer-note">
|
| 424 |
+
<p>Powered by <strong>Z-Image Turbo</strong> from Tongyi-MAI |
|
| 425 |
+
Optimized for fast, high-quality image generation</p>
|
| 426 |
+
<p style="margin-top: 0.5rem; font-size: 0.85rem;">
|
| 427 |
+
💡 Tip: Be specific and detailed in your prompts for best results
|
| 428 |
+
</p>
|
| 429 |
+
</div>
|
| 430 |
+
""")
|
| 431 |
+
|
| 432 |
+
# Event handlers
|
| 433 |
+
def randomize_seed():
|
| 434 |
+
import random
|
| 435 |
+
return random.randint(0, 2**32 - 1)
|
| 436 |
+
|
| 437 |
+
random_seed_btn.click(
|
| 438 |
+
fn=randomize_seed,
|
| 439 |
+
inputs=[],
|
| 440 |
+
outputs=seed
|
| 441 |
+
)
|
| 442 |
+
|
| 443 |
+
generate_btn.click(
|
| 444 |
+
fn=generate_image,
|
| 445 |
+
inputs=[prompt, negative_prompt, height, width, num_steps, seed],
|
| 446 |
+
outputs=output_image,
|
| 447 |
+
api_name="generate"
|
| 448 |
+
)
|
| 449 |
+
|
| 450 |
+
# Also allow generation on Enter key in prompt
|
| 451 |
+
prompt.submit(
|
| 452 |
+
fn=generate_image,
|
| 453 |
+
inputs=[prompt, negative_prompt, height, width, num_steps, seed],
|
| 454 |
+
outputs=output_image
|
| 455 |
+
)
|
| 456 |
+
|
| 457 |
+
# Launch the app
|
| 458 |
+
if __name__ == "__main__":
|
| 459 |
+
demo.launch(
|
| 460 |
+
share=False,
|
| 461 |
+
show_error=True,
|
| 462 |
+
favicon_path=None
|
| 463 |
+
)
|