MogensR commited on
Commit
136b95f
Β·
verified Β·
1 Parent(s): b30f973

Update processing/ai_background.py

Browse files
Files changed (1) hide show
  1. processing/ai_background.py +299 -106
processing/ai_background.py CHANGED
@@ -1,7 +1,7 @@
1
  #!/usr/bin/env python3
2
  """
3
- AI Background Generator Module - Updated to handle dependency conflicts
4
- Handles Stable Diffusion background generation with graceful fallbacks.
5
  """
6
 
7
  import os
@@ -18,70 +18,162 @@
18
  logging.basicConfig(level=logging.INFO)
19
  logger = logging.getLogger(__name__)
20
 
21
- # Try to import AI libraries with fallback
22
- DIFFUSERS_AVAILABLE = False
23
  PIL_AVAILABLE = False
 
 
24
 
25
  try:
26
  from PIL import Image, ImageDraw, ImageFilter
27
  PIL_AVAILABLE = True
28
- logger.info("PIL imported successfully")
29
  except ImportError as e:
30
- logger.warning(f"PIL import failed: {e}")
31
 
 
32
  try:
33
  import torch
34
- from diffusers import StableDiffusionPipeline
35
- DIFFUSERS_AVAILABLE = True
36
- logger.info("Diffusers imported successfully")
 
 
 
 
 
 
 
 
 
 
37
  except Exception as e:
