# BaoLife AI Image Generation System

## Overview

Automated image generation system for BaoLife events using state-of-the-art AI models. Generates high-quality, cozy cartoon-style images for game events with caching and queue management.

## Features

- **Multiple AI Providers**: Google Imagen 4 Ultra (recommended), FLUX 1.1 Pro, and DALL-E 3 support
- **Cozy Cartoon Style**: Optimized prompts tested and tuned for warm, friendly game aesthetic
- **Smart Caching**: Stores generated images in MySQL to avoid duplicate generations
- **Queue System**: Batch processing for efficient large-scale generation
- **Cost Tracking**: Monitors generation costs and statistics
- **Event Integration**: Seamless integration with existing event system

## Cost & Performance

### Google Imagen 4 Ultra (⭐ Recommended)
- **Cost**: Pricing varies (check fal.ai for current rates)
- **Quality**: ⭐⭐⭐⭐⭐ Exceptional, best-in-class for cozy cartoon style
- **Speed**: Very fast, ~5-8 seconds per image
- **Provider**: fal.ai
- **Style**: Produces consistently excellent cozy cartoon style with tested prompts

### FLUX 1.1 Pro
- **Cost**: $0.04 per image
- **Quality**: Excellent, comparable to Midjourney
- **Speed**: 6x faster than FLUX 1.0, ~5-10 seconds per image
- **Provider**: fal.ai (primary), Replicate, Together.ai

### DALL-E 3
- **Cost**: $0.04-0.12 per image (quality/size dependent)
- **Quality**: High-quality, good spatial relationships
- **Speed**: ~10-15 seconds per image
- **Provider**: OpenAI

### Example Costs
- 100 images @ $0.04 = **$4.00**
- 500 images @ $0.04 = **$20.00**
- 1000 images @ $0.04 = **$40.00**

## Setup

### 1. Install Dependencies

```bash
cd ws
pip install openai aiohttp python-dotenv
```

### 2. Configure API Keys

Add to your `.env` file in the project root:

```bash
# For Imagen 4 Ultra (via fal.ai) - Recommended
# Format: client_id:client_secret
FAL_AI_KEY=your_fal_ai_key_here

# Set default provider (imagen4 recommended)
IMAGE_GENERATION_PROVIDER=imagen4

# Optional: For DALL-E 3 (via OpenAI)
OPENAI_API_KEY=your_openai_key_here

# Optional: Replicate (alternative FLUX provider)
REPLICATE_API_TOKEN=your_replicate_token_here
```

### 3. Get API Keys

#### fal.ai (Imagen 4 Ultra / FLUX) - Recommended
1. Visit https://fal.ai
2. Sign up for an account
3. Navigate to Dashboard → API Keys
4. Create a new API key (format: `client_id:client_secret`)
5. Copy key to `.env` file

#### OpenAI (DALL-E 3)
1. Visit https://platform.openai.com
2. Sign up / log in
3. Go to API Keys section
4. Create new secret key
5. Copy key to `.env` file

### 4. Run Database Migration

```bash
cd ws
mysql -u root -p lifesim < migrations/007_ai_image_generation.sql
```

This creates:
- `generated_images` - Cached image storage
- `image_generation_queue` - Batch processing queue
- `event_images` - Event-to-image mappings
- `image_generation_stats` - Usage tracking

## Usage

### Pre-Generate Images (Recommended)

Generate all images for common events:

```bash
cd ws

# Test with 3 sample images first
python pregenerate_images.py --test

# Generate all images (60+ images with Imagen 4 Ultra)
python pregenerate_images.py --provider imagen4

# Generate specific category
python pregenerate_images.py --category education --provider imagen4
python pregenerate_images.py --category home --provider imagen4
python pregenerate_images.py --category romance --provider imagen4

# Add to queue for later processing
python pregenerate_images.py --category all --queue
python pregenerate_images.py --process-queue --batch-size 10
```

### Use in Event Functions

