Files
cultivation-world-simulator/tools/img_gen/gen_img.py
2025-10-31 01:37:28 +08:00

176 lines
7.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import base64
from datetime import datetime
import requests
# 全局配置:请在此处填入你的 DashScope API Key
API_KEY = "sk-26818d3a4eb14b41a71f4d0319e4edfa" # <-- 在此处粘贴你的 API Key
BASE_URL = "https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"
MODEL = "qwen-image-plus"
def generate_qwen_image(prompt: str, *, size: str = "1328*1328") -> str:
"""调用 DashScope 原生接口生成图片,返回 base64 字符串。
入参:
prompt: 生成图片的提示词
size: 图片尺寸,形如 "宽*高"(例如 "1328*1328"
返回:
base64 字符串(不带 data: 前缀),可自行解码保存为图片
"""
if not API_KEY:
raise RuntimeError("请先在代码顶部设置 API_KEY")
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {API_KEY}",
}
payload = {
"model": MODEL,
"input": {
"messages": [
{
"role": "user",
"content": [
{"text": prompt}
],
}
]
},
"parameters": {
"negative_prompt": "",
"prompt_extend": True,
"watermark": True,
"size": size,
},
}
r = requests.post(BASE_URL, headers=headers, json=payload, timeout=120)
r.raise_for_status()
data = r.json()
def extract_image_from_content(content_list):
"""从 content 列表中提取图片,优先 URL 后 base64"""
for item in content_list:
if not isinstance(item, dict):
continue
# 尝试提取 URL
url = item.get("image") or item.get("image_url") or item.get("url")
if isinstance(url, str) and url.startswith("http"):
img_bytes = requests.get(url, timeout=120).content
return base64.b64encode(img_bytes).decode("utf-8")
# 尝试提取 base64
b64 = item.get("b64") or item.get("b64_json") or item.get("image_base64")
if isinstance(b64, str) and len(b64) > 100:
return b64
return None
output = data.get("output", {})
# 尝试路径1output.choices[0].message.content[*]
choices = output.get("choices", [])
if choices:
content_list = choices[0].get("message", {}).get("content", [])
result = extract_image_from_content(content_list)
if result:
return result
# 尝试路径2output.results[0].content[*]
results = output.get("results", [])
if results:
content_list = results[0].get("content", [])
result = extract_image_from_content(content_list)
if result:
return result
raise RuntimeError("未获得图片结果")
def save_generated_image(query: str, folder: str = "tools/img_gen/tmp/raw") -> str:
"""根据查询生成图片并保存到 result 目录。
入参:
query: 图片生成的提示词
返回:
保存的图片文件路径
"""
b64 = generate_qwen_image(query)
img_bytes = base64.b64decode(b64)
result_dir = folder
os.makedirs(result_dir, exist_ok=True)
filename = datetime.now().strftime("%Y%m%d_%H%M%S") + ".png"
out_path = os.path.join(result_dir, filename)
with open(out_path, "wb") as f:
f.write(img_bytes)
print(f"图片已保存: {out_path}")
return out_path
if __name__ == "__main__":
female_prompt_base = "一个好看的仙侠女性头像。只有头部和面部。二次元风格的漫画图片略微Q版正面看镜头。纯白背景。像素风格细节别太多。"
female_affixes = [
"紫色长发,表情嗔怒,带有一丝冷峻,有一个簪子。",
"乌黑直发,眉心一点红砂,清冷淡漠,镶玉步摇。",
"银白短发,英气微笑,发梢轻卷,耳坠为小灵铃。",
"墨绿长发,高马尾,目光坚毅,额前碎发,佩青竹簪。",
"渐变粉蓝长卷发,眸有星点,温柔含笑,薄纱额饰。",
"赤红披发,英气冷艳,眉尾上挑,凤羽发冠。",
"浅金长发,缎带系发,气质圣洁,流苏步摇。",
"乌青长发,微皱眉,眼尾红妆,一枚冰晶发卡。",
"白发如雪,神情淡然,眉心月印,玉质头箍。",
"靛蓝长发,俏皮眨眼,脸颊淡粉,葫芦小发簪。",
"茶棕双丸子头,活泼微笑,脸上淡淡雀斑,小葵花发卡。",
"青丝长发半披半挽,清雅端庄,蝶形玉簪。",
"淡紫短波浪发,俏皮吐舌,星月耳饰。",
"墨发低侧马尾,冷静专注,细链额饰垂坠。",
"湖绿挑染长发,狡黠微笑,狐耳发饰点缀。",
"灰蓝长直发,平刘海,面无表情,银环头饰。",
]
male_prompt_base = "一个英俊的的仙侠男性头像。只有头部和面部。二次元风格的漫画图片略微Q版正面看镜头。纯白背景。像素风格细节别太多。"
male_affixes = [
"乌发高束,剑眉星目,气质冷峻,青玉发冠。",
"银白长发,淡笑从容,额间玄纹,流苏头箍。",
"墨发披肩,脸上一抹浅疤,坚毅沉稳,黑金发簪。",
"深棕短发,目光凌厉,薄唇紧抿,皮绳束发。",
"蓝黑长发,发尾微卷,温润如玉,白玉簪。",
"赤褐长发,桀骜挑眉,轻笑不羁,耳坠小铜铃。",
"玄青半束发,沉静内敛,额前碎发,银纹额饰。",
"白发如雪,清隽淡笑,眉心一点冰蓝印,细环头饰。",
"墨发高马尾,目如寒星,英气逼人,羽纹发冠。",
"亚麻色短发,随性浅笑,轻胡茬,细革头环。",
"乌青长发,神情冷淡,眼神专注,剑形耳坠。",
"银灰长直发,肃杀气质,额缠黑带,简洁利落。",
"深紫挑染长发,狡黠微笑,眸底流光,狐尾发饰。",
"墨发半披,眼神温和从容,玉串发夹。",
"金棕长发,爽朗大笑,额前碎发,兽牙发簪。",
"青黑短发,专注坚定,线条硬朗,细链发饰垂坠。",
]
sect_prompt_base = "像素化的仙侠宗门场景图片,极度像素化,颗粒感强,线条轮廓粗,极简主义,二次元风格漫画图片。"
sect_affixes = [
"山巅飘渺云海,云纹禁制光芒环绕,远处群峰。",
"灵兽栖地,兽栏密布,岩石兽穴。",
"湖面倒影,中央悬浮巨大水镜,镜面波光粼粼,雾气弥漫。",
"幽冥宗门,阴暗昏沉,黑雾弥漫,冷厉气息,幽蓝鬼火点点。",
"炼器工坊,机关密布,熔炉火光。",
"合欢宫殿,粉红雾气,花瓣飘舞,柔和光晕,纱幔轻垂。",
"镇魂大殿,铁血肃杀,封印符文,镇压法阵,黑铁锁链。",
"幽影之地,暗影重重,光影交错,幽冥之气,黑雾吞噬轮廓。",
"船帆如云,炼器炉火。",
]
# for affix in male_affixes:
# prompt_text = male_prompt_base + affix
# save_generated_image(prompt_text, folder="tools/img_gen/tmp/males")
# for affix in female_affixes:
# prompt_text = female_prompt_base + affix
# save_generated_image(prompt_text, folder="tools/img_gen/tmp/females")
for i, affix in enumerate(sect_affixes):
prompt_text = sect_prompt_base + affix
save_generated_image(prompt_text, folder="tools/img_gen/tmp/sects")