Files
2025-11-25 07:08:31 +00:00

313 lines
11 KiB
Python

"""
Batch Processing Script for Image Prompt Variations
Automates generation of multiple prompt variations from input templates
"""
import json
from pathlib import Path
from typing import List, Dict, Optional
from core.orchestrator import PromptOrchestrator
from core.modifiers import ModifierCategory
class BatchProcessor:
"""Handles batch processing of image prompts with various automation features"""
def __init__(self, output_dir: str = "output"):
"""
Initialize batch processor.
Args:
output_dir: Directory to save output files
"""
self.orchestrator = PromptOrchestrator()
self.output_dir = Path(output_dir)
self.output_dir.mkdir(exist_ok=True)
def process_single_prompt(self, base_prompt: str, config: Dict) -> List[Dict]:
"""
Process a single prompt with specified configuration.
Args:
base_prompt: The base prompt to vary
config: Configuration dict with keys:
- lighting_ids: List of modifier IDs (or "all", "dry", "wet")
- styles: List of style names to apply
- export_format: Output format (txt, json, csv)
Returns:
List of variation dictionaries
"""
# Determine which lighting modifiers to use
if config.get("lighting_ids") == "all":
modifier_ids = list(range(1, 21))
elif config.get("lighting_ids") == "dry":
dry_mods = self.orchestrator.get_modifiers_by_category(ModifierCategory.DRY)
modifier_ids = [m.id for m in dry_mods]
elif config.get("lighting_ids") == "wet":
wet_mods = self.orchestrator.get_modifiers_by_category(ModifierCategory.WET)
modifier_ids = [m.id for m in wet_mods]
else:
modifier_ids = config.get("lighting_ids", [])
# Generate variations
variations = self.orchestrator.generate_variation_batch(
base_prompt=base_prompt,
modifier_ids=modifier_ids if modifier_ids else None,
include_styles=config.get("styles", None)
)
return variations
def process_multiple_prompts(self, prompts: List[str], config: Dict,
output_filename: str = "batch_output") -> str:
"""
Process multiple base prompts and save results.
Args:
prompts: List of base prompts
config: Configuration dictionary
output_filename: Name for output file (without extension)
Returns:
Path to output file
"""
all_results = []
for idx, prompt in enumerate(prompts, 1):
variations = self.process_single_prompt(prompt, config)
all_results.append({
"base_prompt_id": idx,
"base_prompt": prompt,
"variations": variations
})
# Export results
export_format = config.get("export_format", "json")
output_path = self.output_dir / f"{output_filename}.{export_format}"
if export_format == "json":
with open(output_path, "w", encoding="utf-8") as f:
json.dump(all_results, f, indent=2)
elif export_format == "txt":
with open(output_path, "w", encoding="utf-8") as f:
for result in all_results:
f.write(f"\n{'=' * 80}\n")
f.write(f"BASE PROMPT #{result['base_prompt_id']}: {result['base_prompt']}\n")
f.write(f"{'=' * 80}\n\n")
for var in result['variations']:
f.write(f"[{var['id']}] {var['type'].upper()} - {var['category']}\n")
f.write(f" Description: {var['description']}\n")
f.write(f" Prompt: {var['prompt']}\n\n")
elif export_format == "csv":
with open(output_path, "w", encoding="utf-8") as f:
f.write("base_prompt_id,base_prompt,variation_id,type,category,description,prompt\n")
for result in all_results:
for var in result['variations']:
f.write(f"{result['base_prompt_id']},\"{result['base_prompt']}\",")
f.write(f"{var['id']},{var['type']},{var['category']},")
f.write(f"\"{var['description']}\",\"{var['prompt']}\"\n")
return str(output_path)
def create_preset_collection(self, base_prompt: str, preset: str) -> List[Dict]:
"""
Apply a preset collection of variations.
Presets:
- "full_day_cycle": All DRY modifiers (complete day cycle)
- "wet_night": All WET modifiers (dramatic night scenes)
- "key_moments": Selected dramatic lighting moments
- "commercial": Best modifiers for commercial photography
Args:
base_prompt: The base prompt
preset: Preset name
Returns:
List of variations
"""
preset_configs = {
"full_day_cycle": {
"lighting_ids": "dry",
"styles": None
},
"wet_night": {
"lighting_ids": "wet",
"styles": None
},
"key_moments": {
"lighting_ids": [1, 7, 8, 10, 18, 20], # Sunrise, golden hour, sunset, blue hours, wet night
"styles": None
},
"commercial": {
"lighting_ids": [3, 4, 7, 11], # Crisp lighting for product shots
"styles": None
},
"artistic": {
"lighting_ids": [7, 8, 9, 10],
"styles": ["impressionist", "minimalist", "art_deco"]
}
}
if preset not in preset_configs:
raise ValueError(f"Unknown preset: {preset}. Available: {list(preset_configs.keys())}")
return self.process_single_prompt(base_prompt, preset_configs[preset])
def generate_comparison_set(self, base_prompt: str,
modifier_pairs: List[tuple]) -> List[Dict]:
"""
Generate side-by-side comparison prompts.
Args:
base_prompt: Base prompt
modifier_pairs: List of (modifier_id_1, modifier_id_2) tuples
Returns:
List of comparison variation sets
"""
comparisons = []
for mod_a, mod_b in modifier_pairs:
prompt_a = self.orchestrator.apply_lighting_modifier(base_prompt, mod_a)
prompt_b = self.orchestrator.apply_lighting_modifier(base_prompt, mod_b)
comparisons.append({
"comparison_type": f"modifier_{mod_a}_vs_{mod_b}",
"variant_a": {
"modifier_id": mod_a,
"description": self.orchestrator.modifiers[mod_a].description,
"prompt": prompt_a
},
"variant_b": {
"modifier_id": mod_b,
"description": self.orchestrator.modifiers[mod_b].description,
"prompt": prompt_b
}
})
return comparisons
def example_workflows():
"""Demonstrate various workflow scenarios"""
processor = BatchProcessor(output_dir="prompt_variations")
print("BATCH PROCESSING WORKFLOWS\n")
print("=" * 80)
# Workflow 1: Single prompt with all lighting variations
print("\n1. FULL LIGHTING CYCLE GENERATION")
print("-" * 80)
base_prompt_1 = "Luxury sedan in urban environment, architectural background"
config_full = {
"lighting_ids": "all",
"export_format": "json"
}
output_1 = processor.process_multiple_prompts(
prompts=[base_prompt_1],
config=config_full,
output_filename="full_lighting_cycle"
)
print(f"✓ Generated full lighting cycle → {output_1}")
# Workflow 2: Multiple prompts with preset
print("\n2. KEY MOMENTS PRESET (Multiple Prompts)")
print("-" * 80)
base_prompts = [
"Sports car on mountain road, scenic vista",
"Classic convertible on beach, sunset backdrop",
"Electric SUV in modern city, glass buildings"
]
variations = []
for prompt in base_prompts:
vars = processor.create_preset_collection(prompt, "key_moments")
variations.extend(vars)
print(f"✓ Generated {len(variations)} variations across {len(base_prompts)} base prompts")
# Workflow 3: Style transformations
print("\n3. STYLE TRANSFORMATION SET")
print("-" * 80)
base_prompt_3 = "Vintage motorcycle in garage, mechanical details"
config_styles = {
"lighting_ids": [7], # Golden hour only
"styles": ["cyberpunk", "art_deco", "minimalist", "noir"],
"export_format": "txt"
}
output_3 = processor.process_multiple_prompts(
prompts=[base_prompt_3],
config=config_styles,
output_filename="style_variations"
)
print(f"✓ Generated style variations → {output_3}")
# Workflow 4: Comparison set
print("\n4. COMPARISON SET GENERATION")
print("-" * 80)
base_prompt_4 = "Modern architecture, geometric forms"
comparison_pairs = [
(4, 7), # Midday vs Golden Hour
(11, 18), # Night dry vs Night wet
(1, 8) # Sunrise vs Sunset
]
comparisons = processor.generate_comparison_set(base_prompt_4, comparison_pairs)
# Save comparisons
output_4 = processor.output_dir / "comparisons.json"
with open(output_4, "w", encoding="utf-8") as f:
json.dump(comparisons, f, indent=2)
print(f"✓ Generated {len(comparisons)} comparison sets → {output_4}")
# Workflow 5: Commercial photography set
print("\n5. COMMERCIAL PHOTOGRAPHY PRESET")
print("-" * 80)
base_prompt_5 = "Product shot of smartwatch, clean background"
commercial_vars = processor.create_preset_collection(base_prompt_5, "commercial")
print(f"✓ Generated {len(commercial_vars)} commercial-grade variations")
print("\n" + "=" * 80)
print("All workflows completed successfully!")
print(f"Output directory: {processor.output_dir}")
def quick_generation_example():
"""Quick example for immediate use"""
orchestrator = PromptOrchestrator()
# Your base prompt
base = "Ferrari on coastal highway at sunset"
print("\nQUICK GENERATION EXAMPLES")
print("=" * 80)
# Generate 5 quick variations
variations = [
orchestrator.apply_lighting_modifier(base, 1), # Sunrise
orchestrator.apply_lighting_modifier(base, 7), # Golden hour
orchestrator.apply_lighting_modifier(base, 10), # Blue hour
orchestrator.apply_lighting_modifier(base, 18), # Blue hour wet
orchestrator.apply_style_transformation(base, "cyberpunk")
]
for i, var in enumerate(variations, 1):
print(f"\n{i}. {var}")
if __name__ == "__main__":
# Run example workflows
example_workflows()
# Quick generation
quick_generation_example()