Files
imagepipeline/pipelines/pipeline_team_gallery_match.py
Frank Schwenk ce431d7eec feat: resume fixes, OpenRouter templates, and project context
Delegate expected output filenames to modules so resume works for rembg
and composite; normalize G'MIC multi-frame output; add OpenRouter style
reference support with tests. Add Crusaders, orange, and team gallery
pipelines plus SOUL/AGENTS context files.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-12 10:45:00 +02:00

78 lines
2.5 KiB
Python

#!/usr/bin/env python3
"""Match new team member photos to an existing player gallery style via OpenRouter."""
import os
from pathlib import Path
from imagepipeline import Pipeline
REPO_ROOT = Path(__file__).resolve().parents[1]
ENV_FILE = REPO_ROOT / ".env"
# Folder with new member photos to style-match.
INPUT = Path("/home/frank/tmp/spieler")
# One existing gallery player image as style reference.
TEMPLATE_IMAGE = Path("/home/frank/Downloads/2026_AHC_44_Julius-Nikolaus_Dittus-524-scaled.webp")
OUTPUT_BASE = Path.home() / "pipeline_output"
OPENROUTER_MODEL = "google/gemini-3-pro-image"
GALLERY_MATCH_PROMPT = (
"Match the second image to the first image's gallery style so it fits seamlessly "
"alongside the other players. Match color grading, white balance, contrast, "
"saturation, lighting direction, background treatment, sharpness, and overall "
"polish. "
"CRITICAL: Do not alter the person's face, identity, facial features, expression, "
"hair, pose, body shape, or clothing details. Do not crop, reframe, or change the "
"aspect ratio. Do not add or remove people or objects. "
"Keep the exact same image dimensions and composition — only adjust global style "
"and color to match the reference."
)
def _load_env_file(path: Path) -> None:
if not path.is_file():
return
for raw_line in path.read_text(encoding="utf-8").splitlines():
line = raw_line.strip()
if not line or line.startswith("#"):
continue
key, sep, value = line.partition("=")
if not sep:
continue
key = key.strip()
value = value.strip()
if len(value) >= 2 and value[0] == value[-1] and value[0] in "\"'":
value = value[1:-1]
os.environ.setdefault(key, value)
def main() -> None:
_load_env_file(ENV_FILE)
with Pipeline(
name="team_gallery_match",
input_dir=INPUT,
output_base=OUTPUT_BASE,
) as p:
p.step(
"openrouter_edit",
inputs="input",
prompt=GALLERY_MATCH_PROMPT,
model=OPENROUTER_MODEL,
template_image=TEMPLATE_IMAGE,
# Downscale for API, then upscale back to original dimensions.
# Use 0 only if you accept higher cost/latency for ~10 MB sources.
max_edge=4096,
skip_existing=True,
)
output_root = p.run()
print(f"Pipeline finished. Output: {output_root}")
if __name__ == "__main__":
main()