38
- logger.warning(f"Diffusers import failed: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  DIFFUSERS_AVAILABLE = False
40
 
41
  class AIBackgroundGenerator:
42
  """
43
- AI Background Generator with graceful fallbacks
44
  """
45
 
46
  def __init__(self):
47
  self.pipeline = None
48
  self.device = "cpu"
49
 
50
- # Color themes for gradient fallbacks
51
  self.color_themes = {
 
52
  'blue': [(64, 128, 255), (0, 64, 128)],
53
- 'ocean': [(0, 119, 190), (0, 64, 128)],
54
  'sky': [(135, 206, 250), (25, 25, 112)],
 
 
 
 
55
  'green': [(34, 139, 34), (0, 100, 0)],
56
  'nature': [(107, 142, 35), (34, 139, 34)],
57
  'forest': [(34, 139, 34), (0, 50, 0)],
 
 
 
 
58
  'professional': [(105, 105, 105), (169, 169, 169)],
59
  'office': [(192, 192, 192), (105, 105, 105)],
60
  'corporate': [(70, 130, 180), (25, 25, 112)],
 
 
 
 
61
  'dark': [(64, 64, 64), (0, 0, 0)],
62
  'night': [(25, 25, 112), (0, 0, 0)],
 
 
 
 
63
  'warm': [(255, 140, 0), (255, 69, 0)],
64
  'sunset': [(255, 94, 77), (255, 154, 0)],
 
 
 
 
65
  'purple': [(147, 112, 219), (75, 0, 130)],
 
 
 
 
66
  'red': [(220, 20, 60), (139, 0, 0)],
 
 
 
 
 
 
 
 
 
 
 
67
  'default': [(100, 149, 237), (65, 105, 225)]
68
  }
69
 
70
- if DIFFUSERS_AVAILABLE:
 
 
71
  self._init_diffusers()
 
 
72
 
73
  def _init_diffusers(self):
74
- """Initialize the Stable Diffusion pipeline"""
 
75
  try:
76
- # Use a lightweight model for faster generation
 
77
  model_id = "runwayml/stable-diffusion-v1-5"
78
 
79
  if torch.cuda.is_available():
80
  self.device = "cuda"
81
- logger.info("Using CUDA device")
82
  else:
83
  self.device = "cpu"
84
- logger.info("Using CPU device")
85
 
86
  self.pipeline = StableDiffusionPipeline.from_pretrained(
87
  model_id,
@@ -95,10 +187,10 @@ def _init_diffusers(self):
95
  self.pipeline.enable_memory_efficient_attention()
96
  self.pipeline.enable_attention_slicing()
97
 
98
- logger.info("Diffusers pipeline initialized successfully")
99
 
100
  except Exception as e:
101
- logger.error(f"Failed to initialize diffusers pipeline: {e}")
102
  self.pipeline = None
103
  global DIFFUSERS_AVAILABLE
104
  DIFFUSERS_AVAILABLE = False
@@ -107,28 +199,51 @@ def _analyze_prompt_theme(self, prompt: str) -> str:
107
  """Analyze prompt to determine appropriate color theme"""
108
  prompt_lower = prompt.lower()
109
 
110
- # Check for specific themes
111
- for theme, colors in self.color_themes.items():
112
  if theme in prompt_lower:
113
  return theme
114
 
115
- # Check for related keywords
116
- if any(word in prompt_lower for word in ['water', 'sea', 'lake', 'river']):
117
- return 'blue'
118
- elif any(word in prompt_lower for word in ['grass', 'tree', 'plant', 'garden']):
119
- return 'green'
120
- elif any(word in prompt_lower for word in ['business', 'meeting', 'work']):
121
- return 'professional'
122
- elif any(word in prompt_lower for word in ['evening', 'midnight', 'shadow']):
123
- return 'dark'
124
- elif any(word in prompt_lower for word in ['fire', 'flame', 'autumn']):
125
- return 'warm'
126
- else:
127
- return 'default'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
128
 
129
  def _create_gradient_background(self, width: int = 1024, height: int = 768,
130
  theme: str = 'default') -> Image.Image:
131
- """Create a gradient background as fallback"""
132
  if not PIL_AVAILABLE:
133
  raise RuntimeError("PIL is not available for gradient generation")
134
 
@@ -136,14 +251,16 @@ def _create_gradient_background(self, width: int = 1024, height: int = 768,
136
  colors = self.color_themes.get(theme, self.color_themes['default'])
137
  color1, color2 = colors
138
 
139
- # Create gradient
140
  image = Image.new('RGB', (width, height))
141
  draw = ImageDraw.Draw(image)
142
 
143
- # Create vertical gradient
144
  for y in range(height):
145
- # Calculate interpolation factor
146
  factor = y / height
 
 
147
 
148
  # Interpolate between colors
149
  r = int(color1[0] * (1 - factor) + color2[0] * factor)
@@ -153,37 +270,69 @@ def _create_gradient_background(self, width: int = 1024, height: int = 768,
153
  # Draw horizontal line
154
  draw.line([(0, y), (width, y)], fill=(r, g, b))
155
 
156
- # Add subtle noise for texture
157
- noise_overlay = Image.new('RGB', (width, height))
158
- noise_draw = ImageDraw.Draw(noise_overlay)
159
 
160
- for _ in range(width * height // 100): # Sparse noise
161
- x = random.randint(0, width - 1)
162
- y = random.randint(0, height - 1)
163
- brightness = random.randint(-20, 20)
164
- noise_draw.point((x, y), fill=(brightness, brightness, brightness))
165
 
166
- # Apply noise with low opacity
167
- image = Image.blend(image, noise_overlay, 0.1)
 
168
 
169
- # Apply slight blur for smoothness
170
- image = image.filter(ImageFilter.GaussianBlur(radius=1))
 
 
 
 
 
 
171
 
172
- return image
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
 
174
  def generate_background(self, prompt: str, width: int = 1024, height: int = 768,
175
  guidance_scale: float = 7.5, num_inference_steps: int = 20) -> Optional[Image.Image]:
176
  """
177
  Generate a background image from a text prompt.
178
- Falls back to gradient if AI generation fails.
179
  """
180
 
181
- # First try AI generation if available
182
- if DIFFUSERS_AVAILABLE and self.pipeline is not None:
 
 
 
 
183
  try:
184
- logger.info(f"Generating AI background for prompt: '{prompt}'")
185
 
186
- # Enhance prompt for better backgrounds
187
  enhanced_prompt = f"{prompt}, high quality, detailed, professional background, 8k"
188
 
189
  with torch.no_grad():
@@ -197,36 +346,42 @@ def generate_background(self, prompt: str, width: int = 1024, height: int = 768,
197
  )
198
 
199
  if result.images and len(result.images) > 0:
200
- logger.info("AI background generated successfully")
201
  return result.images[0]
202
 
203
  except Exception as e:
204
- logger.error(f"AI generation failed: {e}")
205
 
206
- # Fallback to gradient generation
207
- logger.info("Using gradient fallback for background generation")
208
  theme = self._analyze_prompt_theme(prompt)
209
- logger.info(f"Selected theme '{theme}' for prompt: '{prompt}'")
210
 
211
  try:
212
- return self._create_gradient_background(width, height, theme)
 
 
 
 
 
 
213
  except Exception as e:
214
- logger.error(f"Gradient generation failed: {e}")
215
  return None
216
 
217
  def save_background(self, image: Image.Image, output_path: str) -> bool:
218
  """Save the generated background image"""
219
  try:
220
  # Ensure directory exists
221
- os.makedirs(os.path.dirname(output_path), exist_ok=True)
222
 
223
- # Save image
224
- image.save(output_path, format='PNG', quality=95)
225
- logger.info(f"Background saved to: {output_path}")
226
  return True
227
 
228
  except Exception as e:
229
- logger.error(f"Failed to save background: {e}")
230
  return False
231
 
232
  def get_background_base64(self, image: Image.Image) -> str:
@@ -237,10 +392,10 @@ def get_background_base64(self, image: Image.Image) -> str:
237
  img_str = base64.b64encode(buffer.getvalue()).decode()
238
  return img_str
239
  except Exception as e:
240
- logger.error(f"Failed to convert to base64: {e}")
241
  return ""
242
 
243
- # Convenience function for quick background generation
244
  def generate_ai_background(prompt: str, width: int = 1024, height: int = 768) -> Optional[Image.Image]:
245
  """
246
  Quick function to generate a background.
@@ -253,52 +408,90 @@ def generate_ai_background(prompt: str, width: int = 1024, height: int = 768) ->
253
  Returns:
254
  PIL Image object or None if generation fails
255
  """
256
- generator = AIBackgroundGenerator()
257
- return generator.generate_background(prompt, width, height)
 
 
 
 
258
 
259
- # Example usage and testing
260
- if __name__ == "__main__":
261
- # Quick test first
262
- if not test_background_generation():
263
- print("Exiting due to test failure")
264
- sys.exit(1)
 
 
 
 
265
 
266
- # Full test suite
267
- test_prompts = [
268
- "professional office environment",
269
- "peaceful ocean sunset",
270
- "dark forest at night",
271
- "modern corporate meeting room",
272
- "abstract blue technology background"
 
 
 
 
 
 
273
  ]
274
 
275
- generator = AIBackgroundGenerator()
276
 
277
- for i, prompt in enumerate(test_prompts):
278
- print(f"\nGenerating background {i+1}: '{prompt}'")
 
 
279
 
280
  try:
281
- image = generator.generate_background(prompt, width=512, height=384)
282
 
283
  if image:
284
- output_path = f"test_background_{i+1}.png"
285
- if generator.save_background(image, output_path):
286
- print(f"βœ“ Successfully saved: {output_path}")
287
- else:
288
- print(f"βœ— Failed to save: {output_path}")
 
 
 
 
 
289
  else:
290
- print("βœ— Failed to generate background")
291
 
292
  except Exception as e:
293
- print(f"βœ— Error: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
294
 
295
- print(f"\nFinal module status:")
296
- print(f"- PIL Available: {PIL_AVAILABLE}")
297
- print(f"- PyTorch Available: {TORCH_AVAILABLE}")
298
- print(f"- Diffusers Available: {DIFFUSERS_AVAILABLE}")
299
- if generator.pipeline:
300
- print(f"- Device: {generator.device}")
301
- print("- Mode: AI Generation (Stable Diffusion)")
302
  else:
303
- print("- AI Pipeline: Not initialized")
304
- print("- Mode: Gradient Fallback Only")
 
1
  #!/usr/bin/env python3
2
  """
3
+ AI Background Generator Module - Gradient-Only Version
4
+ Handles background generation with smart gradient fallbacks when AI libraries conflict.
5
  """
6
 
7
  import os
 
18
  logging.basicConfig(level=logging.INFO)
19
  logger = logging.getLogger(__name__)
20
 
21
+ # Safe imports only
 
22
  PIL_AVAILABLE = False
23
+ TORCH_AVAILABLE = False
24
+ DIFFUSERS_AVAILABLE = False
25
 
26
  try:
27
  from PIL import Image, ImageDraw, ImageFilter
28
  PIL_AVAILABLE = True
29
+ logger.info("βœ… PIL imported successfully")
30
  except ImportError as e:
31
+ logger.error(f"❌ PIL import failed: {e}")
32
 
33
+ # Check PyTorch availability but don't import if problematic
34
  try:
35
  import torch
36
+ TORCH_AVAILABLE = True
37
+ logger.info("βœ… PyTorch available")
38
+
39
+ # Test for the specific custom_op issue
40
+ if hasattr(torch.library, 'custom_op'):
41
+ logger.info("βœ… PyTorch custom_op available")
42
+ else:
43
+ logger.warning("⚠️ PyTorch custom_op not available - diffusers will likely fail")
44
+
45
+ except ImportError:
46
+ logger.warning("⚠️ PyTorch not available")
47
+ except AttributeError:
48
+ logger.warning("⚠️ PyTorch version incompatible (missing torch.library)")
49
  except Exception as e:
50
+ logger.warning(f"⚠️ PyTorch check failed: {e}")
51
+
52
+ # NEVER attempt to import diffusers if we detect the custom_op issue
53
+ FORCE_GRADIENT_MODE = False
54
+
55
+ if TORCH_AVAILABLE:
56
+ try:
57
+ # First, check if torch.library.custom_op exists
58
+ import torch
59
+ if not hasattr(torch.library, 'custom_op'):
60
+ logger.warning("πŸ”„ Force enabling gradient-only mode due to torch.library.custom_op missing")
61
+ FORCE_GRADIENT_MODE = True
62
+ else:
63
+ # Only try diffusers if custom_op exists
64
+ try:
65
+ # Quick test import to see if diffusers will work
66
+ import importlib.util
67
+ spec = importlib.util.find_spec("diffusers")
68
+ if spec is not None:
69
+ # Try a minimal import test
70
+ from diffusers import __version__
71
+ logger.info(f"βœ… Diffusers {__version__} detected and compatible")
72
+ DIFFUSERS_AVAILABLE = True
73
+ else:
74
+ logger.info("ℹ️ Diffusers not installed")
75
+ except Exception as e:
76
+ if "custom_op" in str(e):
77
+ logger.warning("πŸ”„ Detected custom_op compatibility issue - using gradient-only mode")
78
+ FORCE_GRADIENT_MODE = True
79
+ else:
80
+ logger.warning(f"πŸ”„ Diffusers import issue: {e}")
81
+ except Exception as e:
82
+ logger.warning(f"πŸ”„ PyTorch/Diffusers compatibility check failed: {e}")
83
+ FORCE_GRADIENT_MODE = True
84
+ else:
85
+ logger.info("ℹ️ Skipping diffusers check - PyTorch not available")
86
+
87
+ # Override diffusers availability if we're forcing gradient mode
88
+ if FORCE_GRADIENT_MODE:
89
  DIFFUSERS_AVAILABLE = False
90
 
91
  class AIBackgroundGenerator:
92
  """
93
+ AI Background Generator with intelligent gradient fallbacks
94
  """
95
 
96
  def __init__(self):
97
  self.pipeline = None
98
  self.device = "cpu"
99
 
100
+ # Comprehensive color themes for gradient fallbacks
101
  self.color_themes = {
102
+ # Blues
103
  'blue': [(64, 128, 255), (0, 64, 128)],
104
+ 'ocean': [(0, 119, 190), (0, 64, 128)],
105
  'sky': [(135, 206, 250), (25, 25, 112)],
106
+ 'water': [(0, 191, 255), (0, 100, 200)],
107
+ 'azure': [(240, 255, 255), (0, 127, 255)],
108
+
109
+ # Greens
110
  'green': [(34, 139, 34), (0, 100, 0)],
111
  'nature': [(107, 142, 35), (34, 139, 34)],
112
  'forest': [(34, 139, 34), (0, 50, 0)],
113
+ 'grass': [(124, 252, 0), (34, 139, 34)],
114
+ 'mint': [(152, 251, 152), (0, 128, 0)],
115
+
116
+ # Professional/Business
117
  'professional': [(105, 105, 105), (169, 169, 169)],
118
  'office': [(192, 192, 192), (105, 105, 105)],
119
  'corporate': [(70, 130, 180), (25, 25, 112)],
120
+ 'business': [(47, 79, 79), (112, 128, 144)],
121
+ 'modern': [(95, 158, 160), (47, 79, 79)],
122
+
123
+ # Dark themes
124
  'dark': [(64, 64, 64), (0, 0, 0)],
125
  'night': [(25, 25, 112), (0, 0, 0)],
126
+ 'black': [(105, 105, 105), (0, 0, 0)],
127
+ 'shadow': [(85, 85, 85), (0, 0, 0)],
128
+
129
+ # Warm colors
130
  'warm': [(255, 140, 0), (255, 69, 0)],
131
  'sunset': [(255, 94, 77), (255, 154, 0)],
132
+ 'orange': [(255, 165, 0), (255, 69, 0)],
133
+ 'fire': [(255, 69, 0), (139, 0, 0)],
134
+
135
+ # Cool colors
136
  'purple': [(147, 112, 219), (75, 0, 130)],
137
+ 'violet': [(138, 43, 226), (75, 0, 130)],
138
+ 'lavender': [(230, 230, 250), (147, 112, 219)],
139
+
140
+ # Others
141
  'red': [(220, 20, 60), (139, 0, 0)],
142
+ 'pink': [(255, 182, 193), (255, 20, 147)],
143
+ 'yellow': [(255, 255, 0), (255, 215, 0)],
144
+ 'gold': [(255, 215, 0), (184, 134, 11)],
145
+
146
+ # Technology/Digital
147
+ 'tech': [(0, 255, 255), (0, 0, 139)],
148
+ 'digital': [(138, 43, 226), (25, 25, 112)],
149
+ 'cyber': [(0, 255, 127), (0, 100, 0)],
150
+ 'neon': [(255, 20, 147), (138, 43, 226)],
151
+
152
+ # Default
153
  'default': [(100, 149, 237), (65, 105, 225)]
154
  }
155
 
156
+ # Only try to initialize diffusers if it's actually available
157
+ if DIFFUSERS_AVAILABLE and not FORCE_GRADIENT_MODE:
158
+ logger.info("🎨 Attempting to initialize AI pipeline...")
159
  self._init_diffusers()
160
+ else:
161
+ logger.info("🎨 Using gradient-only mode")
162
 
163
  def _init_diffusers(self):
164
+ """Initialize the Stable Diffusion pipeline (only if safe)"""
165
+ # This will only be called if we've verified diffusers works
166
  try:
167
+ from diffusers import StableDiffusionPipeline
168
+
169
  model_id = "runwayml/stable-diffusion-v1-5"
170
 
171
  if torch.cuda.is_available():
172
  self.device = "cuda"
173
+ logger.info("πŸš€ Using CUDA device")
174
  else:
175
  self.device = "cpu"
176
+ logger.info("πŸ–₯️ Using CPU device")
177
 
178
  self.pipeline = StableDiffusionPipeline.from_pretrained(
179
  model_id,
 
187
  self.pipeline.enable_memory_efficient_attention()
188
  self.pipeline.enable_attention_slicing()
189
 
190
+ logger.info("βœ… AI pipeline initialized successfully")
191
 
192
  except Exception as e:
193
+ logger.error(f"❌ Failed to initialize AI pipeline: {e}")
194
  self.pipeline = None
195
  global DIFFUSERS_AVAILABLE
196
  DIFFUSERS_AVAILABLE = False
 
199
  """Analyze prompt to determine appropriate color theme"""
200
  prompt_lower = prompt.lower()
201
 
202
+ # Direct theme matches first
203
+ for theme in self.color_themes:
204
  if theme in prompt_lower:
205
  return theme
206
 
207
+ # Keyword analysis
208
+ keyword_map = {
209
+ # Water/Ocean
210
+ ('water', 'sea', 'lake', 'river', 'stream'): 'ocean',
211
+ ('sky', 'cloud', 'air'): 'sky',
212
+
213
+ # Nature
214
+ ('tree', 'plant', 'garden', 'leaf', 'flower'): 'nature',
215
+ ('grass', 'field', 'meadow'): 'grass',
216
+
217
+ # Business
218
+ ('business', 'meeting', 'work', 'conference'): 'business',
219
+ ('company', 'enterprise', 'corporate'): 'corporate',
220
+
221
+ # Time/Lighting
222
+ ('evening', 'midnight', 'shadow', 'darkness'): 'night',
223
+ ('fire', 'flame', 'autumn', 'fall'): 'fire',
224
+ ('morning', 'sunrise', 'dawn'): 'warm',
225
+
226
+ # Technology
227
+ ('technology', 'computer', 'digital', 'software'): 'tech',
228
+ ('cyber', 'virtual', 'matrix'): 'cyber',
229
+ ('neon', 'electric', 'bright'): 'neon',
230
+
231
+ # Emotions/Moods
232
+ ('calm', 'peaceful', 'serene'): 'azure',
233
+ ('energetic', 'vibrant', 'active'): 'orange',
234
+ ('elegant', 'sophisticated', 'luxury'): 'purple',
235
+ ('fresh', 'clean', 'pure'): 'mint',
236
+ }
237
+
238
+ for keywords, theme in keyword_map.items():
239
+ if any(keyword in prompt_lower for keyword in keywords):
240
+ return theme
241
+
242
+ return 'default'
243
 
244
  def _create_gradient_background(self, width: int = 1024, height: int = 768,
245
  theme: str = 'default') -> Image.Image:
246
+ """Create a sophisticated gradient background"""
247
  if not PIL_AVAILABLE:
248
  raise RuntimeError("PIL is not available for gradient generation")
249
 
 
251
  colors = self.color_themes.get(theme, self.color_themes['default'])
252
  color1, color2 = colors
253
 
254
+ # Create base gradient
255
  image = Image.new('RGB', (width, height))
256
  draw = ImageDraw.Draw(image)
257
 
258
+ # Create smooth vertical gradient
259
  for y in range(height):
260
+ # Use smooth interpolation
261
  factor = y / height
262
+ # Apply easing function for smoother gradients
263
+ factor = factor * factor * (3.0 - 2.0 * factor) # Smoothstep
264
 
265
  # Interpolate between colors
266
  r = int(color1[0] * (1 - factor) + color2[0] * factor)
 
270
  # Draw horizontal line
271
  draw.line([(0, y), (width, y)], fill=(r, g, b))
272
 
273
+ # Add subtle texture and depth
274
+ self._add_texture(image, theme)
 
275
 
276
+ return image
277
+
278
+ def _add_texture(self, image: Image.Image, theme: str):
279
+ """Add subtle texture to make gradients more interesting"""
280
+ width, height = image.size
281
 
282
+ # Create texture overlay
283
+ texture = Image.new('RGBA', (width, height), (0, 0, 0, 0))
284
+ texture_draw = ImageDraw.Draw(texture)
285
 
286
+ # Add different textures based on theme
287
+ if theme in ['tech', 'digital', 'cyber']:
288
+ # Add subtle grid pattern
289
+ grid_size = 50
290
+ for x in range(0, width, grid_size):
291
+ texture_draw.line([(x, 0), (x, height)], fill=(255, 255, 255, 5))
292
+ for y in range(0, height, grid_size):
293
+ texture_draw.line([(0, y), (width, y)], fill=(255, 255, 255, 5))
294
 
295
+ elif theme in ['nature', 'forest', 'grass']:
296
+ # Add organic noise
297
+ for _ in range(width * height // 200):
298
+ x = random.randint(0, width - 1)
299
+ y = random.randint(0, height - 1)
300
+ size = random.randint(1, 3)
301
+ brightness = random.randint(10, 30)
302
+ texture_draw.ellipse([(x, y), (x+size, y+size)],
303
+ fill=(brightness, brightness, brightness, 20))
304
+
305
+ else:
306
+ # Add subtle noise for general texture
307
+ for _ in range(width * height // 300):
308
+ x = random.randint(0, width - 1)
309
+ y = random.randint(0, height - 1)
310
+ brightness = random.randint(-15, 15)
311
+ alpha = random.randint(5, 15)
312
+ texture_draw.point((x, y), fill=(brightness, brightness, brightness, alpha))
313
+
314
+ # Apply texture
315
+ image.paste(texture, (0, 0), texture)
316
+
317
+ # Final smooth blur for professional look
318
+ image = image.filter(ImageFilter.GaussianBlur(radius=0.8))
319
 
320
  def generate_background(self, prompt: str, width: int = 1024, height: int = 768,
321
  guidance_scale: float = 7.5, num_inference_steps: int = 20) -> Optional[Image.Image]:
322
  """
323
  Generate a background image from a text prompt.
324
+ Uses gradients with intelligent theming.
325
  """
326
 
327
+ if not PIL_AVAILABLE:
328
+ logger.error("❌ Cannot generate backgrounds - PIL not available")
329
+ return None
330
+
331
+ # Check if AI generation is possible and working
332
+ if DIFFUSERS_AVAILABLE and not FORCE_GRADIENT_MODE and self.pipeline is not None:
333
  try:
334
+ logger.info(f"🎨 Attempting AI generation for: '{prompt}'")
335
 
 
336
  enhanced_prompt = f"{prompt}, high quality, detailed, professional background, 8k"
337
 
338
  with torch.no_grad():
 
346
  )
347
 
348
  if result.images and len(result.images) > 0:
349
+ logger.info("βœ… AI background generated successfully")
350
  return result.images[0]
351
 
352
  except Exception as e:
353
+ logger.warning(f"⚠️ AI generation failed, using gradient: {e}")
354
 
355
+ # Use gradient generation (main path for compatibility)
356
+ logger.info(f"🎨 Creating gradient background for: '{prompt}'")
357
  theme = self._analyze_prompt_theme(prompt)
358
+ logger.info(f"🎯 Selected theme: '{theme}'")
359
 
360
  try:
361
+ image = self._create_gradient_background(width, height, theme)
362
+ if image:
363
+ logger.info("βœ… Gradient background generated successfully")
364
+ return image
365
+ else:
366
+ logger.error("❌ Gradient generation returned None")
367
+ return None
368
  except Exception as e:
369
+ logger.error(f"❌ Gradient generation failed: {e}")
370
  return None
371
 
372
  def save_background(self, image: Image.Image, output_path: str) -> bool:
373
  """Save the generated background image"""
374
  try:
375
  # Ensure directory exists
376
+ Path(output_path).parent.mkdir(parents=True, exist_ok=True)
377
 
378
+ # Save image with high quality
379
+ image.save(output_path, format='PNG', quality=95, optimize=True)
380
+ logger.info(f"πŸ’Ύ Background saved to: {output_path}")
381
  return True
382
 
383
  except Exception as e:
384
+ logger.error(f"❌ Failed to save background: {e}")
385
  return False
386
 
387
  def get_background_base64(self, image: Image.Image) -> str:
 
392
  img_str = base64.b64encode(buffer.getvalue()).decode()
393
  return img_str
394
  except Exception as e:
395
+ logger.error(f"❌ Failed to convert to base64: {e}")
396
  return ""
397
 
398
+ # Convenience functions
399
  def generate_ai_background(prompt: str, width: int = 1024, height: int = 768) -> Optional[Image.Image]:
400
  """
401
  Quick function to generate a background.
 
408
  Returns:
409
  PIL Image object or None if generation fails
410
  """
411
+ try:
412
+ generator = AIBackgroundGenerator()
413
+ return generator.generate_background(prompt, width, height)
414
+ except Exception as e:
415
+ logger.error(f"❌ Background generation failed: {e}")
416
+ return None
417
 
418
+ def test_background_generation():
419
+ """Test function to verify the background generator is working"""
420
+ print("\n" + "="*60)
421
+ print("πŸ§ͺ AI BACKGROUND GENERATOR COMPATIBILITY TEST")
422
+ print("="*60)
423
+
424
+ print(f"πŸ“¦ PIL Available: {'βœ…' if PIL_AVAILABLE else '❌'}")
425
+ print(f"πŸ”₯ PyTorch Available: {'βœ…' if TORCH_AVAILABLE else '❌'}")
426
+ print(f"🎨 Diffusers Available: {'βœ…' if DIFFUSERS_AVAILABLE else '❌'}")
427
+ print(f"πŸ”„ Force Gradient Mode: {'βœ…' if FORCE_GRADIENT_MODE else '❌'}")
428
 
429
+ if not PIL_AVAILABLE:
430
+ print("\n❌ CRITICAL: Cannot generate backgrounds - PIL not available")
431
+ return False
432
+
433
+ mode = "AI (Stable Diffusion)" if (DIFFUSERS_AVAILABLE and not FORCE_GRADIENT_MODE) else "Gradient Fallback"
434
+ print(f"\n🎯 Generation Mode: {mode}")
435
+
436
+ # Test multiple themes
437
+ test_cases = [
438
+ ("professional blue office", "Should produce blue professional gradient"),
439
+ ("ocean sunset background", "Should produce ocean-themed gradient"),
440
+ ("dark tech cyber background", "Should produce dark tech gradient"),
441
+ ("green nature forest", "Should produce green nature gradient")
442
  ]
443
 
444
+ print(f"\nπŸ”„ Testing {len(test_cases)} different prompts...")
445
 
446
+ success_count = 0
447
+ for i, (prompt, expected) in enumerate(test_cases, 1):
448
+ print(f"\nπŸ“‹ Test {i}: '{prompt}'")
449
+ print(f" Expected: {expected}")
450
 
451
  try:
452
+ image = generate_ai_background(prompt, 400, 300)
453
 
454
  if image:
455
+ print(f" βœ… Generated: {image.size} {image.mode} image")
456
+ success_count += 1
457
+
458
+ # Save test image
459
+ test_path = f"test_bg_{i}.png"
460
+ try:
461
+ image.save(test_path)
462
+ print(f" πŸ’Ύ Saved: {test_path}")
463
+ except Exception as save_error:
464
+ print(f" ⚠️ Save failed: {save_error}")
465
  else:
466
+ print(" ❌ Generation failed - returned None")
467
 
468
  except Exception as e:
469
+ print(f" ❌ Generation error: {e}")
470
+
471
+ print(f"\n" + "="*60)
472
+ print(f"πŸ“Š RESULTS: {success_count}/{len(test_cases)} tests passed")
473
+
474
+ if success_count == len(test_cases):
475
+ print("πŸŽ‰ ALL TESTS PASSED! Background generator is working perfectly.")
476
+ return True
477
+ elif success_count > 0:
478
+ print("⚠️ PARTIAL SUCCESS: Some backgrounds generated successfully.")
479
+ return True
480
+ else:
481
+ print("❌ ALL TESTS FAILED: Background generator is not working.")
482
+ return False
483
+
484
+ # Example usage and testing
485
+ if __name__ == "__main__":
486
+ # Run compatibility test
487
+ success = test_background_generation()
488
 
489
+ if success:
490
+ print(f"\nπŸš€ Ready to generate backgrounds!")
491
+ print(f"πŸ’‘ Usage example:")
492
+ print(f" from ai_background import generate_ai_background")
493
+ print(f" image = generate_ai_background('your prompt here')")
494
+ print(f" image.save('background.png')")
 
495
  else:
496
+ print(f"\n⚠️ Please check the error messages above.")
497
+ print(f"πŸ’‘ Make sure PIL (Pillow) is installed: pip install Pillow")