arpit13 commited on
Commit
ffda9a4
·
verified ·
1 Parent(s): dd0b18e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +1556 -0
app.py CHANGED
@@ -1,3 +1,1559 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  # AI Image Creator: Enhanced UI and UX
2
  # Part 3: Processing Logic, Prompt Enhancement, and Application Flow
3
 
 
1
+ # AI Image Creator: Enhanced UI and UX
2
+ # Part 1: Core Setup, Model Classes and API Configuration
3
+
4
+ import gradio as gr
5
+ import logging
6
+ import sys
7
+ import random
8
+ import time
9
+ from huggingface_hub import InferenceClient
10
+ from PIL import Image
11
+ import io
12
+ import base64
13
+
14
+ # Set up logging
15
+ logging.basicConfig(
16
+ level=logging.INFO,
17
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
18
+ handlers=[logging.StreamHandler(sys.stdout)]
19
+ )
20
+ logger = logging.getLogger("ai_image_creator")
21
+
22
+ # =============== MODEL CLIENTS SETUP ===============
23
+ def setup_client(api_key, provider=None):
24
+ """Initialize and return API client"""
25
+ try:
26
+ if provider:
27
+ client = InferenceClient(provider=provider, api_key=api_key)
28
+ logger.info(f"{provider} client initialized successfully")
29
+ else:
30
+ client = InferenceClient(api_key=api_key)
31
+ logger.info("Hugging Face client initialized successfully")
32
+ return client
33
+ except Exception as e:
34
+ logger.error(f"Error initializing client: {str(e)}")
35
+ return None
36
+
37
+ # Initialize clients
38
+ try:
39
+ # Replace with your actual HF API key
40
+ hf_api_key = os.getenv("HF_API_KEY")
41
+
42
+ hf_client = setup_client(hf_api_key)
43
+ logger.info("Hugging Face client created successfully")
44
+
45
+ # Set up Llama client if API key is provided
46
+ llama_api_key = os.getenv("HF_API_KEY") # Replace with actual key if available
47
+ try:
48
+ llama_client = setup_client(llama_api_key, "sambanova")
49
+ use_llama = True
50
+ logger.info("Llama client created successfully")
51
+ except Exception as e:
52
+ logger.warning(f"Llama client not available: {str(e)}. Will use fallback enhancement.")
53
+ llama_client = None
54
+ use_llama = False
55
+ except Exception as e:
56
+ logger.error(f"Failed to create Hugging Face client: {str(e)}")
57
+ hf_client = None
58
+ llama_client = None
59
+ use_llama = False
60
+
61
+ # =============== DATA MODELS ===============
62
+
63
+ # Image Models with friendly names, descriptions and icons
64
+ IMAGE_MODELS = {
65
+ "stabilityai/stable-diffusion-xl-base-1.0": {
66
+ "display_name": "SDXL 1.0",
67
+ "description": "Best overall quality, slower generation",
68
+ "icon": "⭐",
69
+ "speed": "slow",
70
+ "quality": "excellent"
71
+ },
72
+ "runwayml/stable-diffusion-v1-5": {
73
+ "display_name": "SD 1.5",
74
+ "description": "Good for general purpose, faster generation",
75
+ "icon": "🚀",
76
+ "speed": "fast",
77
+ "quality": "good"
78
+ },
79
+ "stabilityai/stable-diffusion-2-1": {
80
+ "display_name": "SD 2.1",
81
+ "description": "Improved details, balanced speed and quality",
82
+ "icon": "✨",
83
+ "speed": "medium",
84
+ "quality": "very good"
85
+ },
86
+ "prompthero/openjourney": {
87
+ "display_name": "OpenJourney",
88
+ "description": "Midjourney-like stylized results",
89
+ "icon": "🎨",
90
+ "speed": "medium",
91
+ "quality": "stylized"
92
+ },
93
+ "dreamlike-art/dreamlike-diffusion-1.0": {
94
+ "display_name": "Dreamlike",
95
+ "description": "Artistic style with dreamy aesthetics",
96
+ "icon": "💫",
97
+ "speed": "medium",
98
+ "quality": "artistic"
99
+ }
100
+ }
101
+
102
+ # Creation types with icons and detailed descriptions
103
+ CREATION_TYPES = {
104
+ "Realistic Photo": {
105
+ "description": "Create a photorealistic image with natural details and lighting",
106
+ "icon": "📷",
107
+ "prompt_hint": "Try to include details about lighting, time of day, and environment"
108
+ },
109
+ "Digital Art": {
110
+ "description": "Create colorful digital artwork with clean lines and vibrant colors",
111
+ "icon": "🖌️",
112
+ "prompt_hint": "Consider specifying color palette and mood for better results"
113
+ },
114
+ "Fantasy Illustration": {
115
+ "description": "Create magical and fantastical scenes with otherworldly elements",
116
+ "icon": "🧙",
117
+ "prompt_hint": "Describe magical elements, creatures, and environments in detail"
118
+ },
119
+ "Concept Art": {
120
+ "description": "Create professional concept art for characters, environments or objects",
121
+ "icon": "🎮",
122
+ "prompt_hint": "Include details about perspective, purpose, and design influences"
123
+ },
124
+ "Anime/Manga": {
125
+ "description": "Create Japanese anime or manga style illustration",
126
+ "icon": "🍙",
127
+ "prompt_hint": "Specify anime aesthetics like shading style and character features"
128
+ },
129
+ "Oil Painting": {
130
+ "description": "Create an image with oil painting textures and artistic brushstrokes",
131
+ "icon": "🖼️",
132
+ "prompt_hint": "Consider describing texture, brushwork style, and canvas feel"
133
+ },
134
+ "Watercolor": {
135
+ "description": "Create a soft watercolor illustration with subtle color blending",
136
+ "icon": "💧",
137
+ "prompt_hint": "Mention color blending, paper texture, and watercolor-specific effects"
138
+ },
139
+ "Sketch": {
140
+ "description": "Create a detailed sketch or drawing with line art focus",
141
+ "icon": "✏️",
142
+ "prompt_hint": "Describe line weight, hatching style, and sketch medium (pencil, charcoal, etc.)"
143
+ },
144
+ "3D Rendering": {
145
+ "description": "Create an image that looks like a 3D rendered scene with realistic lighting",
146
+ "icon": "💻",
147
+ "prompt_hint": "Include details about lighting setup, materials, and camera perspective"
148
+ },
149
+ "Pixel Art": {
150
+ "description": "Create retro-style pixel art with limited color palette",
151
+ "icon": "👾",
152
+ "prompt_hint": "Specify resolution, color limitations, and pixel art style (e.g., 16-bit, 8-bit)"
153
+ }
154
+ }
155
+
156
+ # Art styles with icons and detailed descriptions
157
+ ART_STYLES = {
158
+ "Photorealistic": {
159
+ "description": "Detailed realistic style that resembles a photograph with accurate lighting and textures",
160
+ "icon": "📸",
161
+ "examples": "Works by Chuck Close, Richard Estes, or modern 3D renderings"
162
+ },
163
+ "Impressionist": {
164
+ "description": "Soft brushstrokes that capture light and atmosphere over precise details, like Monet",
165
+ "icon": "🌈",
166
+ "examples": "Claude Monet, Pierre-Auguste Renoir, Camille Pissarro"
167
+ },
168
+ "Surrealist": {
169
+ "description": "Dreamlike quality with impossible or irrational scenes, like Salvador Dali",
170
+ "icon": "🌀",
171
+ "examples": "Salvador Dali, René Magritte, Frida Kahlo"
172
+ },
173
+ "Pop Art": {
174
+ "description": "Bold colors, sharp lines and popular culture references, like Andy Warhol",
175
+ "icon": "🎭",
176
+ "examples": "Andy Warhol, Roy Lichtenstein, Keith Haring"
177
+ },
178
+ "Minimalist": {
179
+ "description": "Simplified forms, limited color palette, and clean composition with minimal elements",
180
+ "icon": "⬜",
181
+ "examples": "Piet Mondrian, Kazimir Malevich, Agnes Martin"
182
+ },
183
+ "Abstract": {
184
+ "description": "Non-representational style using shapes, colors, and forms to express ideas",
185
+ "icon": "🔶",
186
+ "examples": "Wassily Kandinsky, Jackson Pollock, Mark Rothko"
187
+ },
188
+ "Cubist": {
189
+ "description": "Geometric shapes and multiple perspectives shown simultaneously, like Picasso",
190
+ "icon": "📐",
191
+ "examples": "Pablo Picasso, Georges Braque, Juan Gris"
192
+ },
193
+ "Art Nouveau": {
194
+ "description": "Ornate, flowing lines inspired by natural forms with decorative elegance",
195
+ "icon": "🌿",
196
+ "examples": "Alphonse Mucha, Gustav Klimt, Antoni Gaudí"
197
+ },
198
+ "Gothic": {
199
+ "description": "Dark, medieval-inspired aesthetic with dramatic lighting and architectural elements",
200
+ "icon": "🏰",
201
+ "examples": "Zdzisław Beksiński, H.R. Giger, medieval architecture"
202
+ },
203
+ "Cyberpunk": {
204
+ "description": "Futuristic dystopian style with neon colors, technology, and urban decay",
205
+ "icon": "🤖",
206
+ "examples": "Blade Runner, Ghost in the Shell, Akira"
207
+ },
208
+ "Steampunk": {
209
+ "description": "Victorian-era aesthetic combined with steam-powered technology and brass elements",
210
+ "icon": "⚙️",
211
+ "examples": "Works by James Ng, Keith Thompson, retrofuturistic Jules Verne adaptations"
212
+ },
213
+ "Retro/Vintage": {
214
+ "description": "Nostalgic style reminiscent of past decades with period-appropriate elements",
215
+ "icon": "📺",
216
+ "examples": "1950s advertisements, vintage travel posters, pulp magazine covers"
217
+ },
218
+ "Art Deco": {
219
+ "description": "Geometric patterns, bold colors, and luxurious materials in a symmetrical style",
220
+ "icon": "🏢",
221
+ "examples": "Works from the 1920s-30s, Chrysler Building, Tamara de Lempicka paintings"
222
+ },
223
+ "Baroque": {
224
+ "description": "Dramatic, ornate style with rich details, contrast, and dynamic composition",
225
+ "icon": "👑",
226
+ "examples": "Caravaggio, Rembrandt, Peter Paul Rubens"
227
+ },
228
+ "Ukiyo-e": {
229
+ "description": "Traditional Japanese woodblock print style with flat areas of color and strong outlines",
230
+ "icon": "🌊",
231
+ "examples": "Hokusai's Great Wave, Hiroshige's landscapes, traditional Japanese prints"
232
+ },
233
+ "Comic Book": {
234
+ "description": "Bold outlines, bright colors, and action-oriented composition like classic comics",
235
+ "icon": "💥",
236
+ "examples": "Jack Kirby, Steve Ditko, modern Marvel/DC art styles"
237
+ },
238
+ "Psychedelic": {
239
+ "description": "Vibrant, swirling colors with abstract patterns inspired by 1960s art",
240
+ "icon": "🌈",
241
+ "examples": "1960s concert posters, Peter Max, Alex Grey"
242
+ },
243
+ "Vaporwave": {
244
+ "description": "Glitch aesthetics with pastel colors, 80s/90s nostalgia and digital elements",
245
+ "icon": "📼",
246
+ "examples": "Retrowave aesthetics, 80s digital graphics, glitch art"
247
+ },
248
+ "Studio Ghibli": {
249
+ "description": "Whimsical, detailed animation style inspired by Japanese animated films",
250
+ "icon": "🐉",
251
+ "examples": "Spirited Away, My Neighbor Totoro, Howl's Moving Castle"
252
+ },
253
+ "Hyperrealism": {
254
+ "description": "Extremely detailed realism that exceeds photograph-like precision",
255
+ "icon": "🔍",
256
+ "examples": "Works by Roberto Bernardi, Denis Peterson, Gottfried Helnwein"
257
+ }
258
+ }
259
+
260
+ # Moods with icons and descriptions
261
+ MOODS = {
262
+ "Happy": {
263
+ "description": "Bright, cheerful atmosphere with warm colors",
264
+ "icon": "😊",
265
+ "color_palette": "Warm and vibrant colors: yellows, bright oranges, light blues"
266
+ },
267
+ "Sad": {
268
+ "description": "Melancholic atmosphere with muted colors",
269
+ "icon": "😢",
270
+ "color_palette": "Muted blues, grays, desaturated colors, cool tones"
271
+ },
272
+ "Mysterious": {
273
+ "description": "Enigmatic atmosphere with shadows and hidden elements",
274
+ "icon": "🔮",
275
+ "color_palette": "Deep purples, dark blues, hints of teal, selective lighting"
276
+ },
277
+ "Peaceful": {
278
+ "description": "Serene, calm atmosphere with gentle lighting",
279
+ "icon": "🕊️",
280
+ "color_palette": "Soft blues, gentle greens, pastel colors, balanced light"
281
+ },
282
+ "Tense": {
283
+ "description": "Suspenseful atmosphere with dramatic lighting",
284
+ "icon": "😰",
285
+ "color_palette": "High contrast, dark shadows, selective reds, strong highlights"
286
+ },
287
+ "Whimsical": {
288
+ "description": "Playful, imaginative atmosphere with fanciful elements",
289
+ "icon": "🦄",
290
+ "color_palette": "Pastels, candy colors, unexpected color combinations"
291
+ },
292
+ "Dark": {
293
+ "description": "Gloomy atmosphere with deep shadows and low lighting",
294
+ "icon": "🌑",
295
+ "color_palette": "Dark blues, blacks, deep greens, minimal highlights"
296
+ },
297
+ "Energetic": {
298
+ "description": "Dynamic, vibrant atmosphere with strong colors and movement",
299
+ "icon": "⚡",
300
+ "color_palette": "Saturated primary colors, bold contrasts, vibrant hues"
301
+ },
302
+ "Romantic": {
303
+ "description": "Soft, dreamy atmosphere with warm, gentle lighting",
304
+ "icon": "❤️",
305
+ "color_palette": "Soft pinks, gentle reds, golden highlights, warm tones"
306
+ },
307
+ "Epic": {
308
+ "description": "Grand, impressive atmosphere with dramatic scale and lighting",
309
+ "icon": "🏔️",
310
+ "color_palette": "Bold colors, dramatic contrast, atmospheric lighting, expansive scale"
311
+ }
312
+ }
313
+
314
+ # Example prompts with rich metadata
315
+ EXAMPLE_PROMPTS = [
316
+ {
317
+ "text": "A serene lake at sunset with mountains in the background and a small wooden boat floating nearby",
318
+ "thumbnail_desc": "Peaceful lake scene at sunset",
319
+ "creation_type": "Realistic Photo",
320
+ "art_style": "Photorealistic",
321
+ "mood": "Peaceful",
322
+ "tags": ["nature", "landscape", "water", "sunset"]
323
+ },
324
+ {
325
+ "text": "A futuristic cityscape with flying cars, neon lights, and tall skyscrapers under a night sky with two moons",
326
+ "thumbnail_desc": "Futuristic city with flying cars",
327
+ "creation_type": "Concept Art",
328
+ "art_style": "Cyberpunk",
329
+ "mood": "Mysterious",
330
+ "tags": ["scifi", "future", "urban", "night"]
331
+ },
332
+ {
333
+ "text": "A close-up portrait of an elderly craftsman with weathered hands working on an intricate wooden carving in his workshop",
334
+ "thumbnail_desc": "Elderly craftsman working with wood",
335
+ "creation_type": "Oil Painting",
336
+ "art_style": "Hyperrealism",
337
+ "mood": "Peaceful",
338
+ "tags": ["portrait", "craftsmanship", "elderly", "detail"]
339
+ },
340
+ {
341
+ "text": "A magical forest with glowing mushrooms, fairy lights, and a small cottage with smoke coming from the chimney",
342
+ "thumbnail_desc": "Magical forest with glowing elements",
343
+ "creation_type": "Fantasy Illustration",
344
+ "art_style": "Studio Ghibli",
345
+ "mood": "Whimsical",
346
+ "tags": ["fantasy", "forest", "magic", "cottage"]
347
+ },
348
+ {
349
+ "text": "A cybernetic samurai with glowing blue circuits standing in a rainy Tokyo street at night",
350
+ "thumbnail_desc": "Cybernetic samurai in rainy Tokyo",
351
+ "creation_type": "Digital Art",
352
+ "art_style": "Cyberpunk",
353
+ "mood": "Dark",
354
+ "tags": ["character", "cyberpunk", "samurai", "rain"]
355
+ },
356
+ {
357
+ "text": "A cute cat with dragon wings and tiny horns sleeping on a pile of gold coins",
358
+ "thumbnail_desc": "Cat with dragon features on gold",
359
+ "creation_type": "Fantasy Illustration",
360
+ "art_style": "Comic Book",
361
+ "mood": "Whimsical",
362
+ "tags": ["creature", "fantasy", "cute", "treasure"]
363
+ },
364
+ {
365
+ "text": "An ancient temple covered in vines and moss, partially sunken into a crystal-clear cenote in the jungle",
366
+ "thumbnail_desc": "Ancient temple in jungle cenote",
367
+ "creation_type": "Concept Art",
368
+ "art_style": "Photorealistic",
369
+ "mood": "Mysterious",
370
+ "tags": ["architecture", "ruins", "jungle", "water"]
371
+ },
372
+ {
373
+ "text": "A cozy coffee shop interior with rain falling outside the windows, soft lighting, and a few people reading books",
374
+ "thumbnail_desc": "Cozy rainy day in coffee shop",
375
+ "creation_type": "Digital Art",
376
+ "art_style": "Impressionist",
377
+ "mood": "Peaceful",
378
+ "tags": ["interior", "rainy", "cozy", "urban"]
379
+ }
380
+ ]
381
+
382
+ # CSS for enhanced UI styling - Will be included in part 2
383
+
384
+ # =============== HELPER FUNCTIONS ===============
385
+
386
+ # Helper function to format dropdown choices with icons
387
+ def format_dropdown_choices(options_dict):
388
+ return [f"{info.get('icon', '•')} {key}" for key in options_dict.keys()]
389
+
390
+ # Helper function to extract the key from formatted choice
391
+ def extract_key(formatted_choice):
392
+ # Skip the icon and space at the beginning
393
+ parts = formatted_choice.split(' ', 1)
394
+ if len(parts) > 1:
395
+ return parts[1]
396
+ return formatted_choice
397
+
398
+ # Function to load example prompt
399
+ def load_example(example_index):
400
+ if example_index < 0 or example_index >= len(EXAMPLE_PROMPTS):
401
+ return "", "", "", ""
402
+
403
+ example = EXAMPLE_PROMPTS[example_index]
404
+ creation = f"{CREATION_TYPES[example['creation_type']]['icon']} {example['creation_type']}"
405
+ art = f"{ART_STYLES[example['art_style']]['icon']} {example['art_style']}"
406
+ mood = f"{MOODS[example['mood']]['icon']} {example['mood']}"
407
+
408
+ return example["text"], creation, art, mood
409
+
410
+ # Get model key from formatted display name
411
+ def get_model_key(formatted_name):
412
+ # Extract display name without the icon
413
+ if ' ' in formatted_name:
414
+ display_name = formatted_name.split(' ', 1)[1]
415
+ # Find the corresponding key
416
+ for key, info in IMAGE_MODELS.items():
417
+ if info['display_name'] == display_name:
418
+ return key
419
+ return list(IMAGE_MODELS.keys())[0] # Default to first model if not found
420
+
421
+ # AI Image Creator: Enhanced UI and UX
422
+ # Part 2: Enhanced UI Components and Styling
423
+
424
+ # CSS for styling the interface - Comprehensive styling for modern UI
425
+ css = """
426
+ /* Main theme colors with CSS variables for better customization */
427
+ :root {
428
+ --primary-color: #4F46E5;
429
+ --primary-hover: #4338CA;
430
+ --secondary-color: #7C3AED;
431
+ --secondary-hover: #6D28D9;
432
+ --background-color: #F8FAFC;
433
+ --card-color: #FFFFFF;
434
+ --text-color: #1E293B;
435
+ --text-muted: #64748B;
436
+ --accent-color: #3B82F6;
437
+ --success-color: #10B981;
438
+ --success-hover: #059669;
439
+ --warning-color: #F59E0B;
440
+ --error-color: #EF4444;
441
+ --error-hover: #DC2626;
442
+ --border-color: #E2E8F0;
443
+ --border-hover: #CBD5E1;
444
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
445
+ --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
446
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
447
+ --radius-sm: 0.375rem;
448
+ --radius: 0.5rem;
449
+ --radius-lg: 0.75rem;
450
+ --radius-xl: 1rem;
451
+ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
452
+ }
453
+
454
+ /* Global styles and resets */
455
+ body, html {
456
+ font-family: var(--font-sans);
457
+ color: var(--text-color);
458
+ background-color: var(--background-color);
459
+ line-height: 1.5;
460
+ margin: 0;
461
+ padding: 0;
462
+ }
463
+
464
+ /* Container with responsive padding */
465
+ .container {
466
+ max-width: 1400px;
467
+ margin: 0 auto;
468
+ padding: 1rem;
469
+ }
470
+
471
+ @media (max-width: 640px) {
472
+ .container {
473
+ padding: 0.5rem;
474
+ }
475
+ }
476
+
477
+ /* Card styling with elevation and hover effects */
478
+ .gr-panel {
479
+ border-radius: var(--radius) !important;
480
+ border: 1px solid var(--border-color) !important;
481
+ box-shadow: var(--shadow) !important;
482
+ overflow: hidden;
483
+ transition: transform 0.2s, box-shadow 0.2s;
484
+ background-color: var(--card-color) !important;
485
+ }
486
+
487
+ .gr-panel:hover {
488
+ transform: translateY(-2px);
489
+ box-shadow: var(--shadow-lg) !important;
490
+ }
491
+
492
+ /* Button styling with gradient and hover states */
493
+ button.primary {
494
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)) !important;
495
+ color: white !important;
496
+ border: none !important;
497
+ border-radius: var(--radius) !important;
498
+ font-weight: 600 !important;
499
+ letter-spacing: 0.025em !important;
500
+ padding: 0.75rem 1.5rem !important;
501
+ transition: all 0.3s ease !important;
502
+ box-shadow: var(--shadow-sm) !important;
503
+ outline: none !important;
504
+ text-transform: none !important;
505
+ }
506
+
507
+ button.primary:hover {
508
+ transform: translateY(-1px);
509
+ box-shadow: var(--shadow) !important;
510
+ opacity: 0.9;
511
+ }
512
+
513
+ button.primary:active {
514
+ transform: translateY(0);
515
+ opacity: 0.8;
516
+ }
517
+
518
+ button.primary[disabled], button.primary[disabled]:hover {
519
+ opacity: 0.5;
520
+ cursor: not-allowed;
521
+ transform: none;
522
+ }
523
+
524
+ /* Secondary button styling */
525
+ button.secondary {
526
+ background-color: transparent !important;
527
+ color: var(--primary-color) !important;
528
+ border: 1px solid var(--primary-color) !important;
529
+ border-radius: var(--radius) !important;
530
+ font-weight: 500 !important;
531
+ padding: 0.625rem 1.25rem !important;
532
+ transition: all 0.2s ease !important;
533
+ text-transform: none !important;
534
+ }
535
+
536
+ button.secondary:hover {
537
+ background-color: rgba(79, 70, 229, 0.05) !important;
538
+ border-color: var(--primary-hover) !important;
539
+ }
540
+
541
+ /* Style for the example buttons */
542
+ .example-button {
543
+ font-size: 0.875rem !important;
544
+ padding: 0.5rem 0.75rem !important;
545
+ background-color: transparent !important;
546
+ border: 1px solid var(--border-color) !important;
547
+ border-radius: var(--radius) !important;
548
+ transition: all 0.2s !important;
549
+ text-align: left !important;
550
+ justify-content: flex-start !important;
551
+ height: auto !important;
552
+ text-overflow: ellipsis;
553
+ overflow: hidden;
554
+ white-space: nowrap;
555
+ width: 100%;
556
+ color: var(--text-color) !important;
557
+ }
558
+
559
+ .example-button:hover {
560
+ background-color: rgba(79, 70, 229, 0.05) !important;
561
+ border-color: var(--primary-color) !important;
562
+ transform: translateY(-1px);
563
+ }
564
+
565
+ /* Form controls styling */
566
+ .gr-input, .gr-textarea, .gr-dropdown {
567
+ border-radius: var(--radius) !important;
568
+ border: 1px solid var(--border-color) !important;
569
+ transition: border-color 0.2s, box-shadow 0.2s !important;
570
+ font-family: var(--font-sans) !important;
571
+ color: var(--text-color) !important;
572
+ }
573
+
574
+ .gr-input:focus, .gr-textarea:focus, .gr-dropdown:focus-within {
575
+ border-color: var(--primary-color) !important;
576
+ box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2) !important;
577
+ outline: none !important;
578
+ }
579
+
580
+ .gr-form {
581
+ gap: 1rem !important;
582
+ }
583
+
584
+ .gr-input-label, .gr-dropdown-label, .gr-textarea-label, .gr-checkbox-label, .gr-radio-label {
585
+ font-size: 0.875rem !important;
586
+ font-weight: 500 !important;
587
+ color: var(--text-color) !important;
588
+ margin-bottom: 0.25rem !important;
589
+ }
590
+
591
+ /* Input placeholder styling */
592
+ .gr-input::placeholder, .gr-textarea::placeholder {
593
+ color: var(--text-muted) !important;
594
+ opacity: 0.7;
595
+ }
596
+
597
+ /* Input and textarea styling */
598
+ textarea, input[type="text"] {
599
+ border-radius: var(--radius) !important;
600
+ border: 1px solid var(--border-color) !important;
601
+ padding: 0.75rem 1rem !important;
602
+ transition: border-color 0.2s, box-shadow 0.2s !important;
603
+ font-family: var(--font-sans) !important;
604
+ }
605
+
606
+ textarea:focus, input[type="text"]:focus {
607
+ border-color: var(--primary-color) !important;
608
+ box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2) !important;
609
+ outline: none !important;
610
+ }
611
+
612
+ /* Dropdown styling */
613
+ .gr-dropdown {
614
+ border-radius: var(--radius) !important;
615
+ border: 1px solid var(--border-color) !important;
616
+ background-color: var(--card-color) !important;
617
+ }
618
+
619
+ .gr-dropdown > div {
620
+ border-radius: var(--radius) !important;
621
+ min-height: 38px !important;
622
+ }
623
+
624
+ .gr-dropdown > div > span {
625
+ font-size: 0.9375rem !important;
626
+ }
627
+
628
+ /* Dropdown menu styling */
629
+ .gr-dropdown ul {
630
+ background-color: var(--card-color) !important;
631
+ border: 1px solid var(--border-color) !important;
632
+ border-radius: var(--radius) !important;
633
+ box-shadow: var(--shadow) !important;
634
+ }
635
+
636
+ .gr-dropdown ul li {
637
+ padding: 0.5rem 0.75rem !important;
638
+ }
639
+
640
+ .gr-dropdown ul li:hover {
641
+ background-color: rgba(79, 70, 229, 0.05) !important;
642
+ }
643
+
644
+ /* Custom header with gradient background */
645
+ .app-header {
646
+ text-align: center;
647
+ padding: 1.75rem 1rem;
648
+ margin-bottom: 2rem;
649
+ background: linear-gradient(135deg, rgba(79, 70, 229, 0.08), rgba(124, 58, 237, 0.08));
650
+ border-radius: var(--radius-lg);
651
+ border-bottom: 3px solid var(--primary-color);
652
+ position: relative;
653
+ overflow: hidden;
654
+ }
655
+
656
+ .app-header::before {
657
+ content: '';
658
+ position: absolute;
659
+ top: -50px;
660
+ left: -50px;
661
+ right: -50px;
662
+ height: 100px;
663
+ background: linear-gradient(135deg, rgba(79, 70, 229, 0.2), rgba(124, 58, 237, 0.2));
664
+ transform: rotate(-5deg);
665
+ z-index: 0;
666
+ }
667
+
668
+ .app-header h1 {
669
+ font-size: 2.5rem !important;
670
+ font-weight: 800 !important;
671
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
672
+ -webkit-background-clip: text;
673
+ -webkit-text-fill-color: transparent;
674
+ margin-bottom: 0.5rem !important;
675
+ position: relative;
676
+ z-index: 1;
677
+ }
678
+
679
+ .app-header p {
680
+ font-size: 1.25rem !important;
681
+ color: var(--text-color);
682
+ opacity: 0.8;
683
+ max-width: 40rem;
684
+ margin: 0 auto;
685
+ position: relative;
686
+ z-index: 1;
687
+ }
688
+
689
+ /* Responsive header */
690
+ @media (max-width: 640px) {
691
+ .app-header h1 {
692
+ font-size: 2rem !important;
693
+ }
694
+
695
+ .app-header p {
696
+ font-size: 1rem !important;
697
+ }
698
+ }
699
+
700
+ /* Examples gallery with grid layout */
701
+ .example-gallery {
702
+ display: grid;
703
+ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
704
+ gap: 1rem;
705
+ margin: 1rem 0;
706
+ }
707
+
708
+ .example-item {
709
+ border-radius: var(--radius);
710
+ overflow: hidden;
711
+ cursor: pointer;
712
+ border: 2px solid transparent;
713
+ transition: all 0.2s;
714
+ display: flex;
715
+ flex-direction: column;
716
+ background-color: var(--card-color);
717
+ }
718
+
719
+ .example-item:hover {
720
+ transform: translateY(-2px);
721
+ border-color: var(--accent-color);
722
+ box-shadow: var(--shadow);
723
+ }
724
+
725
+ .example-item:active {
726
+ transform: translateY(0);
727
+ }
728
+
729
+ .example-item-image {
730
+ width: 100%;
731
+ aspect-ratio: 1;
732
+ background-color: #f0f0f0;
733
+ display: flex;
734
+ align-items: center;
735
+ justify-content: center;
736
+ color: var(--text-muted);
737
+ font-size: 1.5rem;
738
+ border-bottom: 1px solid var(--border-color);
739
+ }
740
+
741
+ .example-item-caption {
742
+ padding: 0.5rem;
743
+ font-size: 0.75rem;
744
+ line-height: 1.25;
745
+ color: var(--text-color);
746
+ overflow: hidden;
747
+ display: -webkit-box;
748
+ -webkit-line-clamp: 2;
749
+ -webkit-box-orient: vertical;
750
+ }
751
+
752
+ /* Loading indicator with animation */
753
+ .loading-indicator {
754
+ display: flex;
755
+ align-items: center;
756
+ justify-content: center;
757
+ height: 100%;
758
+ width: 100%;
759
+ position: absolute;
760
+ top: 0;
761
+ left: 0;
762
+ background-color: rgba(255, 255, 255, 0.8);
763
+ z-index: 1000;
764
+ backdrop-filter: blur(2px);
765
+ border-radius: var(--radius);
766
+ }
767
+
768
+ .spinner {
769
+ width: 40px;
770
+ height: 40px;
771
+ border: 4px solid rgba(79, 70, 229, 0.2);
772
+ border-radius: 50%;
773
+ border-top-color: var(--primary-color);
774
+ animation: spin 1s linear infinite;
775
+ }
776
+
777
+ @keyframes spin {
778
+ to {
779
+ transform: rotate(360deg);
780
+ }
781
+ }
782
+
783
+ /* Info cards with subtle styling */
784
+ .info-card {
785
+ background-color: var(--card-color);
786
+ border-radius: var(--radius);
787
+ padding: 1rem;
788
+ border: 1px solid var(--border-color);
789
+ margin-bottom: 1rem;
790
+ transition: all 0.2s;
791
+ }
792
+
793
+ .info-card:hover {
794
+ border-color: var(--border-hover);
795
+ box-shadow: var(--shadow-sm);
796
+ }
797
+
798
+ .info-card h3 {
799
+ margin-top: 0;
800
+ margin-bottom: 0.5rem;
801
+ font-size: 1rem;
802
+ font-weight: 600;
803
+ color: var(--primary-color);
804
+ display: flex;
805
+ align-items: center;
806
+ gap: 0.5rem;
807
+ }
808
+
809
+ .info-card p {
810
+ margin: 0;
811
+ font-size: 0.875rem;
812
+ color: var(--text-muted);
813
+ line-height: 1.5;
814
+ }
815
+
816
+ /* Model info panel with branded styling */
817
+ .model-info {
818
+ background-color: rgba(79, 70, 229, 0.05);
819
+ border-left: 3px solid var(--primary-color);
820
+ padding: 0.75rem 1rem;
821
+ border-radius: 0 var(--radius) var(--radius) 0;
822
+ margin: 1rem 0;
823
+ }
824
+
825
+ .model-info h3 {
826
+ display: flex;
827
+ align-items: center;
828
+ gap: 0.5rem;
829
+ margin-top: 0;
830
+ margin-bottom: 0.5rem;
831
+ font-size: 1rem;
832
+ font-weight: 600;
833
+ color: var(--primary-color);
834
+ }
835
+
836
+ .model-info p {
837
+ margin: 0 0 0.5rem 0;
838
+ font-size: 0.875rem;
839
+ color: var(--text-color);
840
+ }
841
+
842
+ .model-info .model-id {
843
+ font-size: 0.75rem;
844
+ color: var(--text-muted);
845
+ font-family: monospace;
846
+ background-color: rgba(0, 0, 0, 0.03);
847
+ padding: 0.25rem 0.5rem;
848
+ border-radius: 4px;
849
+ margin-top: 0.5rem;
850
+ word-break: break-all;
851
+ }
852
+
853
+ /* Parameter pills for displaying selections */
854
+ .parameter-pill {
855
+ display: inline-flex;
856
+ align-items: center;
857
+ background-color: rgba(79, 70, 229, 0.1);
858
+ color: var(--primary-color);
859
+ border-radius: 16px;
860
+ padding: 0.25rem 0.75rem;
861
+ margin-right: 0.5rem;
862
+ margin-bottom: 0.5rem;
863
+ font-size: 0.75rem;
864
+ font-weight: 500;
865
+ user-select: none;
866
+ }
867
+
868
+ .parameter-pill .icon {
869
+ margin-right: 0.25rem;
870
+ }
871
+
872
+ /* Badge for showing model speed/quality */
873
+ .badge {
874
+ display: inline-flex;
875
+ align-items: center;
876
+ justify-content: center;
877
+ border-radius: 9999px;
878
+ padding: 0.125rem 0.5rem;
879
+ font-size: 0.75rem;
880
+ font-weight: 500;
881
+ margin-left: 0.5rem;
882
+ }
883
+
884
+ .badge-success {
885
+ background-color: rgba(16, 185, 129, 0.1);
886
+ color: var(--success-color);
887
+ }
888
+
889
+ .badge-warning {
890
+ background-color: rgba(245, 158, 11, 0.1);
891
+ color: var(--warning-color);
892
+ }
893
+
894
+ .badge-error {
895
+ background-color: rgba(239, 68, 68, 0.1);
896
+ color: var(--error-color);
897
+ }
898
+
899
+ .badge-info {
900
+ background-color: rgba(59, 130, 246, 0.1);
901
+ color: var(--accent-color);
902
+ }
903
+
904
+ /* Enhanced accordion styling */
905
+ .gr-accordion {
906
+ border: 1px solid var(--border-color) !important;
907
+ border-radius: var(--radius) !important;
908
+ margin-bottom: 1rem !important;
909
+ overflow: hidden;
910
+ }
911
+
912
+ .gr-accordion > div:first-child {
913
+ padding: 0.75rem 1rem !important;
914
+ background-color: rgba(0, 0, 0, 0.02) !important;
915
+ font-weight: 600 !important;
916
+ color: var(--text-color) !important;
917
+ font-size: 0.9375rem !important;
918
+ }
919
+
920
+ .gr-accordion > div:last-child {
921
+ padding: 1rem !important;
922
+ }
923
+
924
+ /* Tooltip styling */
925
+ .tooltip {
926
+ position: relative;
927
+ display: inline-block;
928
+ cursor: help;
929
+ }
930
+
931
+ .tooltip .tooltiptext {
932
+ visibility: hidden;
933
+ width: 200px;
934
+ background-color: var(--text-color);
935
+ color: white;
936
+ text-align: center;
937
+ border-radius: var(--radius-sm);
938
+ padding: 0.5rem 0.75rem;
939
+ position: absolute;
940
+ z-index: 1000;
941
+ bottom: 125%;
942
+ left: 50%;
943
+ transform: translateX(-50%);
944
+ opacity: 0;
945
+ transition: opacity 0.3s;
946
+ font-size: 0.75rem;
947
+ box-shadow: var(--shadow);
948
+ pointer-events: none;
949
+ }
950
+
951
+ .tooltip .tooltiptext::after {
952
+ content: "";
953
+ position: absolute;
954
+ top: 100%;
955
+ left: 50%;
956
+ margin-left: -5px;
957
+ border-width: 5px;
958
+ border-style: solid;
959
+ border-color: var(--text-color) transparent transparent transparent;
960
+ }
961
+
962
+ .tooltip:hover .tooltiptext {
963
+ visibility: visible;
964
+ opacity: 1;
965
+ }
966
+
967
+ /* History item styling */
968
+ .history-item {
969
+ display: flex;
970
+ align-items: center;
971
+ padding: 0.75rem;
972
+ border-radius: var(--radius);
973
+ margin-bottom: 0.75rem;
974
+ background-color: var(--card-color);
975
+ border: 1px solid var(--border-color);
976
+ cursor: pointer;
977
+ transition: all 0.2s;
978
+ }
979
+
980
+ .history-item:hover {
981
+ background-color: rgba(79, 70, 229, 0.05);
982
+ transform: translateY(-1px);
983
+ }
984
+
985
+ .history-item-image {
986
+ width: 48px;
987
+ height: 48px;
988
+ border-radius: var(--radius-sm);
989
+ object-fit: cover;
990
+ margin-right: 0.75rem;
991
+ background-color: #f0f0f0;
992
+ display: flex;
993
+ align-items: center;
994
+ justify-content: center;
995
+ color: var(--text-muted);
996
+ font-size: 1.25rem;
997
+ }
998
+
999
+ .history-item-content {
1000
+ flex: 1;
1001
+ overflow: hidden;
1002
+ }
1003
+
1004
+ .history-item-title {
1005
+ margin: 0;
1006
+ font-size: 0.875rem;
1007
+ font-weight: 500;
1008
+ white-space: nowrap;
1009
+ overflow: hidden;
1010
+ text-overflow: ellipsis;
1011
+ color: var(--text-color);
1012
+ }
1013
+
1014
+ .history-item-subtitle {
1015
+ margin: 0;
1016
+ font-size: 0.75rem;
1017
+ color: var(--text-muted);
1018
+ margin-top: 0.25rem;
1019
+ }
1020
+
1021
+ /* Tabs styling */
1022
+ .tabs {
1023
+ display: flex;
1024
+ border-bottom: 1px solid var(--border-color);
1025
+ margin-bottom: 1rem;
1026
+ }
1027
+
1028
+ .tab {
1029
+ padding: 0.75rem 1rem;
1030
+ cursor: pointer;
1031
+ border-bottom: 2px solid transparent;
1032
+ font-weight: 500;
1033
+ font-size: 0.9375rem;
1034
+ color: var(--text-muted);
1035
+ transition: all 0.2s;
1036
+ }
1037
+
1038
+ .tab:hover {
1039
+ color: var(--primary-color);
1040
+ }
1041
+
1042
+ .tab.active {
1043
+ color: var(--primary-color);
1044
+ border-bottom-color: var(--primary-color);
1045
+ }
1046
+
1047
+ /* Progress bar */
1048
+ .progress-container {
1049
+ width: 100%;
1050
+ height: 8px;
1051
+ background-color: rgba(79, 70, 229, 0.1);
1052
+ border-radius: 4px;
1053
+ overflow: hidden;
1054
+ margin: 0.5rem 0;
1055
+ }
1056
+
1057
+ .progress-bar {
1058
+ height: 100%;
1059
+ background: linear-gradient(to right, var(--primary-color), var(--secondary-color));
1060
+ width: 0%;
1061
+ transition: width 0.3s ease;
1062
+ border-radius: 4px;
1063
+ }
1064
+
1065
+ /* Image output container */
1066
+ .image-output-container {
1067
+ position: relative;
1068
+ border-radius: var(--radius);
1069
+ overflow: hidden;
1070
+ transition: all 0.2s;
1071
+ background-color: #f5f5f5;
1072
+ min-height: 300px;
1073
+ }
1074
+
1075
+ .image-output-container img {
1076
+ width: 100%;
1077
+ display: block;
1078
+ border-radius: var(--radius);
1079
+ }
1080
+
1081
+ .image-placeholder {
1082
+ position: absolute;
1083
+ top: 0;
1084
+ left: 0;
1085
+ width: 100%;
1086
+ height: 100%;
1087
+ display: flex;
1088
+ flex-direction: column;
1089
+ align-items: center;
1090
+ justify-content: center;
1091
+ color: var(--text-muted);
1092
+ font-size: 1rem;
1093
+ text-align: center;
1094
+ padding: 1rem;
1095
+ }
1096
+
1097
+ .image-placeholder .icon {
1098
+ font-size: 3rem;
1099
+ margin-bottom: 1rem;
1100
+ opacity: 0.6;
1101
+ }
1102
+
1103
+ /* Image controls overlay */
1104
+ .image-controls {
1105
+ position: absolute;
1106
+ bottom: 0;
1107
+ left: 0;
1108
+ right: 0;
1109
+ padding: 0.75rem;
1110
+ background: linear-gradient(to top, rgba(0,0,0,0.7), rgba(0,0,0,0));
1111
+ display: flex;
1112
+ justify-content: flex-end;
1113
+ opacity: 0;
1114
+ transition: opacity 0.2s;
1115
+ }
1116
+
1117
+ .image-output-container:hover .image-controls {
1118
+ opacity: 1;
1119
+ }
1120
+
1121
+ .image-control-button {
1122
+ background-color: rgba(255, 255, 255, 0.9);
1123
+ border: none;
1124
+ border-radius: 50%;
1125
+ width: 36px;
1126
+ height: 36px;
1127
+ display: flex;
1128
+ align-items: center;
1129
+ justify-content: center;
1130
+ cursor: pointer;
1131
+ margin-left: 0.5rem;
1132
+ color: var(--text-color);
1133
+ transition: all 0.2s;
1134
+ }
1135
+
1136
+ .image-control-button:hover {
1137
+ background-color: white;
1138
+ transform: translateY(-2px);
1139
+ box-shadow: var(--shadow);
1140
+ }
1141
+
1142
+ /* Character counter */
1143
+ .character-counter {
1144
+ text-align: right;
1145
+ font-size: 0.75rem;
1146
+ color: var(--text-muted);
1147
+ margin-top: 0.25rem;
1148
+ transition: color 0.2s;
1149
+ }
1150
+
1151
+ .character-counter.warning {
1152
+ color: var(--warning-color);
1153
+ }
1154
+
1155
+ .character-counter.error {
1156
+ color: var(--error-color);
1157
+ }
1158
+
1159
+ /* Status message */
1160
+ .status-message {
1161
+ padding: 0.75rem 1rem;
1162
+ border-radius: var(--radius);
1163
+ margin: 1rem 0;
1164
+ font-size: 0.875rem;
1165
+ display: flex;
1166
+ align-items: center;
1167
+ }
1168
+
1169
+ .status-message .icon {
1170
+ margin-right: 0.75rem;
1171
+ font-size: 1.25rem;
1172
+ }
1173
+
1174
+ .status-success {
1175
+ background-color: rgba(16, 185, 129, 0.1);
1176
+ color: var(--success-color);
1177
+ border-left: 3px solid var(--success-color);
1178
+ }
1179
+
1180
+ .status-error {
1181
+ background-color: rgba(239, 68, 68, 0.1);
1182
+ color: var(--error-color);
1183
+ border-left: 3px solid var(--error-color);
1184
+ }
1185
+
1186
+ .status-warning {
1187
+ background-color: rgba(245, 158, 11, 0.1);
1188
+ color: var(--warning-color);
1189
+ border-left: 3px solid var(--warning-color);
1190
+ }
1191
+
1192
+ .status-info {
1193
+ background-color: rgba(59, 130, 246, 0.1);
1194
+ color: var(--accent-color);
1195
+ border-left: 3px solid var(--accent-color);
1196
+ }
1197
+
1198
+ /* Responsive adjustments */
1199
+ @media (max-width: 768px) {
1200
+ .example-gallery {
1201
+ grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
1202
+ }
1203
+
1204
+ .gr-panel {
1205
+ padding: 0.75rem !important;
1206
+ }
1207
+
1208
+ .gr-accordion > div:first-child {
1209
+ padding: 0.625rem 0.75rem !important;
1210
+ }
1211
+
1212
+ .gr-accordion > div:last-child {
1213
+ padding: 0.75rem !important;
1214
+ }
1215
+
1216
+ button.primary {
1217
+ padding: 0.625rem 1.25rem !important;
1218
+ }
1219
+ }
1220
+ """
1221
+
1222
+ # =============== ENHANCED UI COMPONENTS ===============
1223
+
1224
+ # Function to create and show application UI
1225
+ def create_ui():
1226
+ with gr.Blocks(title="AI Image Creator", css=css) as interface:
1227
+ # Custom header with branding
1228
+ with gr.Row(elem_classes="app-header"):
1229
+ with gr.Column():
1230
+ gr.HTML("""
1231
+ <h1>🎨 AI Image Creator</h1>
1232
+ <p>Transform your ideas into stunning images with AI-powered text-to-image generation</p>
1233
+ """)
1234
+
1235
+ # Main content area
1236
+ with gr.Row(equal_height=False):
1237
+ # Left column - Input controls
1238
+ with gr.Column(scale=1, min_width=380):
1239
+ # Description input with character counter
1240
+ with gr.Group(elem_classes="input-group"):
1241
+ description_input = gr.Textbox(
1242
+ label="Describe what you want to see",
1243
+ placeholder="Be detailed and specific about colors, composition, lighting, and subject...",
1244
+ lines=4,
1245
+ max_lines=8,
1246
+ elem_id="description-input"
1247
+ )
1248
+
1249
+ # Character counter with dynamic updates
1250
+ char_counter = gr.HTML(
1251
+ value="<div class='character-counter'>0 characters</div>",
1252
+ elem_classes="char-counter-container"
1253
+ )
1254
+
1255
+ # Examples gallery with clear visual structure
1256
+ with gr.Group(elem_classes="examples-group"):
1257
+ gr.HTML("<h3 style='margin-top: 0; font-size: 1rem; margin-bottom: 0.75rem;'>🌟 Try an example:</h3>")
1258
+
1259
+ # Gallery of examples
1260
+ with gr.Row(elem_classes="example-gallery"):
1261
+ for i, example in enumerate(EXAMPLE_PROMPTS):
1262
+ with gr.Column(elem_classes="example-item"):
1263
+ # Example card with visual element and caption
1264
+ example_card = gr.Button(
1265
+ example["thumbnail_desc"],
1266
+ elem_classes="example-button"
1267
+ )
1268
+
1269
+ # Event handler for example selection
1270
+ example_card.click(
1271
+ fn=lambda idx=i: load_example(idx),
1272
+ outputs=[description_input, creation_type, art_style, mood_dropdown]
1273
+ )
1274
+
1275
+ # Creation settings with enhanced dropdowns
1276
+ with gr.Group(elem_classes="settings-group"):
1277
+ gr.HTML("<h3 style='margin-top: 0; font-size: 1rem; margin-bottom: 0.75rem;'>🛠️ Image Settings</h3>")
1278
+
1279
+ # Creation Type and Art Style in one row
1280
+ with gr.Row():
1281
+ # Creation type dropdown with icons
1282
+ creation_type = gr.Dropdown(
1283
+ choices=format_dropdown_choices(CREATION_TYPES),
1284
+ value=f"{CREATION_TYPES['Digital Art']['icon']} Digital Art",
1285
+ label="Creation Type",
1286
+ elem_classes="enhanced-dropdown"
1287
+ )
1288
+
1289
+ # Art style dropdown with icons
1290
+ art_style = gr.Dropdown(
1291
+ choices=format_dropdown_choices(ART_STYLES),
1292
+ value=f"{ART_STYLES['Photorealistic']['icon']} Photorealistic",
1293
+ label="Art Style",
1294
+ elem_classes="enhanced-dropdown"
1295
+ )
1296
+
1297
+ # Mood and Model in one row
1298
+ with gr.Row():
1299
+ # Mood dropdown with icons
1300
+ mood_dropdown = gr.Dropdown(
1301
+ choices=format_dropdown_choices(MOODS),
1302
+ value=f"{MOODS['Peaceful']['icon']} Peaceful",
1303
+ label="Mood",
1304
+ elem_classes="enhanced-dropdown"
1305
+ )
1306
+
1307
+ # Model selector with display names
1308
+ formatted_models = [f"{info['icon']} {info['display_name']}" for model_key, info in IMAGE_MODELS.items()]
1309
+ model_selector = gr.Dropdown(
1310
+ choices=formatted_models,
1311
+ value=f"{IMAGE_MODELS['stabilityai/stable-diffusion-xl-base-1.0']['icon']} {IMAGE_MODELS['stabilityai/stable-diffusion-xl-base-1.0']['display_name']}",
1312
+ label="Model",
1313
+ elem_classes="enhanced-dropdown"
1314
+ )
1315
+
1316
+ # Information panels for selected options
1317
+ with gr.Group(elem_classes="info-panels"):
1318
+ # Creation type info
1319
+ creation_info = gr.HTML(value="", elem_classes="option-info")
1320
+
1321
+ # Art style info
1322
+ art_info = gr.HTML(value="", elem_classes="option-info")
1323
+
1324
+ # Model info panel
1325
+ model_info = gr.HTML(value="", elem_classes="option-info")
1326
+
1327
+ # Generate button with clear call to action
1328
+ with gr.Group(elem_classes="action-group"):
1329
+ # Generate button with progress indicator
1330
+ generate_button = gr.Button(
1331
+ "✨ Generate Image",
1332
+ variant="primary",
1333
+ elem_classes="primary",
1334
+ elem_id="generate-button"
1335
+ )
1336
+
1337
+ # Generation status message
1338
+ generation_status = gr.HTML(value="", elem_classes="generation-status")
1339
+
1340
+ # Tips section in collapsible accordion
1341
+ with gr.Accordion("📝 Tips for better results", open=True):
1342
+ gr.HTML("""
1343
+ <div class="tips-container">
1344
+ <h3>Tips for better results:</h3>
1345
+ <ul>
1346
+ <li><strong>Be specific and detailed</strong> - Include information about subjects, environment, lighting, colors, perspective, time of day, etc.</li>
1347
+ <li><strong>Use descriptive adjectives</strong> - Words like "vibrant", "moody", "ethereal", "weathered" help set the tone.</li>
1348
+ <li><strong>Experiment with art styles</strong> - Different styles can dramatically change the look and feel.</li>
1349
+ <li><strong>Combine with the right model</strong> - SDXL provides the highest quality but takes longer.</li>
1350
+ <li><strong>Think about composition</strong> - Mention foreground/background elements and their relationships.</li>
1351
+ </ul>
1352
+ </div>
1353
+ """)
1354
+
1355
+ # Right column - Output display
1356
+ with gr.Column(scale=1, min_width=480):
1357
+ # Image display area with placeholder
1358
+ with gr.Group(elem_classes="output-container"):
1359
+ # Output image with interactive elements
1360
+ image_output = gr.Image(
1361
+ label="Generated Image",
1362
+ elem_id="image-output",
1363
+ type="pil",
1364
+ height=512
1365
+ )
1366
+
1367
+ # Image generation details
1368
+ with gr.Accordion("Image Details", open=True):
1369
+ parameters_display = gr.HTML(value="")
1370
+
1371
+ # Enhanced prompt display
1372
+ with gr.Accordion("Enhanced Prompt", open=False):
1373
+ prompt_output = gr.Textbox(
1374
+ label="AI-Enhanced Prompt Used",
1375
+ lines=5,
1376
+ elem_id="prompt-output",
1377
+ elem_classes="prompt-display"
1378
+ )
1379
+
1380
+ # Technical details for advanced users
1381
+ with gr.Accordion("Technical Details", open=False):
1382
+ technical_info = gr.HTML("""
1383
+ <div class="technical-info">
1384
+ <h4>How Image Generation Works</h4>
1385
+ <p>Images are generated using Stable Diffusion, a latent text-to-image diffusion model. Your text prompt is:
1386
+ <ol>
1387
+ <li>Enhanced with AI to add descriptive details and quality terms</li>
1388
+ <li>Processed through a neural network that gradually transforms random noise into an image</li>
1389
+ <li>Refined based on the parameters you select (model, style, mood)</li>
1390
+ </ol>
1391
+ </p>
1392
+ <p>Different models have different strengths:
1393
+ <ul>
1394
+ <li><strong>SDXL 1.0</strong>: Highest quality, best composition and details</li>
1395
+ <li><strong>SD 1.5</strong>: Faster generation, good for general purpose</li>
1396
+ <li><strong>SD 2.1</strong>: Better with human faces, improved consistency</li>
1397
+ <li><strong>OpenJourney</strong>: Midjourney-like stylized artistic results</li>
1398
+ <li><strong>Dreamlike</strong>: Dreamy, ethereal aesthetic with artistic flair</li>
1399
+ </ul>
1400
+ </p>
1401
+ </div>
1402
+ """)
1403
+
1404
+ # Return all the UI components that need event handlers
1405
+ return interface, description_input, creation_type, art_style, mood_dropdown, model_selector, generate_button, image_output, generation_status, prompt_output, parameters_display, char_counter, creation_info, art_info, model_info
1406
+
1407
+ # Helper function to update character count with color coding
1408
+ def update_char_count(text):
1409
+ count = len(text)
1410
+ if count == 0:
1411
+ color_class = ""
1412
+ elif count < 20:
1413
+ color_class = "warning"
1414
+ elif count > 300:
1415
+ color_class = "warning"
1416
+ elif count > 500:
1417
+ color_class = "error"
1418
+ else:
1419
+ color_class = ""
1420
+
1421
+ return f"<div class='character-counter {color_class}'>{count} characters</div>"
1422
+
1423
+ # Helper function to update creation type info
1424
+ def update_creation_info(choice):
1425
+ key = extract_key(choice)
1426
+ if key in CREATION_TYPES:
1427
+ info = CREATION_TYPES[key]
1428
+ return f"""<div class="info-card">
1429
+ <h3>{info['icon']} {key}</h3>
1430
+ <p>{info['description']}</p>
1431
+ <p style="margin-top: 0.5rem; font-style: italic; opacity: 0.8;">💡 {info['prompt_hint']}</p>
1432
+ </div>"""
1433
+ return ""
1434
+
1435
+ # Helper function to update art style info
1436
+ def update_art_style_info(choice):
1437
+ key = extract_key(choice)
1438
+ if key in ART_STYLES:
1439
+ info = ART_STYLES[key]
1440
+ return f"""<div class="info-card">
1441
+ <h3>{info['icon']} {key}</h3>
1442
+ <p>{info['description']}</p>
1443
+ <p style="margin-top: 0.5rem; font-style: italic; opacity: 0.8;">🎨 Examples: {info['examples']}</p>
1444
+ </div>"""
1445
+ return ""
1446
+
1447
+ # Helper function to update model info
1448
+ def update_model_info(formatted_choice):
1449
+ # Extract display name without the icon
1450
+ if ' ' in formatted_choice:
1451
+ display_name = formatted_choice.split(' ', 1)[1]
1452
+ # Find the corresponding key and info
1453
+ for key, info in IMAGE_MODELS.items():
1454
+ if info['display_name'] == display_name:
1455
+ # Create speed badge
1456
+ speed_badge = ""
1457
+ if info.get('speed') == 'fast':
1458
+ speed_badge = '<span class="badge badge-success">Fast</span>'
1459
+ elif info.get('speed') == 'medium':
1460
+ speed_badge = '<span class="badge badge-warning">Medium</span>'
1461
+ elif info.get('speed') == 'slow':
1462
+ speed_badge = '<span class="badge badge-error">Slower</span>'
1463
+
1464
+ # Create quality badge
1465
+ quality_badge = ""
1466
+ if info.get('quality') == 'excellent':
1467
+ quality_badge = '<span class="badge badge-success">Excellent Quality</span>'
1468
+ elif info.get('quality') == 'very good':
1469
+ quality_badge = '<span class="badge badge-success">Very Good Quality</span>'
1470
+ elif info.get('quality') == 'good':
1471
+ quality_badge = '<span class="badge badge-info">Good Quality</span>'
1472
+ elif info.get('quality') == 'stylized':
1473
+ quality_badge = '<span class="badge badge-info">Stylized</span>'
1474
+ elif info.get('quality') == 'artistic':
1475
+ quality_badge = '<span class="badge badge-info">Artistic</span>'
1476
+
1477
+ return f"""<div class="model-info">
1478
+ <h3>{info['icon']} {info['display_name']} {speed_badge} {quality_badge}</h3>
1479
+ <p>{info['description']}</p>
1480
+ <div class="model-id">{key}</div>
1481
+ </div>"""
1482
+ return ""
1483
+
1484
+ # Helper function to update status message
1485
+ def update_status(message, is_error=False, is_warning=False, is_info=False):
1486
+ if is_error:
1487
+ status_class = "status-error"
1488
+ icon = "❌"
1489
+ elif is_warning:
1490
+ status_class = "status-warning"
1491
+ icon = "⚠️"
1492
+ elif is_info:
1493
+ status_class = "status-info"
1494
+ icon = "ℹ️"
1495
+ else:
1496
+ status_class = "status-success"
1497
+ icon = "✅"
1498
+
1499
+ return f"""<div class="status-message {status_class}">
1500
+ <span class="icon">{icon}</span>
1501
+ <span>{message}</span>
1502
+ </div>"""
1503
+
1504
+ # Helper function to format parameters display as pills
1505
+ def format_parameters(creation_type_val, art_style_val, mood_val, model_name):
1506
+ creation_key = extract_key(creation_type_val)
1507
+ art_key = extract_key(art_style_val)
1508
+ mood_key = extract_key(mood_val)
1509
+
1510
+ # Get model info
1511
+ model_display_name = "Unknown Model"
1512
+ model_id = ""
1513
+ model_icon = "🤖"
1514
+ for key, info in IMAGE_MODELS.items():
1515
+ if f"{info['icon']} {info['display_name']}" == model_name:
1516
+ model_display_name = info['display_name']
1517
+ model_id = key
1518
+ model_icon = info['icon']
1519
+ break
1520
+
1521
+ html = """<div style="margin-bottom: 1rem;">
1522
+ <div style="font-weight: 500; margin-bottom: 0.75rem;">Generated with these parameters:</div>
1523
+ <div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">"""
1524
+
1525
+ # Add creation type pill
1526
+ if creation_key in CREATION_TYPES:
1527
+ html += f"""<div class="parameter-pill">
1528
+ <span class="icon">{CREATION_TYPES[creation_key]['icon']}</span> {creation_key}
1529
+ </div>"""
1530
+
1531
+ # Add art style pill
1532
+ if art_key in ART_STYLES:
1533
+ html += f"""<div class="parameter-pill">
1534
+ <span class="icon">{ART_STYLES[art_key]['icon']}</span> {art_key}
1535
+ </div>"""
1536
+
1537
+ # Add mood pill
1538
+ if mood_key in MOODS:
1539
+ html += f"""<div class="parameter-pill">
1540
+ <span class="icon">{MOODS[mood_key]['icon']}</span> {mood_key}
1541
+ </div>"""
1542
+
1543
+ # Add model pill
1544
+ html += f"""<div class="parameter-pill">
1545
+ <span class="icon">{model_icon}</span> {model_display_name}
1546
+ </div>"""
1547
+
1548
+ # Close container
1549
+ html += """</div>
1550
+ <div style="margin-top: 1rem; font-size: 0.75rem; color: var(--text-muted);">
1551
+ Image generated on {timestamp}
1552
+ </div>
1553
+ </div>""".replace("{timestamp}", time.strftime("%Y-%m-%d at %H:%M:%S"))
1554
+
1555
+ return html
1556
+
1557
  # AI Image Creator: Enhanced UI and UX
1558
  # Part 3: Processing Logic, Prompt Enhancement, and Application Flow
1559