🎨 DALL-E & Midjourney

Commercial text-to-image platforms and techniques

DALL-E vs Midjourney

Two of the most popular commercial AI image generation platforms. DALL-E (by OpenAI) offers API access and high-quality realistic images, while Midjourney (Discord-based) excels at artistic, stylized outputs.

Key Differences:

  • DALL-E: API-first, realistic, precise, programmatic
  • Midjourney: Discord bot, artistic, stylized, community-driven
  • Both: High quality, different strengths, commercial use allowed

🤖 DALL-E API Setup

import openai
from openai import OpenAI
import requests
from PIL import Image
from io import BytesIO
import os

# Initialize OpenAI client
client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

# Available models
dalle_models = {
    'dall-e-3': {
        'quality': 'Highest quality, most detailed',
        'sizes': ['1024x1024', '1024x1792', '1792x1024'],
        'cost': '$0.040 per image (standard), $0.080 (HD)',
    },
    'dall-e-2': {
        'quality': 'Good quality, faster, cheaper',
        'sizes': ['256x256', '512x512', '1024x1024'],
        'cost': '$0.020 per image (1024x1024)',
    }
}

print("DALL-E Models:")
for model, specs in dalle_models.items():
    print(f"\n{model}:")
    for key, value in specs.items():
        print(f"  {key}: {value}")

print("\nGet your API key: https://platform.openai.com/api-keys")

🎨 Generate Images with DALL-E 3

def generate_dalle_image(prompt, model="dall-e-3", size="1024x1024", 
                         quality="standard", n=1):
    """
    Generate image with DALL-E
    
    Args:
        prompt: Text description
        model: 'dall-e-2' or 'dall-e-3'
        size: Image dimensions
        quality: 'standard' or 'hd' (DALL-E 3 only)
        n: Number of images (1-10 for DALL-E 2, only 1 for DALL-E 3)
    """
    
    try:
        response = client.images.generate(
            model=model,
            prompt=prompt,
            size=size,
            quality=quality,
            n=n
        )
        
        # Get image URL
        image_url = response.data[0].url
        
        # Download image
        img_response = requests.get(image_url)
        img = Image.open(BytesIO(img_response.content))
        
        # Get revised prompt (DALL-E 3 often enhances prompts)
        revised_prompt = getattr(response.data[0], 'revised_prompt', None)
        
        return img, revised_prompt
        
    except Exception as e:
        print(f"Error: {e}")
        return None, None

# Example: Generate with DALL-E 3
prompt = """A serene Japanese garden with cherry blossoms in full bloom, 
koi pond with wooden bridge, traditional tea house in background, 
golden hour lighting, photorealistic, 4k quality"""

image, revised = generate_dalle_image(
    prompt=prompt,
    model="dall-e-3",
    size="1024x1024",
    quality="hd"
)

if image:
    image.save("dalle3_garden.png")
    print("Image generated successfully!")
    if revised:
        print(f"\nRevised prompt: {revised}")

print("\nDALL-E 3 automatically enhances prompts for better results!")

✏️ Image Editing with DALL-E

def edit_image_dalle(image_path, mask_path, prompt):
    """
    Edit image with inpainting (DALL-E 2 only)
    
    Args:
        image_path: Original image (must be square, PNG, <4MB)
        mask_path: Mask (transparent areas will be regenerated)
        prompt: What to generate in masked area
    """
    
    response = client.images.edit(
        model="dall-e-2",
        image=open(image_path, "rb"),
        mask=open(mask_path, "rb"),
        prompt=prompt,
        n=1,
        size="1024x1024"
    )
    
    image_url = response.data[0].url
    img_response = requests.get(image_url)
    img = Image.open(BytesIO(img_response.content))
    
    return img

# Example: Add a dog to image
edited = edit_image_dalle(
    image_path="room.png",
    mask_path="room_mask.png",  # Transparent where dog should be
    prompt="a golden retriever sitting on the floor"
)

edited.save("room_with_dog.png")
print("Image edited with inpainting!")

def create_variation(image_path, n=3):
    """Create variations of an existing image"""
    
    response = client.images.create_variation(
        model="dall-e-2",
        image=open(image_path, "rb"),
        n=n,
        size="1024x1024"
    )
    
    variations = []
    for i, img_data in enumerate(response.data):
        img_response = requests.get(img_data.url)
        img = Image.open(BytesIO(img_response.content))
        variations.append(img)
        img.save(f"variation_{i+1}.png")
    
    return variations

# Create 3 variations
variations = create_variation("original.png", n=3)
print(f"Created {len(variations)} variations!")

🎭 Midjourney Setup

# Midjourney is Discord-based, no official API yet
# Access through Discord bot commands

