# Debug Blank/Placeholder Images from AI Services

When AI image generation returns blank (solid color) images instead of real generated content, use this debugging playbook.

## Quick Detection Script

```bash
python3 << 'EOF'
from PIL import Image
import numpy as np
import base64, json, sys

# Test a base64 image from API response
# Usage: Modify to load your image source
img_path = "/tmp/test_image.png"  # or decode from base64

try:
    img = Image.open(img_path)
    arr = np.array(img)
    unique_colors = len(np.unique(arr.reshape(-1, 3), axis=0))
    mean_pixel = arr.mean()
    fsize = os.path.getsize(img_path) / 1024
    
    print(f"File size: {fsize:.1f} KB")
    print(f"Unique colors: {unique_colors}")
    print(f"Mean pixel value: {mean_pixel:.1f}")
    
    if unique_colors < 10:
        print("❌ BLANK IMAGE DETECTED (solid color)")
        print("   Expected: 200,000+ unique colors for real 1024x1024 image")
    elif fsize < 10:
        print("❌ BLANK IMAGE DETECTED (too small)")
        print("   Expected: 1000+ KB for real 1024x1024 PNG")
    else:
        print("✅ Image appears to be valid")
except Exception as e:
    print(f"Error: {e}")
EOF
```

## Session Debugging Flow (2026-05-04 Case Study)

### Symptom
- API returns 3 "images" but all look blank/white
- File size: 1.9 KB (expected: 1800+ KB)
- Unique colors: 1 (expected: 200,000+)

### Root Cause Investigation

**Step 1: Check file size and color distribution**
```bash
file /tmp/final_*.png
ls -lh /tmp/final_*.png
python3 -c "from PIL import Image; import numpy as np; img=Image.open('/tmp/final_1.png'); arr=np.array(img); print(f'Colors: {len(np.unique(arr.reshape(-1,3), axis=0))}')"
```

**Step 2: Check .env configuration**
```bash
cd ~/projects/home-renovation-app/ai-service
cat .env | grep -E "(LEONARDO|STABILITY|OPENAI)_API_KEY"
# Expected output:
# STABILITY_API_KEY=sk-xxx (SET)
# LEONARDO_API_KEY= (NOT SET) ← This was the problem!
```

**Step 3: Check which service is actually being called**
```bash
# Read the endpoint code
grep -A 10 "async def inference" app.py
# Look for: generate_with_leonardo() vs generate_with_stability()
```

**Step 4: Check Docker container environment**
```bash
sudo docker-compose exec ai-service printenv | grep KEY
# Verify keys are passed into container
```

### Root Cause
Endpoint `/inference` was calling `generate_with_leonardo()`, but `LEONARDO_API_KEY` was not set in `.env`. This caused an exception, triggering fallback to `generate_placeholder_image()` which returns a solid-color 512x512 image.

### Fix
1. **Option A: Set Leonardo AI Key** (if you want to use Leonardo)
   ```bash
   echo "LEONARDO_API_KEY=your_key_here" >> .env
   sudo docker-compose up -d --build ai-service
   ```

2. **Option B: Revert to Stability AI** (quick fix, what we did)
   ```python
   # In app.py /inference endpoint
   # Change: image_bytes = await generate_with_leonardo(...)
   # To: image_bytes = await generate_with_stability(prompt, negative_prompt)
   ```
   Then rebuild: `sudo docker-compose up -d --build ai-service`

### Verification After Fix
```bash
# Test generation
curl -s -X POST "http://localhost:8000/api/v1/generate-plan" \
  -H "Content-Type: application/json" \
  -d '{"layout_id": "xxx", "style": "地中海风格", "room_type": "客厅"}' \
  > /tmp/plan_test.json

# Check results
python3 -c "
import json, base64
data = json.load(open('/tmp/plan_test.json'))
for i, p in enumerate(data.get('plans',[])):
    img_bytes = base64.b64decode(p.get('image_base64',''))
    open(f'/tmp/verify_{i}.png','wb').write(img_bytes)
    print(f'Plan {i}: {len(img_bytes)/1024:.1f} KB')
"
```

## Prevention Checklist

- [ ] All API keys in `.env` are set (`STABILITY_API_KEY`, `LEONARDO_API_KEY`, etc.)
- [ ] Container environment variables match `.env` (check `docker-compose.yml`)
- [ ] All endpoints (`/inference`, `/inference/all`) use the same image service
- [ ] Fallback placeholder images are detectable (add logging: "⚠️ Using placeholder image")
- [ ] Add health check endpoint that verifies API keys are set

## Quick Reference

| Indicator | Blank Placeholder | Real Image |
|-----------|-------------------|------------|
| File size | 1-2 KB | 1000-2000 KB |
| Unique colors | 1-10 | 200,000+ |
| Mean pixel | ~240 (white) | 100-150 (varied) |
| Dimensions | Often 512x512 | 1024x1024 |
