104 lines
4.9 KiB
Python
104 lines
4.9 KiB
Python
#!/usr/bin/env python3
|
|
"""CHAR-003 苏白 V2 R6 · Seedream 4.0 · R3-02风格 + 17-18岁年轻化"""
|
|
import os, sys, json, time, subprocess
|
|
from pathlib import Path
|
|
|
|
# 读 .env
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
ENV_FILE = ROOT / ".env"
|
|
env = {}
|
|
if ENV_FILE.exists():
|
|
for line in open(ENV_FILE):
|
|
line = line.strip()
|
|
if line and not line.startswith("#") and "=" in line:
|
|
k, v = line.split("=", 1)
|
|
env[k.strip()] = v.strip()
|
|
|
|
AK = env.get("JIMENG_API_KEY", "")
|
|
URL = env.get("JIMENG_BASE_URL", "https://ark.cn-beijing.volces.com/api/v3")
|
|
MODEL = "doubao-seedream-4-0-250828"
|
|
OUT = ROOT / "assets/candidates/D158-VA-05-001-V2/CHAR-003-SuBai/R6"
|
|
SIZE = "1440x2560"
|
|
|
|
# === R3-02 风格 · 年轻化到17-18岁 ===
|
|
POSITIVE = """Chinese 3D donghua character, Bu Liang Ren Wan Yao Tu Lu Zhuan art style, realistic 3D rendering, full-body male portrait on pure white background. A 17-18 year old youthful male protagonist, handsome teenage face with defined but softened jawline compared to mature men, sharp sword-like eyebrows, bright lively youthful eyes, confident charming smile showing boyish charm. Not mature man, not baby face cartoon, not cute anime. Youthful bone structure with subtle angularity, natural young masculine beauty, clean smooth skin. Long black hair half tied in high bun with dark ribbon, half flowing naturally down shoulders with lustrous weight. White crossed-collar long robe, sleeves rolled back revealing wrists, dark cyan sash tied at waist, pristine clean fabric with realistic subtle folds. Standing confidently with hands on hips, upright athletic teenage build, broad shoulders, energetic youthful posture. Ancient Chinese cultivation fantasy aesthetic, cinematic soft lighting. Asian young male teenager."""
|
|
|
|
NEGATIVE = """cartoon rendering, Q style, Disney, cute doll face, round chubby face, big anime eyes, Japanese anime style, feminine face, braided hair, dress, skirt, female clothing. mature face, old man, wrinkled, middle-aged, facial hair, beard. photorealistic photo, deformed limbs, facial collapse, blurry, text watermark, clipping, weird lighting, low pixel, damaged clothes, patches, stains, beggar, homeless, hunched back, gloomy expression. Zhuge Feng face similarity."""
|
|
|
|
VARIANTS = [
|
|
"Confident bright smile looking directly at viewer, boyish charm and youthful energy.",
|
|
"Slightly tilted head, charismatic grin, bright spirited eyes full of life.",
|
|
"Relaxed confident stance, warm natural smile, teenage protagonist charm.",
|
|
"Heroic upright pose, dazzling confident smile, energetic youthful cultivator spirit."
|
|
]
|
|
|
|
SEEDS = [777, 333, 555, 999]
|
|
|
|
def generate(prompt, neg, seed):
|
|
api_url = f"{URL}/images/generations"
|
|
body = json.dumps({
|
|
"model": MODEL,
|
|
"prompt": prompt,
|
|
"negative_prompt": neg,
|
|
"size": SIZE,
|
|
"n": 1,
|
|
"seed": seed
|
|
})
|
|
r = subprocess.run([
|
|
"curl", "-s", "-m", "120", "--noproxy", "*",
|
|
"-X", "POST", api_url,
|
|
"-H", f"Authorization: Bearer {AK}",
|
|
"-H", "Content-Type: application/json",
|
|
"-d", body
|
|
], capture_output=True, text=True, timeout=130)
|
|
try:
|
|
d = json.loads(r.stdout)
|
|
return d["data"][0].get("url")
|
|
except:
|
|
print(f" API error: {r.stdout[:200]}")
|
|
return None
|
|
|
|
def download(url, dst):
|
|
Path(dst).parent.mkdir(parents=True, exist_ok=True)
|
|
subprocess.run(["curl", "-s", "-m", "120", "-L", "--noproxy", "*", "-o", dst, url],
|
|
capture_output=True, timeout=130)
|
|
return os.path.exists(dst) and os.path.getsize(dst) > 1024
|
|
|
|
def main():
|
|
print("CHAR-003 V2 R6 · Seedream 4.0 · R3-02风格 + 17-18岁")
|
|
if not AK:
|
|
print("ERROR: No API key (JIMENG_API_KEY not found)")
|
|
return 1
|
|
|
|
ts = time.strftime("%Y%m%d-%H%M%S")
|
|
OUT.mkdir(parents=True, exist_ok=True)
|
|
results = []
|
|
|
|
for i, (seed, var) in enumerate(zip(SEEDS, VARIANTS)):
|
|
full_prompt = f"{POSITIVE} {var}"
|
|
print(f"[{i+1}/4] seed={seed}", flush=True)
|
|
url = generate(full_prompt, NEGATIVE, seed)
|
|
if not url:
|
|
results.append({"c": i+1, "ok": False, "err": "api"})
|
|
continue
|
|
dst = OUT / f"CHAR-003-V2-R6-candidate-{i+1:02d}-1440x2560.png"
|
|
if not download(url, str(dst)):
|
|
results.append({"c": i+1, "ok": False, "err": "dl"})
|
|
continue
|
|
results.append({"c": i+1, "ok": True, "raw": str(dst), "seed": seed})
|
|
print(f" → {dst.name}")
|
|
time.sleep(3)
|
|
|
|
ok = sum(1 for r in results if r["ok"])
|
|
print(f"完成: {ok}/4")
|
|
|
|
meta = {"spec": "VA-05-001-V2-R6", "ts": ts, "ok": ok,
|
|
"model": MODEL, "size": SIZE, "engine": "Seedream",
|
|
"results": results}
|
|
with open(OUT / "generation-meta.json", "w", encoding="utf-8") as f:
|
|
json.dump(meta, f, ensure_ascii=False, indent=2)
|
|
return 0 if ok >= 4 else 1
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|