"""
Getting Started with Midjourney:

1. Join Discord: https://discord.gg/midjourney
2. Subscribe: https://www.midjourney.com/account
3. Go to #newbie channels
4. Use /imagine command

Plans:
- Basic: $10/month (200 images)
- Standard: $30/month (unlimited relaxed)
- Pro: $60/month (unlimited fast + stealth)

Commands:
/imagine [prompt] - Generate image
/blend [images] - Blend multiple images
/describe [image] - Get prompt from image
/settings - Change bot settings
"""

# Unofficial API wrapper (use at your own risk)
class MidjourneyClient:
    """Wrapper for Midjourney (requires Discord bot token)"""
    
    def __init__(self, discord_token, channel_id):
        self.token = discord_token
        self.channel_id = channel_id
        self.base_url = "https://discord.com/api/v10"
    
    def imagine(self, prompt):
        """Send /imagine command"""
        # Implementation requires Discord API
        # This is pseudocode for educational purposes
        
        command = f"/imagine prompt: {prompt}"
        # Send to Discord channel
        # Wait for bot response
        # Download generated images
        
        print(f"Would execute: {command}")
        return "image_url"

# Example prompts
midjourney_prompt = """a majestic dragon perched on ancient ruins, 
sunset lighting, fantasy art, highly detailed, 
trending on artstation --ar 16:9 --v 6 --stylize 750"""

print("Midjourney Prompt Structure:")
print(midjourney_prompt)
print("\nParameters explained:")
print("  --ar 16:9  : Aspect ratio")
print("  --v 6      : Version 6 (latest)")
print("  --stylize 750 : Artistic style (0-1000)")

⚙️ Midjourney Parameters

# Comprehensive Midjourney parameters guide

midjourney_parameters = {
    'Aspect Ratio': {
        '--ar 1:1': 'Square (default)',
        '--ar 16:9': 'Landscape/widescreen',
        '--ar 9:16': 'Portrait/vertical',
        '--ar 4:3': 'Classic photo',
        '--ar 3:2': 'Camera standard',
    },
    
    'Version': {
        '--v 6': 'Latest, most accurate',
        '--v 5.2': 'Previous stable',
        '--niji 6': 'Anime/illustration style',
    },
    
    'Quality': {
        '--q 0.25': 'Fast, rough (4x faster)',
        '--q 0.5': 'Balanced',
        '--q 1': 'Standard (default)',
        '--q 2': 'Detailed (2x slower)',
    },
    
    'Stylization': {
        '--s 0': 'Very literal',
        '--s 100': 'Balanced prompt adherence',
        '--s 250': 'Default',
        '--s 750': 'Very artistic',
        '--s 1000': 'Maximum creativity',
    },
    
    'Chaos': {
        '--c 0': 'Predictable, consistent',
        '--c 50': 'Moderate variation',
        '--c 100': 'Wild, experimental',
    },
    
    'Other': {
        '--seed 123': 'Reproducible results',
        '--tile': 'Seamless pattern',
        '--no': 'Negative prompt (e.g., --no people)',
        '--iw 2': 'Image weight (with image prompt)',
    }
}

print("Midjourney Parameters:\n")
for category, params in midjourney_parameters.items():
    print(f"{category}:")
    for param, description in params.items():
        print(f"  {param}: {description}")
    print()

# Example advanced prompt
advanced_prompt = """ethereal forest spirit, glowing mushrooms, 
bioluminescent plants, mystical atmosphere, octane render, 
unreal engine, 8k, highly detailed --ar 16:9 --v 6 --s 750 --c 25 --q 2"""

print("Advanced Prompt Example:")
print(advanced_prompt)

🎨 Prompt Engineering Strategies

# Effective prompting techniques for both platforms

prompt_strategies = {
    'Subject': 'Clear main focus - "a red sports car"',
    'Style': 'Art style - "oil painting", "anime", "photorealistic"',
    'Lighting': 'Lighting conditions - "golden hour", "dramatic lighting"',
    'Composition': 'View angle - "aerial view", "close-up portrait"',
    'Details': 'Specific details - "detailed texture", "intricate patterns"',
    'Quality': 'Quality modifiers - "8k", "highly detailed", "professional"',
    'Artist': 'Art reference - "in the style of Van Gogh"',
    'Mood': 'Emotional tone - "melancholic", "whimsical", "epic"',
}

print("Prompt Engineering Strategies:\n")
for element, description in prompt_strategies.items():
    print(f"{element:12} | {description}")

# Platform-specific tips
dalle_tips = [
    "Be specific and detailed",
    "Use natural language",
    "Describe lighting and mood",
    "DALL-E 3 enhances prompts automatically",
    "Can use longer, more descriptive prompts",
]

midjourney_tips = [
    "Start with subject, then add modifiers",
    "Use art-specific terms (octane render, trending on artstation)",
    "Experiment with stylization values",
    "Reference artists for consistent style",
    "Use --no for negative prompts",
    "Test different chaos values for variety",
]

