Thomas Chauvel
Add photographer-friendly focal length controls
535b594
"""
Pydantic models for FIBO Virtual Photo Studio.
These are app-internal schemas that get mapped to FIBO's API format.
"""
from pydantic import BaseModel, Field
from typing import Optional, List, Dict, Any
class CameraControls(BaseModel):
fov: int = Field(default=47, ge=12, le=120, description="Field of view in degrees (12°=200mm, 28°=85mm, 47°=50mm, 84°=24mm)")
aperture: float = Field(default=2.8, ge=1.2, le=16.0, description="Aperture f-stop")
shutter: float = Field(default=0.008, ge=0.001, le=1.0, description="Shutter speed in seconds")
iso: int = Field(default=200, ge=100, le=6400, description="ISO sensitivity")
class CompositionControls(BaseModel):
angle: str = Field(default="eye_level", description="Camera angle")
framing: str = Field(default="rule_of_thirds", description="Framing style")
class LightingControls(BaseModel):
preset: str = Field(default="softbox_warm", description="Lighting preset name")
intensity: int = Field(default=60, ge=0, le=100, description="Light intensity percentage")
direction: str = Field(default="key_left", description="Light direction")
class WhiteBalance(BaseModel):
kelvin: int = Field(default=5600, ge=3000, le=7500, description="Color temperature in Kelvin")
tint: int = Field(default=3, ge=-10, le=10, description="Tint adjustment")
class ColorControls(BaseModel):
palette: List[str] = Field(default=["#F7E7CE", "#7C5E3B"], description="Color palette as hex values")
contrast: int = Field(default=6, ge=-10, le=10, description="Contrast adjustment")
saturation: int = Field(default=-4, ge=-10, le=10, description="Saturation adjustment")
wb: WhiteBalance = Field(default_factory=WhiteBalance)
class BackgroundControls(BaseModel):
style: str = Field(default="studio_paper_beige", description="Background style")
class FilmProfile(BaseModel):
name: str = Field(default="Portra400-ish", description="Film emulation name")
class Controls(BaseModel):
camera: CameraControls = Field(default_factory=CameraControls)
composition: CompositionControls = Field(default_factory=CompositionControls)
lighting: LightingControls = Field(default_factory=LightingControls)
color: ColorControls = Field(default_factory=ColorControls)
background: BackgroundControls = Field(default_factory=BackgroundControls)
film_profile: FilmProfile = Field(default_factory=FilmProfile)
class Resolution(BaseModel):
width: int = Field(default=1024, ge=512, le=2048)
height: int = Field(default=1024, ge=512, le=2048)
class RenderSettings(BaseModel):
guidance: float = Field(default=7.5, ge=1.0, le=20.0, description="Guidance scale")
steps: int = Field(default=28, ge=10, le=50, description="Number of inference steps")
variation_count: int = Field(default=4, ge=1, le=4, description="Number of variations to generate")
resolution: Resolution = Field(default_factory=Resolution)
seed: Optional[int] = Field(default=None, description="Random seed for reproducibility")
class Preset(BaseModel):
name: str = Field(default="Virtual Photo Studio Preset")
prompt: str = Field(default="studio product shot of a {{PRODUCT}}")
negative_prompt: str = Field(default="blurry, watermark, oversaturated, amateur")
controls: Controls = Field(default_factory=Controls)
render: RenderSettings = Field(default_factory=RenderSettings)
# Style Profile Models
class ToneCurve(BaseModel):
shadows: float = Field(default=-6, ge=-20, le=20)
midtones: float = Field(default=0, ge=-20, le=20)
highlights: float = Field(default=5, ge=-20, le=20)
class HSLChannel(BaseModel):
channel: str = Field(description="Color channel (red, orange, yellow, green, cyan, blue, purple, magenta)")
s: float = Field(default=0, ge=-100, le=100, description="Saturation adjustment")
l: float = Field(default=0, ge=-100, le=100, description="Lightness adjustment")
class Grain(BaseModel):
strength: float = Field(default=0.3, ge=0.0, le=1.0)
size: float = Field(default=0.8, ge=0.1, le=2.0)
class Halation(BaseModel):
strength: float = Field(default=0.2, ge=0.0, le=1.0)
radius: int = Field(default=10, ge=1, le=50)
class StyleProfile(BaseModel):
name: str = Field(default="Detected_Brand_Style")
palette: List[str] = Field(default=["#EEDFCC", "#826C4A", "#2F3E4F"], description="Brand color palette")
tone_curve: ToneCurve = Field(default_factory=ToneCurve)
wb: WhiteBalance = Field(default_factory=WhiteBalance)
hsl: Optional[List[HSLChannel]] = Field(default=None, description="Per-channel HSL adjustments")
grain: Grain = Field(default_factory=Grain)
halation: Halation = Field(default_factory=Halation)