86 lines
4.6 KiB
Python
86 lines
4.6 KiB
Python
#!/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())
|