guanghulab/video-ai-system/tools/char004_gen_r4.py

86 lines
4.6 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""CHAR-004 R4 · 朴素修仙学徒制服 · 纯文生图 · 删所有旧化词"""
import sys, os, json, time, subprocess
from pathlib import Path
sys.path.insert(0, os.path.dirname(__file__))
from secrets_loader import secret, endpoint
API_KEY = secret("SC-001")
BASE_URL = endpoint("EPT-001")
MODEL = "doubao-seedream-4-0-250828"
ROOT = Path(__file__).resolve().parents[1]
JZAO = Path("/Volumes/JZAO/铸渊-ICE-GL-ZY001/OUT-输出/图片/zai-fu-fei-xiu-xian/ep01")
CANDIDATES = ROOT / "assets/candidates/D157-VA-05-001-R4" / "CHAR-004-ZhugeFeng"
POSITIVE = """3D动漫卡通渲染国风玄幻动态漫质感单人男性角色全身立绘纯白背景。
角色为16岁少年清瘦挺拔身高约175cm肩宽略窄身形单薄但精神利落不佝偻不颓废小麦色肤色面部轮廓棱角分明剑眉星目眼神锐利有韧劲鼻梁挺直嘴唇偏薄下颌线清晰少年气强气质冷硬黑色短发高束半马尾发尾有少量碎发用普通深棕色木簪固定额前散落几缕碎发整体整洁
服装为灰蓝色素面交领修仙学徒袍整洁干净布料平整无瑕疵右衽袖口收窄贴合手腕内搭浅色中衣腰间系深棕色麻绳腰带系法简单下装为深灰蓝同色长裤裤脚干净收进黑色短靴黑色粗布短靴厚鞋底鞋面干净
腰间麻绳上挂一个拳头大小的深灰色布包布包完整平整朴素但不破旧
整体气质朴素克制坚韧是普通宗门弟子出身干净利落有少年锐气不是乞丐不是流民不是流浪汉不是穷人
人物完整居中露出比例协调线条清晰色彩柔和卡通渲染3D动漫角色质感"""
NEGATIVE = """乞丐流民流浪汉穷人破旧服装破损破洞补丁污渍泥污脏鞋破裤腿烂袖口脏布包粗糙布料廉价质感过度旧化褪色严重裤脚脏鞋面脏衣服下摆毛边布料磨损乞丐感流民感破旧感寒酸感衣衫不整佝偻颓废萎靡肮脏凌乱CHAR-003同款脸CHAR-003同款五官CHAR-003同款发型与苏白长相相似真人照片写实畸形肢体五官崩坏模糊水印。"""
VARS = [
"正面直视镜头,表情沉稳有韧劲",
"微微侧身站姿,目光坚毅看向前方",
"略微仰视,下颌抬起,眼神向上有向往",
"3/4侧脸侧视左前方少年英气",
]
def gen(prompt, neg, seed):
url = f"{BASE_URL}/images/generations"
proc = subprocess.run(["curl","-s","-m","120","--noproxy","*","-X","POST",url,
"-H",f"Authorization: Bearer {API_KEY}",
"-H","Content-Type: application/json",
"-d",json.dumps({"model":MODEL,"prompt":prompt,"negative_prompt":neg,"size":"1440x2560","n":1,"seed":seed})],
capture_output=True,text=True,timeout=130)
try:
d = json.loads(proc.stdout)
if "data" in d: return d["data"][0].get("url")
except: pass
return None
def dl(url, dst):
Path(dst).parent.mkdir(parents=True,exist_ok=True)
subprocess.run(["curl","-s","-m","60","-L","--noproxy","*","-o",dst,url],capture_output=True,timeout=65)
return os.path.exists(dst) and os.path.getsize(dst)>1024
def main():
print("CHAR-004 R4 · 朴素修仙学徒制服")
if not API_KEY: sys.exit("✗ no key")
ts = time.strftime("%Y%m%d-%H%M%S")
raw_dir = JZAO / "D157-R4" / ts
raw_dir.mkdir(parents=True,exist_ok=True)
CANDIDATES.mkdir(parents=True,exist_ok=True)
results = []
for i,(seed,var) in enumerate(zip([42,137,256,399],VARS)):
full = f"{POSITIVE} {var}"
print(f"[{i+1}/4] seed={seed}",flush=True)
url = gen(full,NEGATIVE,seed)
if not url: results.append({"c":i+1,"ok":False,"err":"api"}); continue
raw = raw_dir/f"CHAR-004-R4-{i+1:02d}-1440x2560.jpg"
if not dl(url,raw): results.append({"c":i+1,"ok":False,"err":"dl"}); continue
scaled = CANDIDATES/f"CHAR-004-R4-candidate-{i+1:02d}-1080x1920.jpg"
subprocess.run(["sips","-z","1920","1080",str(raw),"--out",str(scaled)],capture_output=True)
results.append({"c":i+1,"ok":True,"raw":str(raw),"scaled":str(scaled),"seed":seed})
time.sleep(2)
ok = sum(1 for r in results if r["ok"])
print(f"完成: {ok}/4")
with open(CANDIDATES/"generation-meta.json","w") as f:
json.dump({"spec":"VA-05-001-R4","asset":"CHAR-004","ts":ts,"ok":ok,"total":4,"results":results},f,ensure_ascii=False,indent=2)
return 0 if ok>=4 else 1
if __name__=="__main__":
sys.exit(main())