arpit13 commited on
Commit
fbe6b95
·
verified ·
1 Parent(s): bb51924

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +2021 -0
app.py ADDED
@@ -0,0 +1,2021 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ import os
10
+ from huggingface_hub import InferenceClient
11
+ from PIL import Image
12
+ import io
13
+ import base64
14
+
15
+ # Set up logging
16
+ logging.basicConfig(
17
+ level=logging.INFO,
18
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
19
+ handlers=[logging.StreamHandler(sys.stdout)]
20
+ )
21
+ logger = logging.getLogger("ai_image_creator")
22
+
23
+ # =============== MODEL CLIENTS SETUP ===============
24
+ def setup_client(api_key, provider=None):
25
+ """Initialize and return API client"""
26
+ try:
27
+ if provider:
28
+ client = InferenceClient(provider=provider, api_key=api_key)
29
+ logger.info(f"{provider} client initialized successfully")
30
+ else:
31
+ client = InferenceClient(api_key=api_key)
32
+ logger.info("Hugging Face client initialized successfully")
33
+ return client
34
+ except Exception as e:
35
+ logger.error(f"Error initializing client: {str(e)}")
36
+ return None
37
+
38
+ # Initialize clients
39
+ try:
40
+ # Replace with your actual HF API key
41
+ hf_api_key = os.getenv("HF_API_KEY1")
42
+
43
+ hf_client = setup_client(hf_api_key)
44
+ logger.info("Hugging Face client created successfully")
45
+
46
+ # Set up Llama client if API key is provided
47
+ llama_api_key = os.getenv("HF_API_KEY2") # Replace with actual key if available
48
+ try:
49
+ llama_client = setup_client(llama_api_key, "sambanova")
50
+ use_llama = True
51
+ logger.info("Llama client created successfully")
52
+ except Exception as e:
53
+ logger.warning(f"Llama client not available: {str(e)}. Will use fallback enhancement.")
54
+ llama_client = None
55
+ use_llama = False
56
+ except Exception as e:
57
+ logger.error(f"Failed to create Hugging Face client: {str(e)}")
58
+ hf_client = None
59
+ llama_client = None
60
+ use_llama = False
61
+
62
+ # =============== DATA MODELS ===============
63
+
64
+ # Image Models with friendly names, descriptions and icons
65
+ IMAGE_MODELS = {
66
+ "stabilityai/stable-diffusion-xl-base-1.0": {
67
+ "display_name": "SDXL 1.0",
68
+ "description": "Best overall quality, slower generation",
69
+ "icon": "⭐",
70
+ "speed": "slow",
71
+ "quality": "excellent"
72
+ },
73
+ "runwayml/stable-diffusion-v1-5": {
74
+ "display_name": "SD 1.5",
75
+ "description": "Good for general purpose, faster generation",
76
+ "icon": "🚀",
77
+ "speed": "fast",
78
+ "quality": "good"
79
+ },
80
+ "stabilityai/stable-diffusion-2-1": {
81
+ "display_name": "SD 2.1",
82
+ "description": "Improved details, balanced speed and quality",
83
+ "icon": "✨",
84
+ "speed": "medium",
85
+ "quality": "very good"
86
+ },
87
+ "prompthero/openjourney": {
88
+ "display_name": "OpenJourney",
89
+ "description": "Midjourney-like stylized results",
90
+ "icon": "🎨",
91
+ "speed": "medium",
92
+ "quality": "stylized"
93
+ },
94
+ "dreamlike-art/dreamlike-diffusion-1.0": {
95
+ "display_name": "Dreamlike",
96
+ "description": "Artistic style with dreamy aesthetics",
97
+ "icon": "💫",
98
+ "speed": "medium",
99
+ "quality": "artistic"
100
+ }
101
+ }
102
+
103
+ # Creation types with icons and detailed descriptions
104
+ CREATION_TYPES = {
105
+ "Realistic Photo": {
106
+ "description": "Create a photorealistic image with natural details and lighting",
107
+ "icon": "📷",
108
+ "prompt_hint": "Try to include details about lighting, time of day, and environment"
109
+ },
110
+ "Digital Art": {
111
+ "description": "Create colorful digital artwork with clean lines and vibrant colors",
112
+ "icon": "🖌️",
113
+ "prompt_hint": "Consider specifying color palette and mood for better results"
114
+ },
115
+ "Fantasy Illustration": {
116
+ "description": "Create magical and fantastical scenes with otherworldly elements",
117
+ "icon": "🧙",
118
+ "prompt_hint": "Describe magical elements, creatures, and environments in detail"
119
+ },
120
+ "Concept Art": {
121
+ "description": "Create professional concept art for characters, environments or objects",
122
+ "icon": "🎮",
123
+ "prompt_hint": "Include details about perspective, purpose, and design influences"
124
+ },
125
+ "Anime/Manga": {
126
+ "description": "Create Japanese anime or manga style illustration",
127
+ "icon": "🍙",
128
+ "prompt_hint": "Specify anime aesthetics like shading style and character features"
129
+ },
130
+ "Oil Painting": {
131
+ "description": "Create an image with oil painting textures and artistic brushstrokes",
132
+ "icon": "🖼️",
133
+ "prompt_hint": "Consider describing texture, brushwork style, and canvas feel"
134
+ },
135
+ "Watercolor": {
136
+ "description": "Create a soft watercolor illustration with subtle color blending",
137
+ "icon": "💧",
138
+ "prompt_hint": "Mention color blending, paper texture, and watercolor-specific effects"
139
+ },
140
+ "Sketch": {
141
+ "description": "Create a detailed sketch or drawing with line art focus",
142
+ "icon": "✏️",
143
+ "prompt_hint": "Describe line weight, hatching style, and sketch medium (pencil, charcoal, etc.)"
144
+ },
145
+ "3D Rendering": {
146
+ "description": "Create an image that looks like a 3D rendered scene with realistic lighting",
147
+ "icon": "💻",
148
+ "prompt_hint": "Include details about lighting setup, materials, and camera perspective"
149
+ },
150
+ "Pixel Art": {
151
+ "description": "Create retro-style pixel art with limited color palette",
152
+ "icon": "👾",
153
+ "prompt_hint": "Specify resolution, color limitations, and pixel art style (e.g., 16-bit, 8-bit)"
154
+ }
155
+ }
156
+
157
+ # Art styles with icons and detailed descriptions
158
+ ART_STYLES = {
159
+ "Photorealistic": {
160
+ "description": "Detailed realistic style that resembles a photograph with accurate lighting and textures",
161
+ "icon": "📸",
162
+ "examples": "Works by Chuck Close, Richard Estes, or modern 3D renderings"
163
+ },
164
+ "Impressionist": {
165
+ "description": "Soft brushstrokes that capture light and atmosphere over precise details, like Monet",
166
+ "icon": "🌈",
167
+ "examples": "Claude Monet, Pierre-Auguste Renoir, Camille Pissarro"
168
+ },
169
+ "Surrealist": {
170
+ "description": "Dreamlike quality with impossible or irrational scenes, like Salvador Dali",
171
+ "icon": "🌀",
172
+ "examples": "Salvador Dali, René Magritte, Frida Kahlo"
173
+ },
174
+ "Pop Art": {
175
+ "description": "Bold colors, sharp lines and popular culture references, like Andy Warhol",
176
+ "icon": "🎭",
177
+ "examples": "Andy Warhol, Roy Lichtenstein, Keith Haring"
178
+ },
179
+ "Minimalist": {
180
+ "description": "Simplified forms, limited color palette, and clean composition with minimal elements",
181
+ "icon": "⬜",
182
+ "examples": "Piet Mondrian, Kazimir Malevich, Agnes Martin"
183
+ },
184
+ "Abstract": {
185
+ "description": "Non-representational style using shapes, colors, and forms to express ideas",
186
+ "icon": "🔶",
187
+ "examples": "Wassily Kandinsky, Jackson Pollock, Mark Rothko"
188
+ },
189
+ "Cubist": {
190
+ "description": "Geometric shapes and multiple perspectives shown simultaneously, like Picasso",
191
+ "icon": "📐",
192
+ "examples": "Pablo Picasso, Georges Braque, Juan Gris"
193
+ },
194
+ "Art Nouveau": {
195
+ "description": "Ornate, flowing lines inspired by natural forms with decorative elegance",
196
+ "icon": "🌿",
197
+ "examples": "Alphonse Mucha, Gustav Klimt, Antoni Gaudí"
198
+ },
199
+ "Gothic": {
200
+ "description": "Dark, medieval-inspired aesthetic with dramatic lighting and architectural elements",
201
+ "icon": "🏰",
202
+ "examples": "Zdzisław Beksiński, H.R. Giger, medieval architecture"
203
+ },
204
+ "Cyberpunk": {
205
+ "description": "Futuristic dystopian style with neon colors, technology, and urban decay",
206
+ "icon": "🤖",
207
+ "examples": "Blade Runner, Ghost in the Shell, Akira"
208
+ },
209
+ "Steampunk": {
210
+ "description": "Victorian-era aesthetic combined with steam-powered technology and brass elements",
211
+ "icon": "⚙️",
212
+ "examples": "Works by James Ng, Keith Thompson, retrofuturistic Jules Verne adaptations"
213
+ },
214
+ "Retro/Vintage": {
215
+ "description": "Nostalgic style reminiscent of past decades with period-appropriate elements",
216
+ "icon": "📺",
217
+ "examples": "1950s advertisements, vintage travel posters, pulp magazine covers"
218
+ },
219
+ "Art Deco": {
220
+ "description": "Geometric patterns, bold colors, and luxurious materials in a symmetrical style",
221
+ "icon": "🏢",
222
+ "examples": "Works from the 1920s-30s, Chrysler Building, Tamara de Lempicka paintings"
223
+ },
224
+ "Baroque": {
225
+ "description": "Dramatic, ornate style with rich details, contrast, and dynamic composition",
226
+ "icon": "👑",
227
+ "examples": "Caravaggio, Rembrandt, Peter Paul Rubens"
228
+ },
229
+ "Ukiyo-e": {
230
+ "description": "Traditional Japanese woodblock print style with flat areas of color and strong outlines",
231
+ "icon": "🌊",
232
+ "examples": "Hokusai's Great Wave, Hiroshige's landscapes, traditional Japanese prints"
233
+ },
234
+ "Comic Book": {
235
+ "description": "Bold outlines, bright colors, and action-oriented composition like classic comics",
236
+ "icon": "💥",
237
+ "examples": "Jack Kirby, Steve Ditko, modern Marvel/DC art styles"
238
+ },
239
+ "Psychedelic": {
240
+ "description": "Vibrant, swirling colors with abstract patterns inspired by 1960s art",
241
+ "icon": "🌈",
242
+ "examples": "1960s concert posters, Peter Max, Alex Grey"
243
+ },
244
+ "Vaporwave": {
245
+ "description": "Glitch aesthetics with pastel colors, 80s/90s nostalgia and digital elements",
246
+ "icon": "📼",
247
+ "examples": "Retrowave aesthetics, 80s digital graphics, glitch art"
248
+ },
249
+ "Studio Ghibli": {
250
+ "description": "Whimsical, detailed animation style inspired by Japanese animated films",
251
+ "icon": "🐉",
252
+ "examples": "Spirited Away, My Neighbor Totoro, Howl's Moving Castle"
253
+ },
254
+ "Hyperrealism": {
255
+ "description": "Extremely detailed realism that exceeds photograph-like precision",
256
+ "icon": "🔍",
257
+ "examples": "Works by Roberto Bernardi, Denis Peterson, Gottfried Helnwein"
258
+ }
259
+ }
260
+
261
+ # Moods with icons and descriptions
262
+ MOODS = {
263
+ "Happy": {
264
+ "description": "Bright, cheerful atmosphere with warm colors",
265
+ "icon": "😊",
266
+ "color_palette": "Warm and vibrant colors: yellows, bright oranges, light blues"
267
+ },
268
+ "Sad": {
269
+ "description": "Melancholic atmosphere with muted colors",
270
+ "icon": "😢",
271
+ "color_palette": "Muted blues, grays, desaturated colors, cool tones"
272
+ },
273
+ "Mysterious": {
274
+ "description": "Enigmatic atmosphere with shadows and hidden elements",
275
+ "icon": "🔮",
276
+ "color_palette": "Deep purples, dark blues, hints of teal, selective lighting"
277
+ },
278
+ "Peaceful": {
279
+ "description": "Serene, calm atmosphere with gentle lighting",
280
+ "icon": "🕊️",
281
+ "color_palette": "Soft blues, gentle greens, pastel colors, balanced light"
282
+ },
283
+ "Tense": {
284
+ "description": "Suspenseful atmosphere with dramatic lighting",
285
+ "icon": "😰",
286
+ "color_palette": "High contrast, dark shadows, selective reds, strong highlights"
287
+ },
288
+ "Whimsical": {
289
+ "description": "Playful, imaginative atmosphere with fanciful elements",
290
+ "icon": "🦄",
291
+ "color_palette": "Pastels, candy colors, unexpected color combinations"
292
+ },
293
+ "Dark": {
294
+ "description": "Gloomy atmosphere with deep shadows and low lighting",
295
+ "icon": "🌑",
296
+ "color_palette": "Dark blues, blacks, deep greens, minimal highlights"
297
+ },
298
+ "Energetic": {
299
+ "description": "Dynamic, vibrant atmosphere with strong colors and movement",
300
+ "icon": "⚡",
301
+ "color_palette": "Saturated primary colors, bold contrasts, vibrant hues"
302
+ },
303
+ "Romantic": {
304
+ "description": "Soft, dreamy atmosphere with warm, gentle lighting",
305
+ "icon": "❤️",
306
+ "color_palette": "Soft pinks, gentle reds, golden highlights, warm tones"
307
+ },
308
+ "Epic": {
309
+ "description": "Grand, impressive atmosphere with dramatic scale and lighting",
310
+ "icon": "🏔️",
311
+ "color_palette": "Bold colors, dramatic contrast, atmospheric lighting, expansive scale"
312
+ }
313
+ }
314
+
315
+ # Example prompts with rich metadata
316
+ EXAMPLE_PROMPTS = [
317
+ {
318
+ "text": "A serene lake at sunset with mountains in the background and a small wooden boat floating nearby",
319
+ "thumbnail_desc": "Peaceful lake scene at sunset",
320
+ "creation_type": "Realistic Photo",
321
+ "art_style": "Photorealistic",
322
+ "mood": "Peaceful",
323
+ "tags": ["nature", "landscape", "water", "sunset"]
324
+ },
325
+ {
326
+ "text": "A futuristic cityscape with flying cars, neon lights, and tall skyscrapers under a night sky with two moons",
327
+ "thumbnail_desc": "Futuristic city with flying cars",
328
+ "creation_type": "Concept Art",
329
+ "art_style": "Cyberpunk",
330
+ "mood": "Mysterious",
331
+ "tags": ["scifi", "future", "urban", "night"]
332
+ },
333
+ {
334
+ "text": "A close-up portrait of an elderly craftsman with weathered hands working on an intricate wooden carving in his workshop",
335
+ "thumbnail_desc": "Elderly craftsman working with wood",
336
+ "creation_type": "Oil Painting",
337
+ "art_style": "Hyperrealism",
338
+ "mood": "Peaceful",
339
+ "tags": ["portrait", "craftsmanship", "elderly", "detail"]
340
+ },
341
+ {
342
+ "text": "A magical forest with glowing mushrooms, fairy lights, and a small cottage with smoke coming from the chimney",
343
+ "thumbnail_desc": "Magical forest with glowing elements",
344
+ "creation_type": "Fantasy Illustration",
345
+ "art_style": "Studio Ghibli",
346
+ "mood": "Whimsical",
347
+ "tags": ["fantasy", "forest", "magic", "cottage"]
348
+ },
349
+ {
350
+ "text": "A cybernetic samurai with glowing blue circuits standing in a rainy Tokyo street at night",
351
+ "thumbnail_desc": "Cybernetic samurai in rainy Tokyo",
352
+ "creation_type": "Digital Art",
353
+ "art_style": "Cyberpunk",
354
+ "mood": "Dark",
355
+ "tags": ["character", "cyberpunk", "samurai", "rain"]
356
+ },
357
+ {
358
+ "text": "A cute cat with dragon wings and tiny horns sleeping on a pile of gold coins",
359
+ "thumbnail_desc": "Cat with dragon features on gold",
360
+ "creation_type": "Fantasy Illustration",
361
+ "art_style": "Comic Book",
362
+ "mood": "Whimsical",
363
+ "tags": ["creature", "fantasy", "cute", "treasure"]
364
+ },
365
+ {
366
+ "text": "An ancient temple covered in vines and moss, partially sunken into a crystal-clear cenote in the jungle",
367
+ "thumbnail_desc": "Ancient temple in jungle cenote",
368
+ "creation_type": "Concept Art",
369
+ "art_style": "Photorealistic",
370
+ "mood": "Mysterious",
371
+ "tags": ["architecture", "ruins", "jungle", "water"]
372
+ },
373
+ {
374
+ "text": "A cozy coffee shop interior with rain falling outside the windows, soft lighting, and a few people reading books",
375
+ "thumbnail_desc": "Cozy rainy day in coffee shop",
376
+ "creation_type": "Digital Art",
377
+ "art_style": "Impressionist",
378
+ "mood": "Peaceful",
379
+ "tags": ["interior", "rainy", "cozy", "urban"]
380
+ }
381
+ ]
382
+
383
+ # CSS for enhanced UI styling - Will be included in part 2
384
+
385
+ # =============== HELPER FUNCTIONS ===============
386
+
387
+ # Helper function to format dropdown choices with icons
388
+ def format_dropdown_choices(options_dict):
389
+ return [f"{options_dict[key].get('icon', '•')} {key}" for key in options_dict.keys()]
390
+
391
+ # Helper function to extract the key from formatted choice
392
+ def extract_key(formatted_choice):
393
+ # Skip the icon and space at the beginning
394
+ parts = formatted_choice.split(' ', 1)
395
+ if len(parts) > 1:
396
+ return parts[1]
397
+ return formatted_choice
398
+
399
+ # Function to load example prompt
400
+ def load_example(example_index):
401
+ if example_index < 0 or example_index >= len(EXAMPLE_PROMPTS):
402
+ return "", "", "", ""
403
+
404
+ example = EXAMPLE_PROMPTS[example_index]
405
+ creation = f"{CREATION_TYPES[example['creation_type']]['icon']} {example['creation_type']}"
406
+ art = f"{ART_STYLES[example['art_style']]['icon']} {example['art_style']}"
407
+ mood = f"{MOODS[example['mood']]['icon']} {example['mood']}"
408
+
409
+ return example["text"], creation, art, mood
410
+
411
+ # Get model key from formatted display name
412
+ def get_model_key(formatted_name):
413
+ # Extract display name without the icon
414
+ if ' ' in formatted_name:
415
+ display_name = formatted_name.split(' ', 1)[1]
416
+ # Find the corresponding key
417
+ for key, info in IMAGE_MODELS.items():
418
+ if info['display_name'] == display_name:
419
+ return key
420
+ return list(IMAGE_MODELS.keys())[0] # Default to first model if not found
421
+
422
+ # AI Image Creator: Enhanced UI and UX
423
+ # Part 2: Enhanced UI Components and Styling
424
+
425
+ # CSS for styling the interface - Comprehensive styling for modern UI
426
+ css = """
427
+ /* Main theme colors with CSS variables for better customization */
428
+ :root {
429
+ --primary-color: #4F46E5;
430
+ --primary-hover: #4338CA;
431
+ --secondary-color: #7C3AED;
432
+ --secondary-hover: #6D28D9;
433
+ --background-color: #F8FAFC;
434
+ --card-color: #FFFFFF;
435
+ --text-color: #1E293B;
436
+ --text-muted: #64748B;
437
+ --accent-color: #3B82F6;
438
+ --success-color: #10B981;
439
+ --success-hover: #059669;
440
+ --warning-color: #F59E0B;
441
+ --error-color: #EF4444;
442
+ --error-hover: #DC2626;
443
+ --border-color: #E2E8F0;
444
+ --border-hover: #CBD5E1;
445
+ --shadow-sm: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
446
+ --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
447
+ --shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
448
+ --radius-sm: 0.375rem;
449
+ --radius: 0.5rem;
450
+ --radius-lg: 0.75rem;
451
+ --radius-xl: 1rem;
452
+ --font-sans: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
453
+ }
454
+
455
+ /* Global styles and resets */
456
+ body, html {
457
+ font-family: var(--font-sans);
458
+ color: var(--text-color);
459
+ background-color: var(--background-color);
460
+ line-height: 1.5;
461
+ margin: 0;
462
+ padding: 0;
463
+ }
464
+
465
+ /* Container with responsive padding */
466
+ .container {
467
+ max-width: 1400px;
468
+ margin: 0 auto;
469
+ padding: 1rem;
470
+ }
471
+
472
+ @media (max-width: 640px) {
473
+ .container {
474
+ padding: 0.5rem;
475
+ }
476
+ }
477
+
478
+ /* Card styling with elevation and hover effects */
479
+ .gr-panel {
480
+ border-radius: var(--radius) !important;
481
+ border: 1px solid var(--border-color) !important;
482
+ box-shadow: var(--shadow) !important;
483
+ overflow: hidden;
484
+ transition: transform 0.2s, box-shadow 0.2s;
485
+ background-color: var(--card-color) !important;
486
+ }
487
+
488
+ .gr-panel:hover {
489
+ transform: translateY(-2px);
490
+ box-shadow: var(--shadow-lg) !important;
491
+ }
492
+
493
+ /* Button styling with gradient and hover states */
494
+ button.primary {
495
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color)) !important;
496
+ color: white !important;
497
+ border: none !important;
498
+ border-radius: var(--radius) !important;
499
+ font-weight: 600 !important;
500
+ letter-spacing: 0.025em !important;
501
+ padding: 0.75rem 1.5rem !important;
502
+ transition: all 0.3s ease !important;
503
+ box-shadow: var(--shadow-sm) !important;
504
+ outline: none !important;
505
+ text-transform: none !important;
506
+ }
507
+
508
+ button.primary:hover {
509
+ transform: translateY(-1px);
510
+ box-shadow: var(--shadow) !important;
511
+ opacity: 0.9;
512
+ }
513
+
514
+ button.primary:active {
515
+ transform: translateY(0);
516
+ opacity: 0.8;
517
+ }
518
+
519
+ button.primary[disabled], button.primary[disabled]:hover {
520
+ opacity: 0.5;
521
+ cursor: not-allowed;
522
+ transform: none;
523
+ }
524
+
525
+ /* Secondary button styling */
526
+ button.secondary {
527
+ background-color: transparent !important;
528
+ color: var(--primary-color) !important;
529
+ border: 1px solid var(--primary-color) !important;
530
+ border-radius: var(--radius) !important;
531
+ font-weight: 500 !important;
532
+ padding: 0.625rem 1.25rem !important;
533
+ transition: all 0.2s ease !important;
534
+ text-transform: none !important;
535
+ }
536
+
537
+ button.secondary:hover {
538
+ background-color: rgba(79, 70, 229, 0.05) !important;
539
+ border-color: var(--primary-hover) !important;
540
+ }
541
+
542
+ /* Style for the example buttons */
543
+ .example-button {
544
+ font-size: 0.875rem !important;
545
+ padding: 0.5rem 0.75rem !important;
546
+ background-color: transparent !important;
547
+ border: 1px solid var(--border-color) !important;
548
+ border-radius: var(--radius) !important;
549
+ transition: all 0.2s !important;
550
+ text-align: left !important;
551
+ justify-content: flex-start !important;
552
+ height: auto !important;
553
+ text-overflow: ellipsis;
554
+ overflow: hidden;
555
+ white-space: nowrap;
556
+ width: 100%;
557
+ color: var(--text-color) !important;
558
+ }
559
+
560
+ .example-button:hover {
561
+ background-color: rgba(79, 70, 229, 0.05) !important;
562
+ border-color: var(--primary-color) !important;
563
+ transform: translateY(-1px);
564
+ }
565
+
566
+ /* Form controls styling */
567
+ .gr-input, .gr-textarea, .gr-dropdown {
568
+ border-radius: var(--radius) !important;
569
+ border: 1px solid var(--border-color) !important;
570
+ transition: border-color 0.2s, box-shadow 0.2s !important;
571
+ font-family: var(--font-sans) !important;
572
+ color: var(--text-color) !important;
573
+ }
574
+
575
+ .gr-input:focus, .gr-textarea:focus, .gr-dropdown:focus-within {
576
+ border-color: var(--primary-color) !important;
577
+ box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2) !important;
578
+ outline: none !important;
579
+ }
580
+
581
+ .gr-form {
582
+ gap: 1rem !important;
583
+ }
584
+
585
+ .gr-input-label, .gr-dropdown-label, .gr-textarea-label, .gr-checkbox-label, .gr-radio-label {
586
+ font-size: 0.875rem !important;
587
+ font-weight: 500 !important;
588
+ color: var(--text-color) !important;
589
+ margin-bottom: 0.25rem !important;
590
+ }
591
+
592
+ /* Input placeholder styling */
593
+ .gr-input::placeholder, .gr-textarea::placeholder {
594
+ color: var(--text-muted) !important;
595
+ opacity: 0.7;
596
+ }
597
+
598
+ /* Input and textarea styling */
599
+ textarea, input[type="text"] {
600
+ border-radius: var(--radius) !important;
601
+ border: 1px solid var(--border-color) !important;
602
+ padding: 0.75rem 1rem !important;
603
+ transition: border-color 0.2s, box-shadow 0.2s !important;
604
+ font-family: var(--font-sans) !important;
605
+ }
606
+
607
+ textarea:focus, input[type="text"]:focus {
608
+ border-color: var(--primary-color) !important;
609
+ box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.2) !important;
610
+ outline: none !important;
611
+ }
612
+
613
+ /* Dropdown styling */
614
+ .gr-dropdown {
615
+ border-radius: var(--radius) !important;
616
+ border: 1px solid var(--border-color) !important;
617
+ background-color: var(--card-color) !important;
618
+ }
619
+
620
+ .gr-dropdown > div {
621
+ border-radius: var(--radius) !important;
622
+ min-height: 38px !important;
623
+ }
624
+
625
+ .gr-dropdown > div > span {
626
+ font-size: 0.9375rem !important;
627
+ }
628
+
629
+ /* Dropdown menu styling */
630
+ .gr-dropdown ul {
631
+ background-color: var(--card-color) !important;
632
+ border: 1px solid var(--border-color) !important;
633
+ border-radius: var(--radius) !important;
634
+ box-shadow: var(--shadow) !important;
635
+ }
636
+
637
+ .gr-dropdown ul li {
638
+ padding: 0.5rem 0.75rem !important;
639
+ }
640
+
641
+ .gr-dropdown ul li:hover {
642
+ background-color: rgba(79, 70, 229, 0.05) !important;
643
+ }
644
+
645
+ /* Custom header with gradient background */
646
+ .app-header {
647
+ text-align: center;
648
+ padding: 1.75rem 1rem;
649
+ margin-bottom: 2rem;
650
+ background: linear-gradient(135deg, rgba(79, 70, 229, 0.08), rgba(124, 58, 237, 0.08));
651
+ border-radius: var(--radius-lg);
652
+ border-bottom: 3px solid var(--primary-color);
653
+ position: relative;
654
+ overflow: hidden;
655
+ }
656
+
657
+ .app-header::before {
658
+ content: '';
659
+ position: absolute;
660
+ top: -50px;
661
+ left: -50px;
662
+ right: -50px;
663
+ height: 100px;
664
+ background: linear-gradient(135deg, rgba(79, 70, 229, 0.2), rgba(124, 58, 237, 0.2));
665
+ transform: rotate(-5deg);
666
+ z-index: 0;
667
+ }
668
+
669
+ .app-header h1 {
670
+ font-size: 2.5rem !important;
671
+ font-weight: 800 !important;
672
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
673
+ -webkit-background-clip: text;
674
+ -webkit-text-fill-color: transparent;
675
+ margin-bottom: 0.5rem !important;
676
+ position: relative;
677
+ z-index: 1;
678
+ }
679
+
680
+ .app-header p {
681
+ font-size: 1.25rem !important;
682
+ color: var(--text-color);
683
+ opacity: 0.8;
684
+ max-width: 40rem;
685
+ margin: 0 auto;
686
+ position: relative;
687
+ z-index: 1;
688
+ }
689
+
690
+ /* Responsive header */
691
+ @media (max-width: 640px) {
692
+ .app-header h1 {
693
+ font-size: 2rem !important;
694
+ }
695
+
696
+ .app-header p {
697
+ font-size: 1rem !important;
698
+ }
699
+ }
700
+
701
+ /* Examples gallery with grid layout */
702
+ .example-gallery {
703
+ display: grid;
704
+ grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
705
+ gap: 1rem;
706
+ margin: 1rem 0;
707
+ }
708
+
709
+ .example-item {
710
+ border-radius: var(--radius);
711
+ overflow: hidden;
712
+ cursor: pointer;
713
+ border: 2px solid transparent;
714
+ transition: all 0.2s;
715
+ display: flex;
716
+ flex-direction: column;
717
+ background-color: var(--card-color);
718
+ }
719
+
720
+ .example-item:hover {
721
+ transform: translateY(-2px);
722
+ border-color: var(--accent-color);
723
+ box-shadow: var(--shadow);
724
+ }
725
+
726
+ .example-item:active {
727
+ transform: translateY(0);
728
+ }
729
+
730
+ .example-item-image {
731
+ width: 100%;
732
+ aspect-ratio: 1;
733
+ background-color: #f0f0f0;
734
+ display: flex;
735
+ align-items: center;
736
+ justify-content: center;
737
+ color: var(--text-muted);
738
+ font-size: 1.5rem;
739
+ border-bottom: 1px solid var(--border-color);
740
+ }
741
+
742
+ .example-item-caption {
743
+ padding: 0.5rem;
744
+ font-size: 0.75rem;
745
+ line-height: 1.25;
746
+ color: var(--text-color);
747
+ overflow: hidden;
748
+ display: -webkit-box;
749
+ -webkit-line-clamp: 2;
750
+ -webkit-box-orient: vertical;
751
+ }
752
+
753
+ /* Loading indicator with animation */
754
+ .loading-indicator {
755
+ display: flex;
756
+ align-items: center;
757
+ justify-content: center;
758
+ height: 100%;
759
+ width: 100%;
760
+ position: absolute;
761
+ top: 0;
762
+ left: 0;
763
+ background-color: rgba(255, 255, 255, 0.8);
764
+ z-index: 1000;
765
+ backdrop-filter: blur(2px);
766
+ border-radius: var(--radius);
767
+ }
768
+
769
+ .spinner {
770
+ width: 40px;
771
+ height: 40px;
772
+ border: 4px solid rgba(79, 70, 229, 0.2);
773
+ border-radius: 50%;
774
+ border-top-color: var(--primary-color);
775
+ animation: spin 1s linear infinite;
776
+ }
777
+
778
+ @keyframes spin {
779
+ to {
780
+ transform: rotate(360deg);
781
+ }
782
+ }
783
+
784
+ /* Info cards with subtle styling */
785
+ .info-card {
786
+ background-color: var(--card-color);
787
+ border-radius: var(--radius);
788
+ padding: 1rem;
789
+ border: 1px solid var(--border-color);
790
+ margin-bottom: 1rem;
791
+ transition: all 0.2s;
792
+ }
793
+
794
+ .info-card:hover {
795
+ border-color: var(--border-hover);
796
+ box-shadow: var(--shadow-sm);
797
+ }
798
+
799
+ .info-card h3 {
800
+ margin-top: 0;
801
+ margin-bottom: 0.5rem;
802
+ font-size: 1rem;
803
+ font-weight: 600;
804
+ color: var(--primary-color);
805
+ display: flex;
806
+ align-items: center;
807
+ gap: 0.5rem;
808
+ }
809
+
810
+ .info-card p {
811
+ margin: 0;
812
+ font-size: 0.875rem;
813
+ color: var(--text-muted);
814
+ line-height: 1.5;
815
+ }
816
+
817
+ /* Model info panel with branded styling */
818
+ .model-info {
819
+ background-color: rgba(79, 70, 229, 0.05);
820
+ border-left: 3px solid var(--primary-color);
821
+ padding: 0.75rem 1rem;
822
+ border-radius: 0 var(--radius) var(--radius) 0;
823
+ margin: 1rem 0;
824
+ }
825
+
826
+ .model-info h3 {
827
+ display: flex;
828
+ align-items: center;
829
+ gap: 0.5rem;
830
+ margin-top: 0;
831
+ margin-bottom: 0.5rem;
832
+ font-size: 1rem;
833
+ font-weight: 600;
834
+ color: var(--primary-color);
835
+ }
836
+
837
+ .model-info p {
838
+ margin: 0 0 0.5rem 0;
839
+ font-size: 0.875rem;
840
+ color: var(--text-color);
841
+ }
842
+
843
+ .model-info .model-id {
844
+ font-size: 0.75rem;
845
+ color: var(--text-muted);
846
+ font-family: monospace;
847
+ background-color: rgba(0, 0, 0, 0.03);
848
+ padding: 0.25rem 0.5rem;
849
+ border-radius: 4px;
850
+ margin-top: 0.5rem;
851
+ word-break: break-all;
852
+ }
853
+
854
+ /* Parameter pills for displaying selections */
855
+ .parameter-pill {
856
+ display: inline-flex;
857
+ align-items: center;
858
+ background-color: rgba(79, 70, 229, 0.1);
859
+ color: var(--primary-color);
860
+ border-radius: 16px;
861
+ padding: 0.25rem 0.75rem;
862
+ margin-right: 0.5rem;
863
+ margin-bottom: 0.5rem;
864
+ font-size: 0.75rem;
865
+ font-weight: 500;
866
+ user-select: none;
867
+ }
868
+
869
+ .parameter-pill .icon {
870
+ margin-right: 0.25rem;
871
+ }
872
+
873
+ /* Badge for showing model speed/quality */
874
+ .badge {
875
+ display: inline-flex;
876
+ align-items: center;
877
+ justify-content: center;
878
+ border-radius: 9999px;
879
+ padding: 0.125rem 0.5rem;
880
+ font-size: 0.75rem;
881
+ font-weight: 500;
882
+ margin-left: 0.5rem;
883
+ }
884
+
885
+ .badge-success {
886
+ background-color: rgba(16, 185, 129, 0.1);
887
+ color: var(--success-color);
888
+ }
889
+
890
+ .badge-warning {
891
+ background-color: rgba(245, 158, 11, 0.1);
892
+ color: var(--warning-color);
893
+ }
894
+
895
+ .badge-error {
896
+ background-color: rgba(239, 68, 68, 0.1);
897
+ color: var(--error-color);
898
+ }
899
+
900
+ .badge-info {
901
+ background-color: rgba(59, 130, 246, 0.1);
902
+ color: var(--accent-color);
903
+ }
904
+
905
+ /* Enhanced accordion styling */
906
+ .gr-accordion {
907
+ border: 1px solid var(--border-color) !important;
908
+ border-radius: var(--radius) !important;
909
+ margin-bottom: 1rem !important;
910
+ overflow: hidden;
911
+ }
912
+
913
+ .gr-accordion > div:first-child {
914
+ padding: 0.75rem 1rem !important;
915
+ background-color: rgba(0, 0, 0, 0.02) !important;
916
+ font-weight: 600 !important;
917
+ color: var(--text-color) !important;
918
+ font-size: 0.9375rem !important;
919
+ }
920
+
921
+ .gr-accordion > div:last-child {
922
+ padding: 1rem !important;
923
+ }
924
+
925
+ /* Tooltip styling */
926
+ .tooltip {
927
+ position: relative;
928
+ display: inline-block;
929
+ cursor: help;
930
+ }
931
+
932
+ .tooltip .tooltiptext {
933
+ visibility: hidden;
934
+ width: 200px;
935
+ background-color: var(--text-color);
936
+ color: white;
937
+ text-align: center;
938
+ border-radius: var(--radius-sm);
939
+ padding: 0.5rem 0.75rem;
940
+ position: absolute;
941
+ z-index: 1000;
942
+ bottom: 125%;
943
+ left: 50%;
944
+ transform: translateX(-50%);
945
+ opacity: 0;
946
+ transition: opacity 0.3s;
947
+ font-size: 0.75rem;
948
+ box-shadow: var(--shadow);
949
+ pointer-events: none;
950
+ }
951
+
952
+ .tooltip .tooltiptext::after {
953
+ content: "";
954
+ position: absolute;
955
+ top: 100%;
956
+ left: 50%;
957
+ margin-left: -5px;
958
+ border-width: 5px;
959
+ border-style: solid;
960
+ border-color: var(--text-color) transparent transparent transparent;
961
+ }
962
+
963
+ .tooltip:hover .tooltiptext {
964
+ visibility: visible;
965
+ opacity: 1;
966
+ }
967
+
968
+ /* History item styling */
969
+ .history-item {
970
+ display: flex;
971
+ align-items: center;
972
+ padding: 0.75rem;
973
+ border-radius: var(--radius);
974
+ margin-bottom: 0.75rem;
975
+ background-color: var(--card-color);
976
+ border: 1px solid var(--border-color);
977
+ cursor: pointer;
978
+ transition: all 0.2s;
979
+ }
980
+
981
+ .history-item:hover {
982
+ background-color: rgba(79, 70, 229, 0.05);
983
+ transform: translateY(-1px);
984
+ }
985
+
986
+ .history-item-image {
987
+ width: 48px;
988
+ height: 48px;
989
+ border-radius: var(--radius-sm);
990
+ object-fit: cover;
991
+ margin-right: 0.75rem;
992
+ background-color: #f0f0f0;
993
+ display: flex;
994
+ align-items: center;
995
+ justify-content: center;
996
+ color: var(--text-muted);
997
+ font-size: 1.25rem;
998
+ }
999
+
1000
+ .history-item-content {
1001
+ flex: 1;
1002
+ overflow: hidden;
1003
+ }
1004
+
1005
+ .history-item-title {
1006
+ margin: 0;
1007
+ font-size: 0.875rem;
1008
+ font-weight: 500;
1009
+ white-space: nowrap;
1010
+ overflow: hidden;
1011
+ text-overflow: ellipsis;
1012
+ color: var(--text-color);
1013
+ }
1014
+
1015
+ .history-item-subtitle {
1016
+ margin: 0;
1017
+ font-size: 0.75rem;
1018
+ color: var(--text-muted);
1019
+ margin-top: 0.25rem;
1020
+ }
1021
+
1022
+ /* Tabs styling */
1023
+ .tabs {
1024
+ display: flex;
1025
+ border-bottom: 1px solid var(--border-color);
1026
+ margin-bottom: 1rem;
1027
+ }
1028
+
1029
+ .tab {
1030
+ padding: 0.75rem 1rem;
1031
+ cursor: pointer;
1032
+ border-bottom: 2px solid transparent;
1033
+ font-weight: 500;
1034
+ font-size: 0.9375rem;
1035
+ color: var(--text-muted);
1036
+ transition: all 0.2s;
1037
+ }
1038
+
1039
+ .tab:hover {
1040
+ color: var(--primary-color);
1041
+ }
1042
+
1043
+ .tab.active {
1044
+ color: var(--primary-color);
1045
+ border-bottom-color: var(--primary-color);
1046
+ }
1047
+
1048
+ /* Progress bar */
1049
+ .progress-container {
1050
+ width: 100%;
1051
+ height: 8px;
1052
+ background-color: rgba(79, 70, 229, 0.1);
1053
+ border-radius: 4px;
1054
+ overflow: hidden;
1055
+ margin: 0.5rem 0;
1056
+ }
1057
+
1058
+ .progress-bar {
1059
+ height: 100%;
1060
+ background: linear-gradient(to right, var(--primary-color), var(--secondary-color));
1061
+ width: 0%;
1062
+ transition: width 0.3s ease;
1063
+ border-radius: 4px;
1064
+ }
1065
+
1066
+ /* Image output container */
1067
+ .image-output-container {
1068
+ position: relative;
1069
+ border-radius: var(--radius);
1070
+ overflow: hidden;
1071
+ transition: all 0.2s;
1072
+ background-color: #f5f5f5;
1073
+ min-height: 300px;
1074
+ }
1075
+
1076
+ .image-output-container img {
1077
+ width: 100%;
1078
+ display: block;
1079
+ border-radius: var(--radius);
1080
+ }
1081
+
1082
+ .image-placeholder {
1083
+ position: absolute;
1084
+ top: 0;
1085
+ left: 0;
1086
+ width: 100%;
1087
+ height: 100%;
1088
+ display: flex;
1089
+ flex-direction: column;
1090
+ align-items: center;
1091
+ justify-content: center;
1092
+ color: var(--text-muted);
1093
+ font-size: 1rem;
1094
+ text-align: center;
1095
+ padding: 1rem;
1096
+ }
1097
+
1098
+ .image-placeholder .icon {
1099
+ font-size: 3rem;
1100
+ margin-bottom: 1rem;
1101
+ opacity: 0.6;
1102
+ }
1103
+
1104
+ /* Image controls overlay */
1105
+ .image-controls {
1106
+ position: absolute;
1107
+ bottom: 0;
1108
+ left: 0;
1109
+ right: 0;
1110
+ padding: 0.75rem;
1111
+ background: linear-gradient(to top, rgba(0,0,0,0.7), rgba(0,0,0,0));
1112
+ display: flex;
1113
+ justify-content: flex-end;
1114
+ opacity: 0;
1115
+ transition: opacity 0.2s;
1116
+ }
1117
+
1118
+ .image-output-container:hover .image-controls {
1119
+ opacity: 1;
1120
+ }
1121
+
1122
+ .image-control-button {
1123
+ background-color: rgba(255, 255, 255, 0.9);
1124
+ border: none;
1125
+ border-radius: 50%;
1126
+ width: 36px;
1127
+ height: 36px;
1128
+ display: flex;
1129
+ align-items: center;
1130
+ justify-content: center;
1131
+ cursor: pointer;
1132
+ margin-left: 0.5rem;
1133
+ color: var(--text-color);
1134
+ transition: all 0.2s;
1135
+ }
1136
+
1137
+ .image-control-button:hover {
1138
+ background-color: white;
1139
+ transform: translateY(-2px);
1140
+ box-shadow: var(--shadow);
1141
+ }
1142
+
1143
+ /* Character counter */
1144
+ .character-counter {
1145
+ text-align: right;
1146
+ font-size: 0.75rem;
1147
+ color: var(--text-muted);
1148
+ margin-top: 0.25rem;
1149
+ transition: color 0.2s;
1150
+ }
1151
+
1152
+ .character-counter.warning {
1153
+ color: var(--warning-color);
1154
+ }
1155
+
1156
+ .character-counter.error {
1157
+ color: var(--error-color);
1158
+ }
1159
+
1160
+ /* Status message */
1161
+ .status-message {
1162
+ padding: 0.75rem 1rem;
1163
+ border-radius: var(--radius);
1164
+ margin: 1rem 0;
1165
+ font-size: 0.875rem;
1166
+ display: flex;
1167
+ align-items: center;
1168
+ }
1169
+
1170
+ .status-message .icon {
1171
+ margin-right: 0.75rem;
1172
+ font-size: 1.25rem;
1173
+ }
1174
+
1175
+ .status-success {
1176
+ background-color: rgba(16, 185, 129, 0.1);
1177
+ color: var(--success-color);
1178
+ border-left: 3px solid var(--success-color);
1179
+ }
1180
+
1181
+ .status-error {
1182
+ background-color: rgba(239, 68, 68, 0.1);
1183
+ color: var(--error-color);
1184
+ border-left: 3px solid var(--error-color);
1185
+ }
1186
+
1187
+ .status-warning {
1188
+ background-color: rgba(245, 158, 11, 0.1);
1189
+ color: var(--warning-color);
1190
+ border-left: 3px solid var(--warning-color);
1191
+ }
1192
+
1193
+ .status-info {
1194
+ background-color: rgba(59, 130, 246, 0.1);
1195
+ color: var(--accent-color);
1196
+ border-left: 3px solid var(--accent-color);
1197
+ }
1198
+
1199
+ /* Responsive adjustments */
1200
+ @media (max-width: 768px) {
1201
+ .example-gallery {
1202
+ grid-template-columns: repeat(auto-fill, minmax(110px, 1fr));
1203
+ }
1204
+
1205
+ .gr-panel {
1206
+ padding: 0.75rem !important;
1207
+ }
1208
+
1209
+ .gr-accordion > div:first-child {
1210
+ padding: 0.625rem 0.75rem !important;
1211
+ }
1212
+
1213
+ .gr-accordion > div:last-child {
1214
+ padding: 0.75rem !important;
1215
+ }
1216
+
1217
+ button.primary {
1218
+ padding: 0.625rem 1.25rem !important;
1219
+ }
1220
+ }
1221
+ """
1222
+
1223
+ # =============== ENHANCED UI COMPONENTS ===============
1224
+
1225
+ # Function to create and show application UI
1226
+ def create_ui():
1227
+ with gr.Blocks(title="AI Image Creator", css=css) as interface:
1228
+ # Custom header with branding
1229
+ with gr.Row(elem_classes="app-header"):
1230
+ with gr.Column():
1231
+ gr.HTML("""
1232
+ <h1>🎨 AI Image Creator</h1>
1233
+ <p>Transform your ideas into stunning images with AI-powered text-to-image generation</p>
1234
+ """)
1235
+
1236
+ # Main content area
1237
+ with gr.Row(equal_height=False):
1238
+ # Left column - Input controls
1239
+ with gr.Column(scale=1, min_width=380):
1240
+ # Description input with character counter
1241
+ with gr.Group(elem_classes="input-group"):
1242
+ description_input = gr.Textbox(
1243
+ label="Describe what you want to see",
1244
+ placeholder="Be detailed and specific about colors, composition, lighting, and subject...",
1245
+ lines=4,
1246
+ max_lines=8,
1247
+ elem_id="description-input"
1248
+ )
1249
+
1250
+ # Character counter with dynamic updates
1251
+ char_counter = gr.HTML(
1252
+ value="<div class='character-counter'>0 characters</div>",
1253
+ elem_classes="char-counter-container"
1254
+ )
1255
+
1256
+ # Creation settings with enhanced dropdowns
1257
+ with gr.Group(elem_classes="settings-group"):
1258
+ gr.HTML("<h3 style='margin-top: 0; font-size: 1rem; margin-bottom: 0.75rem;'>🛠️ Image Settings</h3>")
1259
+
1260
+ # Creation Type and Art Style in one row
1261
+ with gr.Row():
1262
+ # Creation type dropdown with icons
1263
+ creation_type = gr.Dropdown(
1264
+ choices=format_dropdown_choices(CREATION_TYPES),
1265
+ value=f"{CREATION_TYPES['Digital Art']['icon']} Digital Art",
1266
+ label="Creation Type",
1267
+ elem_classes="enhanced-dropdown"
1268
+ )
1269
+
1270
+ # Art style dropdown with icons
1271
+ art_style = gr.Dropdown(
1272
+ choices=format_dropdown_choices(ART_STYLES),
1273
+ value=f"{ART_STYLES['Photorealistic']['icon']} Photorealistic",
1274
+ label="Art Style",
1275
+ elem_classes="enhanced-dropdown"
1276
+ )
1277
+
1278
+ # Mood and Model in one row
1279
+ with gr.Row():
1280
+ # Mood dropdown with icons
1281
+ mood_dropdown = gr.Dropdown(
1282
+ choices=format_dropdown_choices(MOODS),
1283
+ value=f"{MOODS['Peaceful']['icon']} Peaceful",
1284
+ label="Mood",
1285
+ elem_classes="enhanced-dropdown"
1286
+ )
1287
+
1288
+ # Model selector with display names
1289
+ formatted_models = [f"{info['icon']} {info['display_name']}" for model_key, info in IMAGE_MODELS.items()]
1290
+ model_selector = gr.Dropdown(
1291
+ choices=formatted_models,
1292
+ value=f"{IMAGE_MODELS['stabilityai/stable-diffusion-xl-base-1.0']['icon']} {IMAGE_MODELS['stabilityai/stable-diffusion-xl-base-1.0']['display_name']}",
1293
+ label="Model",
1294
+ elem_classes="enhanced-dropdown"
1295
+ )
1296
+
1297
+ # Examples gallery with clear visual structure
1298
+ with gr.Group(elem_classes="examples-group"):
1299
+ gr.HTML("<h3 style='margin-top: 0; font-size: 1rem; margin-bottom: 0.75rem;'>🌟 Try an example:</h3>")
1300
+
1301
+ # Gallery of examples
1302
+ with gr.Row(elem_classes="example-gallery"):
1303
+ for i, example in enumerate(EXAMPLE_PROMPTS):
1304
+ with gr.Column(elem_classes="example-item"):
1305
+ # Example card with visual element and caption
1306
+ example_card = gr.Button(
1307
+ example["thumbnail_desc"],
1308
+ elem_classes="example-button"
1309
+ )
1310
+
1311
+ # Event handler for example selection
1312
+ example_card.click(
1313
+ fn=lambda idx=i: load_example(idx),
1314
+ outputs=[description_input, creation_type, art_style, mood_dropdown]
1315
+ )
1316
+
1317
+ # Information panels for selected options
1318
+ with gr.Group(elem_classes="info-panels"):
1319
+ # Creation type info
1320
+ creation_info = gr.HTML(value="", elem_classes="option-info")
1321
+
1322
+ # Art style info
1323
+ art_info = gr.HTML(value="", elem_classes="option-info")
1324
+
1325
+ # Model info panel
1326
+ model_info = gr.HTML(value="", elem_classes="option-info")
1327
+
1328
+ # Generate button with clear call to action
1329
+ with gr.Group(elem_classes="action-group"):
1330
+ # Generate button with progress indicator
1331
+ generate_button = gr.Button(
1332
+ "✨ Generate Image",
1333
+ variant="primary",
1334
+ elem_classes="primary",
1335
+ elem_id="generate-button"
1336
+ )
1337
+
1338
+ # Generation status message
1339
+ generation_status = gr.HTML(value="", elem_classes="generation-status")
1340
+
1341
+ # Tips section in collapsible accordion
1342
+ with gr.Accordion("📝 Tips for better results", open=True):
1343
+ gr.HTML("""
1344
+ <div class="tips-container">
1345
+ <h3>Tips for better results:</h3>
1346
+ <ul>
1347
+ <li><strong>Be specific and detailed</strong> - Include information about subjects, environment, lighting, colors, perspective, time of day, etc.</li>
1348
+ <li><strong>Use descriptive adjectives</strong> - Words like "vibrant", "moody", "ethereal", "weathered" help set the tone.</li>
1349
+ <li><strong>Experiment with art styles</strong> - Different styles can dramatically change the look and feel.</li>
1350
+ <li><strong>Combine with the right model</strong> - SDXL provides the highest quality but takes longer.</li>
1351
+ <li><strong>Think about composition</strong> - Mention foreground/background elements and their relationships.</li>
1352
+ </ul>
1353
+ </div>
1354
+ """)
1355
+
1356
+ # Right column - Output display
1357
+ with gr.Column(scale=1, min_width=480):
1358
+ # Image display area with placeholder
1359
+ with gr.Group(elem_classes="output-container"):
1360
+ # Output image with interactive elements
1361
+ image_output = gr.Image(
1362
+ label="Generated Image",
1363
+ elem_id="image-output",
1364
+ type="pil",
1365
+ height=512
1366
+ )
1367
+
1368
+ # Image generation details
1369
+ with gr.Accordion("Image Details", open=True):
1370
+ parameters_display = gr.HTML(value="")
1371
+
1372
+ # Enhanced prompt display
1373
+ with gr.Accordion("Enhanced Prompt", open=False):
1374
+ prompt_output = gr.Textbox(
1375
+ label="AI-Enhanced Prompt Used",
1376
+ lines=5,
1377
+ elem_id="prompt-output",
1378
+ elem_classes="prompt-display"
1379
+ )
1380
+
1381
+ # Technical details for advanced users
1382
+ with gr.Accordion("Technical Details", open=False):
1383
+ technical_info = gr.HTML("""
1384
+ <div class="technical-info">
1385
+ <h4>How Image Generation Works</h4>
1386
+ <p>Images are generated using Stable Diffusion, a latent text-to-image diffusion model. Your text prompt is:
1387
+ <ol>
1388
+ <li>Enhanced with AI to add descriptive details and quality terms</li>
1389
+ <li>Processed through a neural network that gradually transforms random noise into an image</li>
1390
+ <li>Refined based on the parameters you select (model, style, mood)</li>
1391
+ </ol>
1392
+ </p>
1393
+ <p>Different models have different strengths:
1394
+ <ul>
1395
+ <li><strong>SDXL 1.0</strong>: Highest quality, best composition and details</li>
1396
+ <li><strong>SD 1.5</strong>: Faster generation, good for general purpose</li>
1397
+ <li><strong>SD 2.1</strong>: Better with human faces, improved consistency</li>
1398
+ <li><strong>OpenJourney</strong>: Midjourney-like stylized artistic results</li>
1399
+ <li><strong>Dreamlike</strong>: Dreamy, ethereal aesthetic with artistic flair</li>
1400
+ </ul>
1401
+ </p>
1402
+ </div>
1403
+ """)
1404
+
1405
+ # Set up event handlers within the Blocks context
1406
+ description_input.change(
1407
+ fn=update_char_count,
1408
+ inputs=description_input,
1409
+ outputs=char_counter
1410
+ )
1411
+
1412
+ creation_type.change(
1413
+ fn=update_creation_info,
1414
+ inputs=creation_type,
1415
+ outputs=creation_info
1416
+ )
1417
+
1418
+ art_style.change(
1419
+ fn=update_art_style_info,
1420
+ inputs=art_style,
1421
+ outputs=art_info
1422
+ )
1423
+
1424
+ model_selector.change(
1425
+ fn=update_model_info,
1426
+ inputs=model_selector,
1427
+ outputs=model_info
1428
+ )
1429
+
1430
+ generate_button.click(
1431
+ fn=generate_with_status,
1432
+ inputs=[
1433
+ description_input,
1434
+ creation_type,
1435
+ art_style,
1436
+ mood_dropdown,
1437
+ model_selector
1438
+ ],
1439
+ outputs=[
1440
+ image_output,
1441
+ generation_status,
1442
+ prompt_output,
1443
+ parameters_display
1444
+ ]
1445
+ )
1446
+
1447
+ # Load default values on page load
1448
+ interface.load(
1449
+ fn=lambda: (
1450
+ update_creation_info(f"{CREATION_TYPES['Digital Art']['icon']} Digital Art"),
1451
+ update_art_style_info(f"{ART_STYLES['Photorealistic']['icon']} Photorealistic"),
1452
+ update_model_info(f"{IMAGE_MODELS['stabilityai/stable-diffusion-xl-base-1.0']['icon']} {IMAGE_MODELS['stabilityai/stable-diffusion-xl-base-1.0']['display_name']}")
1453
+ ),
1454
+ outputs=[creation_info, art_info, model_info]
1455
+ )
1456
+
1457
+ 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
1458
+
1459
+ # Helper function to update character count with color coding
1460
+ def update_char_count(text):
1461
+ count = len(text)
1462
+ if count == 0:
1463
+ color_class = ""
1464
+ elif count < 20:
1465
+ color_class = "warning"
1466
+ elif count > 300:
1467
+ color_class = "warning"
1468
+ elif count > 500:
1469
+ color_class = "error"
1470
+ else:
1471
+ color_class = ""
1472
+
1473
+ return f"<div class='character-counter {color_class}'>{count} characters</div>"
1474
+
1475
+ # Helper function to update creation type info
1476
+ def update_creation_info(choice):
1477
+ key = extract_key(choice)
1478
+ if key in CREATION_TYPES:
1479
+ info = CREATION_TYPES[key]
1480
+ return f"""<div class="info-card">
1481
+ <h3>{info['icon']} {key}</h3>
1482
+ <p>{info['description']}</p>
1483
+ <p style="margin-top: 0.5rem; font-style: italic; opacity: 0.8;">💡 {info['prompt_hint']}</p>
1484
+ </div>"""
1485
+ return ""
1486
+
1487
+ # Helper function to update art style info
1488
+ def update_art_style_info(choice):
1489
+ key = extract_key(choice)
1490
+ if key in ART_STYLES:
1491
+ info = ART_STYLES[key]
1492
+ return f"""<div class="info-card">
1493
+ <h3>{info['icon']} {key}</h3>
1494
+ <p>{info['description']}</p>
1495
+ <p style="margin-top: 0.5rem; font-style: italic; opacity: 0.8;">🎨 Examples: {info['examples']}</p>
1496
+ </div>"""
1497
+ return ""
1498
+
1499
+ # Helper function to update model info
1500
+ def update_model_info(formatted_choice):
1501
+ # Extract display name without the icon
1502
+ if ' ' in formatted_choice:
1503
+ display_name = formatted_choice.split(' ', 1)[1]
1504
+ # Find the corresponding key and info
1505
+ for key, info in IMAGE_MODELS.items():
1506
+ if info['display_name'] == display_name:
1507
+ # Create speed badge
1508
+ speed_badge = ""
1509
+ if info.get('speed') == 'fast':
1510
+ speed_badge = '<span class="badge badge-success">Fast</span>'
1511
+ elif info.get('speed') == 'medium':
1512
+ speed_badge = '<span class="badge badge-warning">Medium</span>'
1513
+ elif info.get('speed') == 'slow':
1514
+ speed_badge = '<span class="badge badge-error">Slower</span>'
1515
+
1516
+ # Create quality badge
1517
+ quality_badge = ""
1518
+ if info.get('quality') == 'excellent':
1519
+ quality_badge = '<span class="badge badge-success">Excellent Quality</span>'
1520
+ elif info.get('quality') == 'very good':
1521
+ quality_badge = '<span class="badge badge-success">Very Good Quality</span>'
1522
+ elif info.get('quality') == 'good':
1523
+ quality_badge = '<span class="badge badge-info">Good Quality</span>'
1524
+ elif info.get('quality') == 'stylized':
1525
+ quality_badge = '<span class="badge badge-info">Stylized</span>'
1526
+ elif info.get('quality') == 'artistic':
1527
+ quality_badge = '<span class="badge badge-info">Artistic</span>'
1528
+
1529
+ return f"""<div class="model-info">
1530
+ <h3>{info['icon']} {info['display_name']} {speed_badge} {quality_badge}</h3>
1531
+ <p>{info['description']}</p>
1532
+ <div class="model-id">{key}</div>
1533
+ </div>"""
1534
+ return ""
1535
+
1536
+ # Helper function to update status message
1537
+ def update_status(message, is_error=False, is_warning=False, is_info=False):
1538
+ if is_error:
1539
+ status_class = "status-error"
1540
+ icon = "❌"
1541
+ elif is_warning:
1542
+ status_class = "status-warning"
1543
+ icon = "⚠️"
1544
+ elif is_info:
1545
+ status_class = "status-info"
1546
+ icon = "ℹ️"
1547
+ else:
1548
+ status_class = "status-success"
1549
+ icon = "✅"
1550
+
1551
+ return f"""<div class="status-message {status_class}">
1552
+ <span class="icon">{icon}</span>
1553
+ <span>{message}</span>
1554
+ </div>"""
1555
+
1556
+ # Helper function to format parameters display as pills
1557
+ def format_parameters(creation_type_val, art_style_val, mood_val, model_name):
1558
+ creation_key = extract_key(creation_type_val)
1559
+ art_key = extract_key(art_style_val)
1560
+ mood_key = extract_key(mood_val)
1561
+
1562
+ # Get model info
1563
+ model_display_name = "Unknown Model"
1564
+ model_id = ""
1565
+ model_icon = "🤖"
1566
+ for key, info in IMAGE_MODELS.items():
1567
+ if f"{info['icon']} {info['display_name']}" == model_name:
1568
+ model_display_name = info['display_name']
1569
+ model_id = key
1570
+ model_icon = info['icon']
1571
+ break
1572
+
1573
+ html = """<div style="margin-bottom: 1rem;">
1574
+ <div style="font-weight: 500; margin-bottom: 0.75rem;">Generated with these parameters:</div>
1575
+ <div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">"""
1576
+
1577
+ # Add creation type pill
1578
+ if creation_key in CREATION_TYPES:
1579
+ html += f"""<div class="parameter-pill">
1580
+ <span class="icon">{CREATION_TYPES[creation_key]['icon']}</span> {creation_key}
1581
+ </div>"""
1582
+
1583
+ # Add art style pill
1584
+ if art_key in ART_STYLES:
1585
+ html += f"""<div class="parameter-pill">
1586
+ <span class="icon">{ART_STYLES[art_key]['icon']}</span> {art_key}
1587
+ </div>"""
1588
+
1589
+ # Add mood pill
1590
+ if mood_key in MOODS:
1591
+ html += f"""<div class="parameter-pill">
1592
+ <span class="icon">{MOODS[mood_key]['icon']}</span> {mood_key}
1593
+ </div>"""
1594
+
1595
+ # Add model pill
1596
+ html += f"""<div class="parameter-pill">
1597
+ <span class="icon">{model_icon}</span> {model_display_name}
1598
+ </div>"""
1599
+
1600
+ # Close container
1601
+ html += """</div>
1602
+ <div style="margin-top: 1rem; font-size: 0.75rem; color: var(--text-muted);">
1603
+ Image generated on {timestamp}
1604
+ </div>
1605
+ </div>""".replace("{timestamp}", time.strftime("%Y-%m-%d at %H:%M:%S"))
1606
+
1607
+ return html
1608
+
1609
+ # AI Image Creator: Enhanced UI and UX
1610
+ # Part 3: Processing Logic, Prompt Enhancement, and Application Flow
1611
+
1612
+ # =============== PROMPT ENHANCEMENT LOGIC ===============
1613
+
1614
+ # Function to enhance prompt with Llama 4 with improved logical understanding
1615
+ def enhance_prompt_with_llama(user_input, creation_type, art_style, mood):
1616
+ """
1617
+ Enhance user input with Llama 4 model to create detailed image generation prompts
1618
+
1619
+ Args:
1620
+ user_input (str): User's original description
1621
+ creation_type (str): Selected creation type (e.g., "Digital Art")
1622
+ art_style (str): Selected art style (e.g., "Photorealistic")
1623
+ mood (str): Selected mood (e.g., "Peaceful")
1624
+
1625
+ Returns:
1626
+ str: Enhanced prompt optimized for image generation
1627
+ """
1628
+ try:
1629
+ if not use_llama or llama_client is None:
1630
+ logger.warning("Llama enhancement not available, using fallback")
1631
+ return enhance_prompt_fallback(user_input, creation_type, art_style, mood)
1632
+
1633
+ logger.info(f"Enhancing prompt with Llama 4 for creation type: {creation_type}, art style: {art_style}")
1634
+
1635
+ # Enhanced Llama 4 system prompt with detailed instructions
1636
+ system_prompt = """You are a world-class prompt engineer who specializes in creating detailed, effective prompts for text-to-image AI models.
1637
+
1638
+ Your task is to transform a user's simple description into a comprehensive, detailed image generation prompt that will create stunning visuals. Consider all the provided elements (description, creation type, art style, mood) and combine them into a cohesive, detailed prompt.
1639
+
1640
+ MOST IMPORTANTLY - ADD LOGICAL DETAILS:
1641
+ - Analyze what the user wants and add logical details that would make the scene realistic or coherent
1642
+ - If describing something fantastical (e.g., "flying cat"), add logical details about how this could work (e.g., "a cat with majestic feathered wings spread wide")
1643
+ - Think about environment, lighting, perspective, time of day, weather, and other contextual elements
1644
+ - Create a vivid, imaginable scene with spatial relationships clearly defined
1645
+
1646
+ PROMPT STRUCTURE GUIDELINES:
1647
+ 1. Start with the core subject and its primary characteristics
1648
+ 2. Add environment and setting details
1649
+ 3. Describe lighting, atmosphere, and mood
1650
+ 4. Include specific visual style and artistic technique references
1651
+ 5. Add technical quality terms (8K, detailed, masterful, etc.)
1652
+
1653
+ FORMAT YOUR RESPONSE AS A SINGLE PARAGRAPH with no additional comments, explanations, or bullet points. Use natural language without awkward comma separations. Aim for 75-150 words.
1654
+
1655
+ AVOID:
1656
+ - Do not include quotation marks in your response
1657
+ - Do not preface with "here's a prompt" or similar text
1658
+ - Do not use placeholders
1659
+ - Do not add negative prompts
1660
+ - Do not write in list format or use bullet points
1661
+
1662
+ Respond only with the enhanced prompt and nothing else."""
1663
+
1664
+ # Get creation type description
1665
+ creation_info = CREATION_TYPES.get(creation_type, {"description": "Create a detailed image", "icon": "🎨"})
1666
+ creation_description = creation_info["description"]
1667
+
1668
+ # Get art style description
1669
+ style_info = ART_STYLES.get(art_style, {"description": "with detailed and professional quality", "icon": "🖌️"})
1670
+ style_description = style_info["description"]
1671
+
1672
+ # Get mood description
1673
+ mood_info = MOODS.get(mood, {"description": "atmospheric", "icon": "✨"})
1674
+ mood_description = mood_info["description"]
1675
+
1676
+ # Prepare the user prompt for Llama
1677
+ user_prompt = f"""Description: {user_input}
1678
+ Creation Type: {creation_type} - {creation_description}
1679
+ Art Style: {art_style} - {style_description}
1680
+ Mood: {mood} - {mood_description}
1681
+
1682
+ Please create a comprehensive, detailed image generation prompt that combines all these elements."""
1683
+
1684
+ try:
1685
+ # Request enhancement from Llama 4
1686
+ completion = llama_client.chat.completions.create(
1687
+ model="meta-llama/Llama-4-Scout-17B-16E-Instruct",
1688
+ messages=[
1689
+ {"role": "system", "content": system_prompt},
1690
+ {"role": "user", "content": user_prompt}
1691
+ ],
1692
+ max_tokens=500,
1693
+ temperature=0.7, # Slight creativity while maintaining coherence
1694
+ )
1695
+ enhanced = completion.choices[0].message.content
1696
+ logger.info(f"Llama 4 enhanced prompt: {enhanced[:100]}...")
1697
+ return enhanced if enhanced else user_input
1698
+ except Exception as e:
1699
+ logger.error(f"Error during Llama enhancement: {str(e)}")
1700
+ return enhance_prompt_fallback(user_input, creation_type, art_style, mood)
1701
+ except Exception as e:
1702
+ logger.error(f"Error in Llama enhancement: {str(e)}")
1703
+ return enhance_prompt_fallback(user_input, creation_type, art_style, mood)
1704
+
1705
+ # Fallback prompt enhancement without Llama
1706
+ def enhance_prompt_fallback(user_input, creation_type, art_style, mood):
1707
+ """
1708
+ Enhance user input without requiring Llama API using rule-based enhancement
1709
+
1710
+ Args:
1711
+ user_input (str): User's original description
1712
+ creation_type (str): Selected creation type (e.g., "Digital Art")
1713
+ art_style (str): Selected art style (e.g., "Photorealistic")
1714
+ mood (str): Selected mood (e.g., "Peaceful")
1715
+
1716
+ Returns:
1717
+ str: Enhanced prompt using predefined rules and templates
1718
+ """
1719
+ logger.info(f"Using fallback enhancement for: {user_input[:50]}...")
1720
+
1721
+ # Quality terms by creation type
1722
+ quality_terms = {
1723
+ "Realistic Photo": [
1724
+ "photorealistic", "high resolution", "detailed",
1725
+ "natural lighting", "sharp focus", "professional photography",
1726
+ "crisp details", "realistic textures", "DSLR photo"
1727
+ ],
1728
+ "Digital Art": [
1729
+ "vibrant colors", "clean lines", "digital illustration",
1730
+ "polished", "professional digital art", "detailed rendering",
1731
+ "digital painting", "colorful", "vector-like precision"
1732
+ ],
1733
+ "Fantasy Illustration": [
1734
+ "magical atmosphere", "fantasy art", "detailed illustration",
1735
+ "epic", "otherworldly", "imaginative scene",
1736
+ "fantasy environment", "magical lighting", "mythical qualities"
1737
+ ],
1738
+ "Concept Art": [
1739
+ "professional concept art", "detailed design", "conceptual illustration",
1740
+ "industry standard", "visual development", "production artwork",
1741
+ "concept design", "detailed environment", "character design"
1742
+ ],
1743
+ "Anime/Manga": [
1744
+ "anime style", "manga illustration", "cel shaded",
1745
+ "Japanese animation", "2D character art", "anime aesthetic",
1746
+ "clean linework", "anime proportions", "stylized features"
1747
+ ],
1748
+ "Oil Painting": [
1749
+ "oil on canvas", "textured brushwork", "rich colors",
1750
+ "traditional painting", "artistic brushstrokes", "gallery quality",
1751
+ "glazed layers", "impasto technique", "classical painting style"
1752
+ ],
1753
+ "Watercolor": [
1754
+ "watercolor painting", "soft color bleeding", "delicate washes",
1755
+ "transparent layers", "loose brushwork", "gentle transitions",
1756
+ "watercolor paper texture", "wet-on-wet technique", "fluid color blending"
1757
+ ],
1758
+ "Sketch": [
1759
+ "detailed sketch", "pencil drawing", "line art",
1760
+ "hand-drawn", "fine details", "shading techniques",
1761
+ "graphite", "charcoal texture", "gestural lines"
1762
+ ],
1763
+ "3D Rendering": [
1764
+ "3D render", "volumetric lighting", "ray tracing",
1765
+ "3D modeling", "realistic textures", "computer graphics",
1766
+ "physically based rendering", "global illumination", "ambient occlusion"
1767
+ ],
1768
+ "Pixel Art": [
1769
+ "pixel art", "8-bit style", "retro game aesthetic",
1770
+ "limited color palette", "pixelated", "nostalgic game art",
1771
+ "16-bit look", "pixel perfect", "dithering effects"
1772
+ ]
1773
+ }
1774
+
1775
+ # Style modifiers for different art styles - more detailed descriptions
1776
+ style_modifiers = {
1777
+ "Photorealistic": "highly detailed photorealistic style with perfect lighting, natural shadows, and lifelike textures",
1778
+ "Impressionist": "impressionist style with visible brushstrokes capturing light and atmosphere over precise details, reminiscent of Claude Monet",
1779
+ "Surrealist": "surrealist style with dreamlike and impossible elements, juxtaposed reality, inspired by Salvador Dali",
1780
+ "Pop Art": "pop art style with bold colors, sharp lines, halftone patterns and cultural references, like Andy Warhol",
1781
+ "Minimalist": "minimalist style with simplified forms, limited color palette, clean composition, and essential elements only",
1782
+ "Abstract": "abstract style using non-representational shapes, colors, and forms to express emotion rather than reality",
1783
+ "Cubist": "cubist style with geometric forms, multiple perspectives shown simultaneously, fractured surfaces, like Pablo Picasso",
1784
+ "Art Nouveau": "art nouveau style with ornate flowing lines inspired by natural forms, decorative elegance, and organic shapes",
1785
+ "Gothic": "gothic style with dark atmosphere, dramatic elements, pointed arches, and medieval-inspired architecture",
1786
+ "Cyberpunk": "cyberpunk style with neon colors, high tech low life aesthetic, futuristic technology, and urban decay",
1787
+ "Steampunk": "steampunk style with Victorian aesthetics, brass machinery, steam-powered technology, and retrofuturistic design",
1788
+ "Retro/Vintage": "retro style with nostalgic elements from past decades, aged texture, and period-appropriate colors and design",
1789
+ "Art Deco": "art deco style with geometric patterns, bold colors, symmetry, luxurious materials, and streamlined forms",
1790
+ "Baroque": "baroque style with dramatic lighting, rich details, contrast, dynamic composition, and ornate decorations",
1791
+ "Ukiyo-e": "ukiyo-e style Japanese woodblock print aesthetic with flat areas of color, strong outlines, and traditional subjects",
1792
+ "Comic Book": "comic book style with bold outlines, vibrant colors, dynamic action poses, and expressive characters",
1793
+ "Psychedelic": "psychedelic style with vibrant swirling colors, abstract patterns, distorted perspective, and 1960s-inspired visuals",
1794
+ "Vaporwave": "vaporwave aesthetic with glitch art, pastel colors, 80s/90s nostalgia, ancient statues, and digital elements",
1795
+ "Studio Ghibli": "Studio Ghibli anime style with whimsical detailed environments, soft colors, and charming character design",
1796
+ "Hyperrealism": "hyperrealistic style with extreme detail beyond photography, perfect textures, and meticulous precision"
1797
+ }
1798
+
1799
+ # Mood modifiers for different moods - enhanced descriptions
1800
+ mood_modifiers = {
1801
+ "Happy": "bright cheerful atmosphere with warm golden lighting, vibrant colors, and uplifting elements",
1802
+ "Sad": "melancholic atmosphere with muted colors, soft shadows, and somber emotional tone",
1803
+ "Mysterious": "enigmatic atmosphere with shadows, fog, hidden elements, and dramatic lighting contrasts",
1804
+ "Peaceful": "serene calm atmosphere with gentle lighting, soft colors, and tranquil composition",
1805
+ "Tense": "suspenseful atmosphere with dramatic lighting, stark contrasts, and unsettling composition",
1806
+ "Whimsical": "playful whimsical atmosphere with imaginative elements, saturated colors, and fantastical details",
1807
+ "Dark": "dark gloomy atmosphere with deep shadows, limited lighting, and ominous elements",
1808
+ "Energetic": "dynamic vibrant atmosphere with strong colors, motion effects, and active composition",
1809
+ "Romantic": "soft romantic atmosphere with dreamy lighting, gentle colors, and intimate ambiance",
1810
+ "Epic": "grand epic atmosphere with dramatic scale, sweeping vistas, and majestic lighting"
1811
+ }
1812
+
1813
+ # Get terms for the specific creation type, or use generic terms
1814
+ type_terms = quality_terms.get(creation_type, [
1815
+ "high quality", "detailed", "professional", "masterful", "high resolution", "sharp details"
1816
+ ])
1817
+
1818
+ # Common quality terms enhanced with trending and technical terms
1819
+ common_terms = [
1820
+ "8K resolution", "highly detailed", "professional", "masterpiece",
1821
+ "trending on artstation", "award winning", "stunning", "intricate details",
1822
+ "perfect composition", "cinematic lighting"
1823
+ ]
1824
+
1825
+ # Get style modifier
1826
+ style_modifier = style_modifiers.get(art_style, "detailed professional style")
1827
+
1828
+ # Get mood modifier
1829
+ mood_modifier = mood_modifiers.get(mood, "atmospheric")
1830
+
1831
+ # Basic prompt structure - core subject and style elements
1832
+ prompt_parts = [
1833
+ user_input,
1834
+ style_modifier,
1835
+ mood_modifier
1836
+ ]
1837
+
1838
+ # Add randomly selected quality terms for variety
1839
+ selected_type_terms = random.sample(type_terms, min(3, len(type_terms)))
1840
+ selected_common_terms = random.sample(common_terms, min(3, len(common_terms)))
1841
+
1842
+ # Combine terms
1843
+ quality_description = ", ".join(selected_type_terms + selected_common_terms)
1844
+
1845
+ # Final enhanced prompt
1846
+ enhanced_prompt = f"{', '.join(prompt_parts)}, {quality_description}"
1847
+
1848
+ logger.info(f"Fallback enhanced prompt: {enhanced_prompt[:100]}...")
1849
+ return enhanced_prompt
1850
+
1851
+ # =============== IMAGE GENERATION FUNCTIONS ===============
1852
+
1853
+ # Generate image function with loading state handling and retry mechanism
1854
+ def generate_image(description, creation_type, art_style, mood, model_name, retries=1):
1855
+ """
1856
+ Generate image based on user inputs by enhancing prompt and calling image model API
1857
+
1858
+ Args:
1859
+ description (str): User's original description
1860
+ creation_type (str): Selected creation type
1861
+ art_style (str): Selected art style
1862
+ mood (str): Selected mood
1863
+ model_name (str): Model identifier
1864
+ retries (int): Number of retries if generation fails
1865
+
1866
+ Returns:
1867
+ tuple: (image, status_message, enhanced_prompt)
1868
+ """
1869
+ try:
1870
+ # Validate input
1871
+ if not description.strip():
1872
+ return None, "Please enter a description for your image", ""
1873
+
1874
+ logger.info(f"Generating image with model: {model_name}")
1875
+
1876
+ # Enhance prompt with Llama or fallback
1877
+ enhanced_prompt = enhance_prompt_with_llama(description, creation_type, art_style, mood)
1878
+
1879
+ # Validate client availability
1880
+ if hf_client is None:
1881
+ logger.error("Hugging Face client not available")
1882
+ return None, "Error: Unable to connect to image generation service. Please try again later.", enhanced_prompt
1883
+
1884
+ # Add negative prompt to avoid common issues
1885
+ negative_prompt = "low quality, blurry, distorted, deformed, disfigured, bad anatomy, watermark, signature, text, poorly drawn, amateur, ugly"
1886
+
1887
+ try:
1888
+ # Generate image with progress tracking
1889
+ logger.info(f"Sending request to model {model_name} with prompt: {enhanced_prompt[:100]}...")
1890
+
1891
+ # Log start time for performance tracking
1892
+ start_time = time.time()
1893
+
1894
+ # Generate the image
1895
+ image = hf_client.text_to_image(
1896
+ prompt=enhanced_prompt,
1897
+ model=model_name,
1898
+ negative_prompt=negative_prompt
1899
+ )
1900
+
1901
+ # Calculate generation time
1902
+ generation_time = time.time() - start_time
1903
+ logger.info(f"Image generated successfully in {generation_time:.2f} seconds")
1904
+
1905
+ # Success message with generation details
1906
+ if use_llama:
1907
+ enhancement_method = "Llama 4 AI"
1908
+ else:
1909
+ enhancement_method = "rule-based enhancement"
1910
+
1911
+ success_message = f"Image created successfully in {generation_time:.1f}s using {model_name.split('/')[-1]} model and {enhancement_method}"
1912
+
1913
+ return image, success_message, enhanced_prompt
1914
+
1915
+ except Exception as e:
1916
+ error_message = str(e)
1917
+ logger.error(f"Error during image generation: {error_message}")
1918
+
1919
+ # Retry logic for transient errors
1920
+ if retries > 0:
1921
+ logger.info(f"Retrying image generation, {retries} attempts remaining")
1922
+ time.sleep(1) # Small delay before retry
1923
+ return generate_image(description, creation_type, art_style, mood, model_name, retries - 1)
1924
+
1925
+ # Format user-friendly error message
1926
+ if "429" in error_message:
1927
+ friendly_error = "Server is currently busy. Please try again in a few moments."
1928
+ elif "401" in error_message or "403" in error_message:
1929
+ friendly_error = "Authentication error with the image service. Please check API settings."
1930
+ elif "timeout" in error_message.lower():
1931
+ friendly_error = "Request timed out. The server might be under heavy load."
1932
+ else:
1933
+ friendly_error = f"Error generating image: {error_message}"
1934
+
1935
+ return None, friendly_error, enhanced_prompt
1936
+ except Exception as e:
1937
+ logger.error(f"Unexpected error in generate_image: {str(e)}")
1938
+ return None, f"Unexpected error: {str(e)}", ""
1939
+
1940
+ # Wrapper function for generate_image with status updates
1941
+ def generate_with_status(description, creation_type_val, art_style_val, mood_val, model_name):
1942
+ """
1943
+ Wrapper for generate_image that handles UI status updates and parameter formatting
1944
+
1945
+ Args:
1946
+ description (str): User's original description
1947
+ creation_type_val (str): Formatted creation type with icon
1948
+ art_style_val (str): Formatted art style with icon
1949
+ mood_val (str): Formatted mood with icon
1950
+ model_name (str): Formatted model name with icon
1951
+
1952
+ Returns:
1953
+ tuple: (image, status_html, enhanced_prompt, parameters_html)
1954
+ """
1955
+ # Check if description is empty
1956
+ if not description.strip():
1957
+ return None, update_status("Please enter a description", is_error=True), "", ""
1958
+
1959
+ # Extract keys from formatted values
1960
+ creation_key = extract_key(creation_type_val)
1961
+ art_key = extract_key(art_style_val)
1962
+ mood_key = extract_key(mood_val)
1963
+
1964
+ # Get model key from formatted name
1965
+ model_key = None
1966
+ for key, info in IMAGE_MODELS.items():
1967
+ if f"{info['icon']} {info['display_name']}" == model_name:
1968
+ model_key = key
1969
+ break
1970
+
1971
+ if not model_key:
1972
+ return None, update_status("Invalid model selection", is_error=True), "", ""
1973
+
1974
+ try:
1975
+ # Generate the image
1976
+ image, message, enhanced_prompt = generate_image(
1977
+ description, creation_key, art_key, mood_key, model_key
1978
+ )
1979
+
1980
+ if image is None:
1981
+ return None, update_status(message, is_error=True), "", ""
1982
+
1983
+ # Format parameters display
1984
+ params_html = format_parameters(creation_type_val, art_style_val, mood_val, model_name)
1985
+
1986
+ # Success message
1987
+ success_message = update_status(message)
1988
+ return image, success_message, enhanced_prompt, params_html
1989
+
1990
+ except Exception as e:
1991
+ error_message = str(e)
1992
+ logger.error(f"Error in generate_with_status: {error_message}")
1993
+ return None, update_status(f"Error: {error_message}", is_error=True), "", ""
1994
+
1995
+ # =============== MAIN APPLICATION FLOW ===============
1996
+
1997
+ def main():
1998
+ """
1999
+ Main application entry point - creates UI and sets up event handlers
2000
+ """
2001
+ # Create the UI components - event handlers are now defined inside create_ui
2002
+ interface, *_ = create_ui()
2003
+
2004
+ # Launch the interface with appropriate parameters for Gradio version
2005
+ # Check Gradio version to decide on the correct parameters to use
2006
+ try:
2007
+ # Use simple parameters that work across versions
2008
+ interface.launch(
2009
+ share=False, # Set to True to create a public link
2010
+ debug=False # Set to True for development
2011
+ )
2012
+ except Exception as e:
2013
+ logger.error(f"Error launching Gradio interface: {str(e)}")
2014
+ # Fallback to the most basic launch parameters
2015
+ interface.launch()
2016
+
2017
+ # =============== APP EXECUTION ===============
2018
+
2019
+ if __name__ == "__main__":
2020
+ # Start the application
2021
+ main()