Add camera angle, lighting, backdrop (+ color) fields; expand hairstyles/expressions/poses; structured multi-paragraph prompt output

This commit is contained in:
Perry Dolmans
2026-07-13 10:33:35 +02:00
parent cc0b29f25e
commit f4ab67cfbb
3 changed files with 501 additions and 49 deletions
+480 -44
View File
@@ -8,7 +8,7 @@
{
"key": "character",
"type": "form_builder",
"template": "{shot_type}. A {androgyny} {origin} {gender}, {age}, {build_type} build, {height}. {skin_tone} complexion {skin_details}, {skin_realism}, {skin_pores}, {freckles}, {moles}, {dimples}, {skin_imperfections}. {face_shape} face, {facial_asymmetry}, {lip_color} {lip_shape} lips, {makeup}, {expression}. {beard}. {eye_color} {eye_shape} eyes, {eye_details}. {hair_color} hair, {hair_style}, {hair_length}, {dishevelment}. Wardrobe: {wardrobe}. {pose}. Shot on {camera_type}, {focal_length} lens at {aperture}. Neutral pale grey seamless studio backdrop, soft even key light. Photoreal, natural unretouched skin texture, subtle facial asymmetry, lifelike detailed eyes, natural color, authentic, unfiltered.",
"template": "{shot_type}.\n\nA {androgyny} {origin} {gender}, {age}, {build_type} build, {height}.\n\n{skin_tone} complexion {skin_details}, {skin_realism}, {skin_pores}, {freckles}, {moles}, {dimples}, {skin_imperfections}.\n\n{face_shape} face, {facial_asymmetry}, {lip_color} {lip_shape} lips, {makeup}, {expression}. {beard}.\n\n{eye_color} {eye_shape} eyes, {eye_details}.\n\n{hair_color} hair, {hair_style}, {hair_length}, {dishevelment}.\n\nWardrobe: {wardrobe}.\n\n{pose}.\n\nShot on {camera_type}, {focal_length} lens at {aperture}, {camera_angle}.\n\n{backdrop_color} {backdrop}, {lighting}.\n\nPhotoreal, natural unretouched skin texture, subtle facial asymmetry, lifelike detailed eyes, natural color, authentic, unfiltered.",
"seed_default": 0,
"default_engine": "fast",
"fields": [
@@ -501,19 +501,43 @@
"label": "Expressie",
"group": "Gezicht",
"allow_custom": true,
"default": "relaxed natural smile",
"default": "neutral",
"options": [
"relaxed natural smile",
"amused",
"angry",
"anxious",
"aroused",
"blissful",
"bored",
"concentrated",
"confused",
"contemptuous",
"crying",
"disgusted",
"ecstatic",
"embarrassed",
"excited",
"fearful",
"focused",
"frowning",
"happy",
"intense",
"laughing",
"lustful",
"neutral",
"soft smile",
"serious",
"confident",
"playful",
"pensive",
"serene",
"joyful",
"horny",
"intense gaze"
"overwhelmed",
"passionate",
"proud",
"relaxed",
"sad",
"satisfied",
"sensual",
"shocked",
"skeptical",
"smiling",
"surprised",
"tired",
"yearning"
]
},
{
@@ -639,22 +663,152 @@
"label": "Haarstijl",
"group": "Haar",
"allow_custom": true,
"default": "loose beach waves, centre part",
"default": "beach waves",
"options": [
"loose beach waves",
"straight and sleek",
"soft waves",
"1970s long cut",
"angled bob",
"balayage",
"bangs",
"bantu knots",
"beach waves",
"blunt chin bob",
"bob",
"boho waves",
"box braids",
"braided ballerina bun",
"braided bun",
"braided chignon",
"braided cornrows",
"braided headband",
"braided low ponytail",
"braided ponytail",
"braided side bun",
"braided side sweep",
"braided sock bun",
"braided top knot",
"braided twist-out",
"braided updo",
"braided wrap-around ponytail",
"bubble ponytail",
"bun",
"buzz cut",
"cascading curls",
"center part",
"chignon",
"comb over",
"cornrow updo",
"cornrows",
"crew cut",
"curled ends",
"curls with bangs",
"curly",
"tight curls",
"afro",
"blunt bob",
"pixie cut",
"long straight",
"curly bangs",
"curly faux hawk",
"curly half-up",
"curly ponytail",
"curly side sweep",
"curly undercut",
"curtain bangs",
"curtain fringe",
"double bun",
"double French braids",
"fade",
"faux hawk",
"faux locs",
"finger coils",
"finger waves",
"fishtail braid",
"fishtail updo",
"flamboyage",
"flat twist",
"French braid",
"French twist",
"frohawk",
"goddess braids",
"half-down",
"half-up",
"high ponytail",
"highlights",
"honeycomb locs",
"layered",
"lob",
"low bun",
"low fade",
"low ponytail",
"low ponytail with twist",
"messy bun",
"braided",
"messy pixie",
"messy side braid",
"milkmaid braids",
"mullet",
"pigtails",
"pinned back",
"pinned curls",
"pixie cut",
"pompadour",
"pompadour fade",
"ponytail",
"puff",
"quiff",
"rolled bangs",
"rope braid",
"scissor fade",
"sculpted curls",
"shag",
"sharp shoulder cut",
"shaved designs",
"side bun",
"side part",
"side shave",
"side-swept",
"side-swept curls",
"sleek and straight",
"sleek bob",
"sleek fishtail",
"sleek low bun",
"sleek top knot",
"slicked back",
"shoulder-length layers"
"slicked back undercut",
"slicked ponytail",
"slicked side part",
"slicked-back bun",
"slicked-back quiff",
"soft waves",
"sombre",
"space buns",
"spiky",
"spiral curls",
"straight",
"swoop bangs",
"tapered cut",
"textured bob",
"textured messy bun",
"textured pixie",
"textured side sweep",
"top knot",
"tucked updo",
"twist braids",
"twist out",
"twisted bangs",
"twisted chignon",
"twisted half-up",
"twisted ponytail",
"twisted side updo",
"twisted top knot",
"twisted updo",
"undercut",
"updo",
"v-shaped layers",
"victory rolls",
"vintage curls",
"voluminous curls",
"voluminous high ponytail",
"voluminous side-swept bangs",
"voluminous updo",
"waterfall braid",
"waterfall twist",
"wavy",
"wet look"
]
},
{
@@ -716,17 +870,88 @@
"label": "Pose",
"group": "Uitvoer",
"allow_custom": true,
"default": "relaxed natural standing pose",
"default": "Standing straight with hands at sides",
"options": [
"relaxed natural standing pose",
"hand on hip",
"contrapposto stance",
"walking mid-stride",
"seated relaxed",
"dynamic action pose",
"arms crossed",
"candid over-the-shoulder glance",
"high-fashion editorial pose"
"Sitting cross-legged",
"Standing with hands on hips",
"Leaning against a wall",
"Jumping with arms raised",
"Lying on the stomach, propped up on elbows",
"Sitting with one leg folded",
"Posing with arms folded",
"Running with hands extended",
"Leaning forward with hands on knees",
"Standing on tiptoes",
"Spinning with arms outstretched",
"Crouching with hands on the ground",
"Arching the back",
"Bending over with hands touching toes",
"Kneeling with one hand on the thigh",
"Standing straight with hands clasped behind",
"Dancing with arms in the air",
"Twirling hair with fingers",
"Sitting with legs extended",
"Reaching high with both hands",
"Sitting, leaning on one hand",
"Kneeling with head bowed",
"Lying on the side, propped up on one elbow",
"Leaping with legs extended",
"Stretching both arms overhead",
"Balancing on one foot",
"Squatting with hands on ankles",
"Sitting with hands clasping the knee",
"Standing with one hand on the hip",
"Walking with hands swinging by sides",
"Sitting with legs crossed at ankles",
"Leaning back with hands stretched out",
"Standing with one leg bent",
"Bending sideways with one hand reaching down",
"Lying flat on the back with arms at sides",
"Dancing with one hand on the hip",
"Standing with arms behind the head",
"Kneeling with both hands on thighs",
"Running with arms pumping at sides",
"Sitting with back hunched",
"Leaping with one hand reaching up",
"Standing with one foot in front of the other",
"Lounging with one hand behind the head",
"Sitting with one knee up, hand on knee",
"Standing straight with hands at sides",
"Standing with arms crossed over chest",
"Sitting with legs tucked under",
"Dancing with one arm raised",
"Lying flat with hands under the head",
"Balancing with arms outstretched",
"Leaning forward with one hand on the knee",
"Jumping with legs apart",
"Sitting with one hand on the cheek",
"Standing with arms hanging loosely",
"Kneeling with one knee up",
"Lying on the side with knees bent",
"Standing with one hand on the waist",
"Walking with one hand in the pocket",
"Crouching with both hands on the ground",
"Sitting, hugging knees to chest",
"Standing with one hand waving",
"Lying on the back with knees up",
"Kneeling, hands folded in lap",
"Sitting with legs outstretched",
"Standing with one foot on tiptoe",
"Walking with an exaggerated stride",
"Leaning forward with hands on thighs",
"Sitting, leaning forward with elbows on knees",
"Walking with hands in pockets",
"Leaning back, arms folded",
"Sitting cross-legged with hands on knees",
"Kneeling with hands on the floor",
"Standing with one hand over the heart",
"Lying on the side, one hand propping up head",
"Standing with hands behind the back",
"Sitting with hands in the lap",
"Walking with arms swinging in rhythm",
"Standing with hands in pockets",
"Kneeling with one hand reaching out",
"Standing with arms stretched out"
]
},
{
@@ -780,6 +1005,162 @@
"f/11",
"f/16"
]
},
{
"key": "camera_angle",
"type": "enum",
"label": "Camera-hoek",
"group": "Camera & lens",
"allow_custom": true,
"default": "eye level",
"options": [
"bird's eye view",
"boom shot",
"close-up",
"crane shot",
"dolly shot",
"dutch angle",
"eye level",
"fish-eye lens",
"handheld shot",
"high angle",
"jib shot",
"long shot",
"low angle",
"oblique angle",
"overhead shot",
"point-of-view shot",
"pov from above",
"pov from behind",
"pov from below",
"steadicam shot",
"tilt shot",
"tracking shot",
"wide shot",
"worm's eye view",
"zoom shot"
]
},
{
"key": "lighting",
"type": "enum",
"label": "Belichting",
"group": "Belichting",
"allow_custom": true,
"default": "soft even key light",
"options": [
"soft even key light",
"key light from the left, soft fill",
"key light from the right, soft fill",
"key light from above, soft fill",
"45-degree key light",
"rim light from top left",
"rim light from top right",
"rim light from behind",
"backlight from behind",
"top-down light from above",
"underlight from below",
"window light from the left",
"window light from the right",
"side light from the left",
"side light from the right",
"accent lighting",
"ambient lighting",
"backlight",
"bright neon lighting",
"broad lighting",
"candlelight",
"chiaroscuro",
"clamshell lighting",
"color temperature lighting",
"contre-jour lighting",
"direct flash photography",
"fluorescent lighting",
"fresnel lighting",
"gelled lighting",
"glowy luminescence",
"glowy translucency",
"hard shadows",
"high-key lighting",
"hmi lighting",
"iridescent light",
"led panel lighting",
"light painting",
"loop lighting",
"low-key lighting",
"luminescence",
"moody low-light",
"motivated lighting",
"paramount lighting",
"practical lighting",
"radiant god rays",
"rembrandt lighting",
"rim lighting",
"short lighting",
"silhouetted against the bright window",
"soft bounced lighting",
"soft diffused lighting",
"soft fill lighting",
"soft natural lighting",
"specular lighting",
"split lighting",
"strobe lighting",
"strong side key lights",
"three-point lighting",
"translucency",
"tungsten lighting",
"warm golden hour lighting"
]
},
{
"key": "backdrop_color",
"type": "enum",
"label": "Achtergrond-kleur",
"group": "Achtergrond",
"allow_custom": true,
"default": "neutral pale grey",
"options": [
"neutral pale grey",
"white",
"off-white",
"light grey",
"mid grey",
"charcoal",
"black",
"deep blue",
"teal",
"warm amber",
"muted green",
"dusty pink",
"burgundy",
"cool blue-grey"
]
},
{
"key": "backdrop",
"type": "enum",
"label": "Achtergrond",
"group": "Achtergrond",
"allow_custom": true,
"default": "seamless studio backdrop",
"options": [
"seamless studio backdrop",
"seamless paper backdrop",
"gradient studio backdrop",
"plain painted wall",
"textured concrete wall",
"exposed brick wall",
"wooden panel wall",
"soft fabric curtain",
"blurred city street",
"blurred urban night scene",
"blurred park greenery",
"blurred café interior",
"cozy indoor interior",
"minimalist interior",
"blurred forest",
"blurred beach"
]
}
],
"engines": [
@@ -806,17 +1187,72 @@
},
"default_format": "land",
"formats": [
{"key": "uw_21_9", "label": "Ultrawide 21:9 · 1440×608", "w": 1440, "h": 608},
{"key": "land", "label": "Liggend 16:9 · 1440×800", "w": 1440, "h": 800},
{"key": "land_3_2", "label": "Liggend 3:2 · 1440×960", "w": 1440, "h": 960},
{"key": "land_4_3", "label": "Liggend 4:3 · 1440×1088", "w": 1440, "h": 1088},
{"key": "land_5_4", "label": "Liggend 5:4 · 1440×1152", "w": 1440, "h": 1152},
{"key": "square", "label": "Vierkant 1:1 · 1440×1440", "w": 1440, "h": 1440},
{"key": "port_4_5", "label": "Staand 4:5 · 1152×1440", "w": 1152, "h": 1440},
{"key": "port_3_4", "label": "Staand 3:4 · 1088×1440", "w": 1088, "h": 1440},
{"key": "port_2_3", "label": "Staand 2:3 · 960×1440", "w": 960, "h": 1440},
{"key": "port", "label": "Staand 9:16 · 800×1440", "w": 800, "h": 1440},
{"key": "port_9_21", "label": "Staand 9:21 · 608×1440", "w": 608, "h": 1440}
{
"key": "uw_21_9",
"label": "Ultrawide 21:9 · 1440×608",
"w": 1440,
"h": 608
},
{
"key": "land",
"label": "Liggend 16:9 · 1440×800",
"w": 1440,
"h": 800
},
{
"key": "land_3_2",
"label": "Liggend 3:2 · 1440×960",
"w": 1440,
"h": 960
},
{
"key": "land_4_3",
"label": "Liggend 4:3 · 1440×1088",
"w": 1440,
"h": 1088
},
{
"key": "land_5_4",
"label": "Liggend 5:4 · 1440×1152",
"w": 1440,
"h": 1152
},
{
"key": "square",
"label": "Vierkant 1:1 · 1440×1440",
"w": 1440,
"h": 1440
},
{
"key": "port_4_5",
"label": "Staand 4:5 · 1152×1440",
"w": 1152,
"h": 1440
},
{
"key": "port_3_4",
"label": "Staand 3:4 · 1088×1440",
"w": 1088,
"h": 1440
},
{
"key": "port_2_3",
"label": "Staand 2:3 · 960×1440",
"w": 960,
"h": 1440
},
{
"key": "port",
"label": "Staand 9:16 · 800×1440",
"w": 800,
"h": 1440
},
{
"key": "port_9_21",
"label": "Staand 9:21 · 608×1440",
"w": 608,
"h": 1440
}
]
},
{
+12 -5
View File
@@ -23,11 +23,18 @@ def compose_wardrobe(value: dict | None) -> str:
def _cleanup(text: str) -> str:
text = re.sub(r"\s+", " ", text)
text = re.sub(r"\s+([,.])", r"\1", text)
text = re.sub(r",\s*,", ",", text)
text = re.sub(r"\(\s*\)", "", text)
return text.strip()
# Behoud alinea-breaks (witregels) tussen blokken; schoon binnen elk blok op.
blocks = re.split(r"\n\s*\n", text)
cleaned = []
for b in blocks:
b = re.sub(r"\s+", " ", b)
b = re.sub(r"\s+([,.])", r"\1", b)
b = re.sub(r",\s*,", ",", b)
b = re.sub(r"\(\s*\)", "", b)
b = b.strip()
if b:
cleaned.append(b)
return "\n\n".join(cleaned)
def compose_form(cb_param: dict, value: dict) -> str:
+9
View File
@@ -61,6 +61,15 @@ def test_wardrobe_default_fallback_and_override():
assert node_compose.compose_form(cb, {"fields": {}, "wardrobe": {"mode": "free", "text": "a red gown"}}) == "Wardrobe: a red gown."
def test_compose_preserves_paragraph_breaks():
cb = {"template": "{a}\n\n{b}\n\n{c}",
"fields": [{"key": "a", "type": "text", "default": "first block"},
{"key": "b", "type": "text", "default": ""},
{"key": "c", "type": "text", "default": "third block"}]}
# witregels blijven tussen blokken; een leeg blok wordt weggelaten
assert node_compose.compose_form(cb, {"fields": {}, "wardrobe": None}) == "first block\n\nthird block"
@pytest.mark.skipif(app_compose is None, reason="orchestrator/compose.py niet beschikbaar (standalone repo)")
def test_parity_with_app_compose():
# De geporte kopie moet exact hetzelfde produceren als orchestrator/compose.py.