print("\n\nDALL-E Tips:")
for tip in dalle_tips:
    print(f"  • {tip}")

print("\nMidjourney Tips:")
for tip in midjourney_tips:
    print(f"  • {tip}")

📊 Platform Comparison

Feature DALL-E 3 DALL-E 2 Midjourney v6
Interface API, ChatGPT API Discord bot
Image Quality Excellent (realistic) Good Excellent (artistic)
Prompt Following Very accurate Moderate Very accurate
Max Resolution 1792x1024 1024x1024 2048+ (upscale)
Speed ~10-30 seconds ~5-10 seconds ~30-60 seconds
Cost $0.04-$0.08/image $0.02/image $10-$60/month
Editing No Inpainting, variations Remix, vary region
Best For Realistic, programmatic Quick iterations Artistic, stylized

🚀 Practical Application

import json
from datetime import datetime

class ImageGenerationWorkflow:
    """Production workflow for AI image generation"""
    
    def __init__(self, platform="dalle"):
        self.platform = platform
        self.client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
        self.history = []
    
    def generate(self, prompt, **kwargs):
        """Generate image with metadata tracking"""
        
        start_time = datetime.now()
        
        if self.platform == "dalle":
            image, revised_prompt = generate_dalle_image(prompt, **kwargs)
        elif self.platform == "midjourney":
            # Implement Midjourney generation
            image, revised_prompt = None, None
        
        end_time = datetime.now()
        
        # Track generation
        metadata = {
            'prompt': prompt,
            'revised_prompt': revised_prompt,
            'platform': self.platform,
            'timestamp': start_time.isoformat(),
            'duration': (end_time - start_time).total_seconds(),
            'parameters': kwargs,
        }
        
        self.history.append(metadata)
        
        return image, metadata
    
    def batch_generate(self, prompts, save_dir='outputs'):
        """Generate multiple images"""
        
        os.makedirs(save_dir, exist_ok=True)
        results = []
        
        for i, prompt in enumerate(prompts):
            print(f"Generating {i+1}/{len(prompts)}: {prompt[:50]}...")
            
            image, metadata = self.generate(prompt)
            
            if image:
                filename = f"{save_dir}/image_{i+1}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
                image.save(filename)
                metadata['filename'] = filename
                results.append(metadata)
        
        # Save metadata
        with open(f"{save_dir}/metadata.json", 'w') as f:
            json.dump(results, f, indent=2)
        
        print(f"\nGenerated {len(results)} images in {save_dir}/")
        return results
    
    def export_history(self, filename='generation_history.json'):
        """Export generation history"""
        with open(filename, 'w') as f:
            json.dump(self.history, f, indent=2)
        print(f"History exported to {filename}")

# Example workflow
workflow = ImageGenerationWorkflow(platform="dalle")

# Generate multiple images
prompts = [
    "a futuristic cityscape at night, neon lights, cyberpunk style",
    "a peaceful mountain lake at sunrise, misty atmosphere",
    "an abstract representation of artificial intelligence",
]

results = workflow.batch_generate(prompts, save_dir='ai_images')

# Export history
workflow.export_history()

print(f"\nProcessed {len(results)} prompts successfully!")

🎯 Use Case Recommendations

use_cases = {
    'Product Photography': {
        'Best Platform': 'DALL-E 3',
        'Why': 'Realistic, precise, good with objects',
        'Example': 'Professional product shot of wireless headphones, white background, studio lighting',
    },
    
    'Concept Art': {
        'Best Platform': 'Midjourney',
        'Why': 'Artistic style, creative interpretation',
        'Example': 'Fantasy character concept art, detailed armor, dramatic pose --ar 2:3 --v 6 --s 750',
    },
    
    'Marketing Assets': {
        'Best Platform': 'DALL-E 3',
        'Why': 'Brand consistency, text integration, API access',
        'Example': 'Modern minimal hero image for tech startup, blue gradient, professional',
    },
    
    'Book Covers': {
        'Best Platform': 'Midjourney',
        'Why': 'Artistic quality, unique style',
        'Example': 'Epic fantasy book cover, dragon flying over castle, dramatic sky --ar 2:3 --v 6',
    },
    
    'Social Media': {
        'Best Platform': 'DALL-E 3',
        'Why': 'Fast API access, batch generation',
        'Example': 'Instagram post background, colorful abstract pattern, modern aesthetic',
    },
    
    'Game Assets': {
        'Best Platform': 'Midjourney + DALL-E 2',
        'Why': 'Midjourney for style, DALL-E 2 for variations',
        'Example': 'Isometric game tile, medieval fantasy village, pixel art style --ar 1:1 --tile',
    },
}

print("Use Case Recommendations:\n")
for use_case, details in use_cases.items():
    print(f"{use_case}:")
    for key, value in details.items():
        print(f"  {key}: {value}")
    print()

🎯 Key Takeaways