#### Method 1: Get Cached Image (Recommended)
```python
from image_generation import get_event_image_url

def myEvent(player, type='message'):
    fname = 'myEvent'
    check = fname not in player.events

    # Get pre-generated image from cache
    image_url = get_event_image_url('school_exterior', 'education')

    return messageFunction(
        fname,
        'You arrived at school.',
        player,
        check,
        title='School',
        image=image_url or ''  # Fallback to empty string
    )
```

#### Method 2: Generate on Demand (Async)
```python
from image_generation import generate_and_cache_image

async def myAsyncEvent(player):
    # Generate new image (or use cached if available)
    image_url = await generate_and_cache_image(
        prompt="large contemporary high school building",
        event_type="school_exterior",
        event_category="education",
        use_cache=True  # Check cache first
    )

    return image_url
```

#### Method 3: Add to Queue
```python
from image_generation import add_to_generation_queue

# Add to queue for background processing
await add_to_generation_queue(
    prompt="cozy teenage bedroom with desk",
    event_type="bedroom",
    event_category="home",
    priority=8
)
```

## Pre-Generation Script Categories

The `pregenerate_images.py` script includes **60+ prompts** across 8 categories:

### Education (9 images)
- School exterior, classroom, cafeteria, hallway, library, playground, gymnasium
- College campus, lecture hall

### Home & Family (7 images)
- Teen bedroom, child bedroom, house exterior, dining room, living room, kitchen, backyard

### Family Events (5 images)
- Family dinner, watching TV, board games, parent hug, siblings playing

### Social & Activities (5 images)
- Friends at park, birthday party, mall, gaming, movie theater

### Romance & Dating (4 images)
- Restaurant date, romantic walk, coffee date, movie date

### Activities (5 images)
- Studying, reading, gym, jogging, music practice

### Jobs & Career (4 images)
- Office, office work, meeting, retail store

### Special Events (4 images)
- Graduation, wedding, hospital, birthday cake

### Emotions & States (4 images)
- Sad, happy, angry, stressed

**Total: ~50 images for comprehensive event coverage**

## Adding Custom Prompts

Edit `pregenerate_images.py` and add to `EVENT_PROMPTS`:

```python
"your_category": [
    {
        "prompt": "description of scene in cozy cartoon style",
        "event_type": "unique_event_name",
        "event_category": "your_category",
        "priority": 8  # 1-10, higher = more important
    },
    # ... more prompts
]
```

## Style Guidelines

The system automatically applies cozy cartoon styling optimized for Imagen 4 Ultra:

**Automatic suffix added to all prompts:**
```
cozy cartoon style, illustration, warm colors,
friendly atmosphere, high quality digital art, clean lines,
--no words, text, letters, face
```

This style has been tested and produces consistently excellent results with:
- Warm, inviting color palettes
- Clean, professional illustration style
- No unwanted text or faces in backgrounds
- Perfect for game event imagery

### Tested Prompt Examples
✓ "large contemporary architecture high school" → Perfect school building
✓ "journalist office" → Clean office scene with warm lighting
✓ "fine wine product image white background" → Product-style illustration

### Good Prompt Examples
✓ "large contemporary architecture high school building exterior"
✓ "cozy teenage bedroom with desk and computer"
✓ "happy family having dinner together at dining table"

### Prompt Tips
- Be specific about subject and setting
- Use descriptive adjectives (cozy, modern, happy, contemporary)
- Specify view (exterior, interior, close-up)
- Don't include "cozy cartoon style" - it's added automatically
- Faces are automatically excluded from backgrounds (keeps focus on scenes)

## Database Schema

### `generated_images`
Stores all generated images with metadata:
- `image_url` - URL to generated image
- `prompt` - Full prompt used
- `event_type` - Event identifier
- `event_category` - Category grouping
- `provider` - 'imagen4', 'flux', 'dalle3', or 'manual'
- `generation_cost` - Cost in USD
- `tags` - JSON array for searchability
- `quality_rating` - Optional 1-5 rating

### `image_generation_queue`
Manages batch processing:
- `status` - pending, processing, completed, failed
- `priority` - 1-10 (higher = more urgent)
- `attempts` / `max_attempts` - Retry logic

