"""Eleven views; no taggers or training-caption generation.""" from dataclasses import dataclass PROMPT_VERSION = "pose-transfer-v2" @dataclass(frozen=True) class View: key: str label: str camera: str pose: str frame: str shape: str = "portrait" STAND = "Stand upright in a neutral relaxed A-pose, arms lowered, legs narrowly spaced." SIT = "Sit on the ground hugging both knees against the chest, arms around the shins, feet on the floor." PRONE = "Lie face down on the stomach, legs straight, arms bent resting near the head." FULL = "Show the entire body including the top of the head and both feet." COWBOY = "Frame from the top of the head to mid-thigh; the knees and feet are outside the frame." VIEWS = ( View("full_front", "全身 正面", "front view, eye-level shot", STAND, FULL), View("full_left", "全身 左側面", "left side view, eye-level shot", STAND, FULL), View("full_right", "全身 右側面", "right side view, eye-level shot", STAND, FULL), View("full_back", "全身 背面", "back view, eye-level shot", STAND, FULL), View("cowboy_front", "腿上 正面", "front view, eye-level shot", "", COWBOY, "square"), View("cowboy_back", "腿上 背面", "back view, eye-level shot", "", COWBOY, "square"), View("upper_front", "上半身 正面", "front view, eye-level shot", "", "Show only the head, shoulders and chest; waist and legs are outside the frame.", "square"), View("face_front", "顔 正面", "front view, eye-level shot", "", "Close-up portrait showing the head and face, with only the top of the shoulders visible.", "square"), View("knees_front", "膝抱え 正面", "front view, eye-level shot", SIT, FULL), View("knees_back", "膝抱え 背面", "back view, eye-level shot", SIT, FULL), View("prone_back", "うつ伏せ 後方・俯瞰", "back view, high-angle shot", PRONE, FULL, "landscape"), ) BY_KEY = {view.key: view for view in VIEWS} DEFAULT_KEYS = list(BY_KEY) SIZES = { "fast": {"portrait": (512, 768), "square": (640, 640), "landscape": (768, 512)}, "standard": {"portrait": (832, 1216), "square": (1024, 1024), "landscape": (1216, 832)}, } SIZES["balanced"] = SIZES["standard"] REFERENCE_RESOLUTION = {"fast": 640, "balanced": 640, "standard": 1024} def validate_keys(keys): if not keys: raise ValueError("視点を1つ以上選択してください。") if any(key not in BY_KEY for key in keys): raise ValueError("不明な視点が含まれています。") return list(dict.fromkeys(keys)) def make_prompt(view, extra="", pose_guide=True, angles=False): parts = [] if angles: # Qwen 2.1 adapter grammar; the 2511 grammar is NOT used. parts.append(" " + view.camera + (" close-up" if view.key in ("face_front", "upper_front") else "")) if pose_guide: parts.append( "Edit Image 2: replace its grey mannequin with the character from Image 1. " "Keep Image 2's pose, body orientation, camera, crop and placement in the frame. " "Image 1 supplies only the character design, outfit, hair and rendering style; " "do not preserve Image 1's pose, camera direction or framing. " "Render the character's normal skin and clothing, with no mannequin joints or grey material." ) else: parts.append("Reshoot the character in Image 1 from the requested camera and framing.") if view.key in ("full_back", "cowboy_back", "knees_back"): parts.append( "Strict rear view. The character faces away from the viewer. " "Show the back of the head, back of the hair and back of the clothing. " "The face, eyes and front of the chest are hidden." ) elif view.key == "full_left": parts.append("Strict profile, with the nose pointing to the RIGHT edge of the image.") elif view.key == "full_right": parts.append("Strict profile, with the nose pointing to the LEFT edge of the image.") elif view.key == "prone_back": parts.append( "Look down at the character's back while they lie face down on the floor. " "Their chest and face point toward the floor, not toward the camera. " "Place the head at the RIGHT of the image and feet at the LEFT, matching Image 2." if pose_guide else "Look down at the character's back while they lie face down on the floor. " "Their chest and face point toward the floor, not toward the camera." ) parts.extend(["Camera: " + view.camera + ".", view.pose, view.frame, "Preserve the identity, hair, outfit details, colors and visual style from Image 1. " "Use a plain white background. One character, no text, no collage.", extra.strip()]) return " ".join(part for part in parts if part)