### `event_images`
Maps events to images:
- `event_function_name` - Event function name
- `generated_image_id` - Foreign key to image
- `is_primary` - Primary image flag

## Monitoring & Statistics

### Check Generation Stats
```sql
-- View all generated images
SELECT event_type, event_category, image_url, created_at
FROM generated_images
WHERE is_active = TRUE
ORDER BY created_at DESC;

-- Check queue status
SELECT status, COUNT(*) as count
FROM image_generation_queue
GROUP BY status;

-- Total cost
SELECT SUM(generation_cost) as total_cost
FROM generated_images;

-- Images by category
SELECT event_category, COUNT(*) as count
FROM generated_images
GROUP BY event_category
ORDER BY count DESC;
```

### View Sample Images
```sql
-- Get all education images
SELECT event_type, image_url
FROM generated_images
WHERE event_category = 'education'
AND is_active = TRUE;
```

## Troubleshooting

### "API key not configured"
- Ensure `.env` file exists in project root
- Verify API key is set correctly
- Restart Python script after adding keys

### "FLUX API error 401"
- Check FAL_AI_KEY is valid
- Verify account has credits at https://fal.ai/dashboard

### "Rate limit exceeded"
- Add delays between requests (script has 3-second delays)
- Use queue mode: `--queue` then `--process-queue` later
- FLUX: 60 requests/minute, OpenAI: varies by tier

### Images not appearing in events
- Check `generated_images` table has data
- Verify `event_type` matches between script and event function
- Ensure `is_active = TRUE`
- Use `get_event_image_url()` helper function

### "No image returned from FLUX API"
- Check prompt isn't triggering safety filters
- Avoid violent, explicit, or copyrighted content
- Review fal.ai logs for details

## Migration from Manual Images

If you have existing Midjourney images:

```sql
-- Import manual images to cache
INSERT INTO generated_images
(image_url, prompt, style_preset, event_type, event_category, provider, model_version)
VALUES
('https://cdn.discordapp.com/...',
 'your original midjourney prompt',
 'cozy_cartoon',
 'school_exterior',
 'education',
 'manual',
 'midjourney_v6');
```

Then map to events:
```sql
INSERT INTO event_images (event_function_name, event_type, generated_image_id)
VALUES ('schoolEvent', 'school_exterior', LAST_INSERT_ID());
```

## Best Practices

1. **Pre-generate core images** - Run script before deploying new events
2. **Use caching** - Set `use_cache=True` to avoid duplicate generations
3. **Batch processing** - Use queue for large batches (10+ images)
4. **Monitor costs** - Check `image_generation_stats` table regularly
5. **Quality review** - Manually review and rate images, regenerate if needed
6. **Backup URLs** - Store image URLs in multiple locations for redundancy
7. **Test mode** - Always test with `--test` flag first

## Cost Optimization

- Use FLUX instead of DALL-E HD ($0.04 vs $0.08-0.12)
- Enable caching to reuse images across similar events
- Generate common images once, use for multiple event types
- Use queue mode to batch requests and avoid API rate limits
- Set quality ratings and filter low-quality images for regeneration

## Future Enhancements

Potential additions:
- Image variants (multiple images per event)
- Style variations (anime, realistic, pixel art)
- Character-specific images (facial features, age, etc.)
- Dynamic image selection based on game state
- Image CDN integration for faster loading
- Automatic retry with different provider on failure

## Support

For issues or questions:
1. Check database has migration: `SHOW TABLES LIKE 'generated_images';`
2. Verify API keys: `python -c "from config import config; print(config.FAL_AI_KEY[:10])"`
3. Test generation: `python pregenerate_images.py --test`
4. Review logs for error messages

## Reference Links

- **FLUX 1.1 Pro**: https://fal.ai/models/fal-ai/flux-pro
- **DALL-E 3**: https://platform.openai.com/docs/guides/images
- **fal.ai Dashboard**: https://fal.ai/dashboard
- **OpenAI Dashboard**: https://platform.openai.com/account/api-keys
