vesion 0.5.0 基座版本

This commit is contained in:
Wang Xiuqiang 2025-07-05 04:24:43 +08:00
parent 295fbb0cb4
commit a86b258a88
38 changed files with 1735 additions and 391 deletions

View File

@ -1,4 +1,4 @@
# AI海报生成系统
# 基于多种LLMs组合以及ComfyUI参与的定制化用户海报生成的智能融合ai系统
## 概述

View File

@ -122,30 +122,5 @@ if result["status"] == "success":
f.write(psd_response.content)
```
## 错误处理
```json
{
"status": "error",
"message": "错误描述",
"data": null
}
```
常见错误码:
- `400`: 请求参数错误
- `404`: 资源不存在
- `500`: 服务器内部错误
## 部署
### 开发环境
```bash
cd scripts
python run_pipeline.py # 选择2
```
### 生产环境
```bash
uvicorn scripts.run_pipeline:app --host 0.0.0.0 --port 8000
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 1.1 MiB

View File

@ -0,0 +1,8 @@
no text, no AI style
Cartoon-Style Nankai University Poster,
featuring the iconic main building with exaggerated playful proportions, its red-brick façade adorned with oversized arched windows glowing like amber honey. Towering pine trees with spiral-shaped needles frame the scene, while cheerful squirrels in tiny scarves scamper across cobblestone paths.
The clock tower stands tall, its face smiling like a friendly sun, with floating musical notes escaping the bells. Students with simplified, round faces carry stacks of books that emit tiny sparkles, their backpacks shaped like clouds. Cherry blossom petals drift in the air, each one a soft pink watercolor stroke.
Environment:
A gradient sky shifts from peach dawn to lavender twilight, dotted with cartoon stars. The lawn is a patchwork of emerald and lime, textured like plush felt. A mirrored lake reflects the building upside-down, rippling with tiny fish that leap as heart-shaped splashes. Fireflies hover near lanterns shaped like glowing pearls.

View File

@ -1,120 +0,0 @@
<template>
<div class="poster-container lotus-theme">
<div class="background-layer">
<img src="../outputs/lotus.jpg" alt="荷花背景" class="background-image" />
</div>
<div class="content-layer">
<div class="title-section">
<h1 class="main-title lotus-title">{{ title }}</h1>
<h2 class="subtitle lotus-subtitle">{{ subtitle }}</h2>
</div>
<div class="main-content lotus-content">
<div class="decoration-elements">
<div class="lotus-decoration"></div>
</div>
</div>
<div class="footer-section">
<div class="logo-area">
<span class="logo-text">{{ logoText }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const title = ref('端午节')
const subtitle = ref('粽叶飘香,龙舟竞渡')
const logoText = ref('')
</script>
<style scoped>
.poster-container {
width: 1080px;
height: 1920px;
position: relative;
overflow: hidden;
background: linear-gradient(135deg, #f8f4e6, #e8dcc0);
}
.background-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.background-image {
width: 100%;
height: 100%;
object-fit: cover;
opacity: 0.8;
}
.content-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.title-section {
position: absolute;
top: 20%;
left: 50%;
transform: translateX(-50%);
text-align: center;
width: 80%;
}
.lotus-title {
font-size: 64px;
font-weight: bold;
color: #2d5016;
text-shadow: 2px 2px 4px rgba(0,0,0,0.3);
margin-bottom: 20px;
font-family: 'SimSun', serif;
}
.lotus-subtitle {
font-size: 32px;
color: #4a6741;
margin-bottom: 40px;
font-family: 'KaiTi', cursive;
}
.lotus-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 70%;
}
.lotus-decoration {
width: 200px;
height: 200px;
background: radial-gradient(circle, rgba(255,192,203,0.6), rgba(255,182,193,0.3));
border-radius: 50%;
margin: 0 auto;
}
.footer-section {
position: absolute;
bottom: 10%;
left: 50%;
transform: translateX(-50%);
}
.logo-text {
font-size: 24px;
color: #2d5016;
font-weight: 500;
}
</style>

48
outputs/layout.json Normal file
View File

@ -0,0 +1,48 @@
{
"canvas": {
"width": 1080,
"height": 1920
},
"images": {
"background.png": {
"position": {
"x": 0,
"y": 0
},
"size": {
"width": 1080,
"height": 1920
}
},
"nankai.png": {
"position": {
"x": 390,
"y": 200
},
"size": {
"width": 300,
"height": 300
}
},
"lotus.jpg": {
"position": {
"x": 270,
"y": 960
},
"size": {
"width": 540,
"height": 500
}
},
"stamp.jpg": {
"position": {
"x": 800,
"y": 1600
},
"size": {
"width": 200,
"height": 200
}
}
}
}

View File

@ -1,16 +1,16 @@
{
"layer5_logo_content": {
"text": "",
"color": "#000000"
"color": "#7E0C6E"
},
"layer6_title_content": {
"content": "端午节",
"font_name": "SimHei",
"content": "南开风采",
"font_name": "FZLanTingHei-ExtraBold-GB",
"color": "#000000"
},
"layer7_subtitle_content": {
"content": "粽叶飘香,龙舟竞渡",
"font_name": "SimHei",
"color": "#7E0C6E"
"content": "百年学府,智慧之光",
"font_name": "Microsoft YaHei",
"color": "#333333"
}
}

225
outputs/poster_layout.vue Normal file
View File

@ -0,0 +1,225 @@
<template>
<div class="poster-container" :style="containerStyle">
<!-- 图片层 - 根据layout.json定义 -->
<div
v-for="(imageInfo, imageName) in layout.images"
:key="imageName"
class="image-layer"
:style="getImageStyle(imageInfo, imageName)"
></div>
<!-- 文本层 -->
<div class="text-layer title" :style="getTitleStyle()">
{{ content.layer6_title_content.content }}
</div>
<div class="text-layer subtitle" :style="getSubtitleStyle()">
{{ content.layer7_subtitle_content.content }}
</div>
<div
v-if="content.layer5_logo_content.text"
class="text-layer logo"
:style="getLogoStyle()"
>
{{ content.layer5_logo_content.text }}
</div>
</div>
</template>
<script>
import { ref, reactive, computed } from "vue";
// layout.jsonposter_content.json
// 使API
const layout = {
canvas: {
width: 1080,
height: 1920,
},
images: {
"background.png": {
position: {
x: 0,
y: 0,
},
size: {
width: 1080,
height: 1920,
},
},
"nankai.png": {
position: {
x: 390,
y: 200,
},
size: {
width: 300,
height: 300,
},
},
"lotus.jpg": {
position: {
x: 270,
y: 960,
},
size: {
width: 540,
height: 500,
},
},
"stamp.jpg": {
position: {
x: 800,
y: 1600,
},
size: {
width: 200,
height: 200,
},
},
},
};
const content = {
layer5_logo_content: {
text: "",
color: "#7E0C6E",
},
layer6_title_content: {
content: "南开风采",
font_name: "FZLanTingHei-ExtraBold-GB",
color: "#000000",
},
layer7_subtitle_content: {
content: "百年学府,智慧之光",
font_name: "Microsoft YaHei",
color: "#333333",
},
};
export default {
name: "PosterLayout",
setup() {
const baseUrl = "../outputs/"; //
//
const containerStyle = computed(() => {
return {
width: `${layout.canvas.width}px`,
height: `${layout.canvas.height}px`,
position: "relative",
overflow: "hidden",
background: "#ffffff",
};
});
//
const getImageStyle = (imageInfo, imageName) => {
return {
position: "absolute",
left: `${imageInfo.position.x}px`,
top: `${imageInfo.position.y}px`,
width: `${imageInfo.size.width}px`,
height: `${imageInfo.size.height}px`,
backgroundImage: `url(${baseUrl}${imageName})`,
backgroundSize: "cover",
backgroundPosition: "center",
backgroundRepeat: "no-repeat",
zIndex: imageName.includes("background") ? 1 : 2, //
};
};
//
const getTitleStyle = () => {
const titleContent = content.layer6_title_content;
return {
position: "absolute",
left: "150px",
top: "700px",
width: "780px",
textAlign: "center",
color: titleContent.color || "#000000",
fontFamily: titleContent.font_name || "SimHei",
fontSize: "80px",
fontWeight: "bold",
zIndex: 10,
textShadow: "2px 2px 4px rgba(0, 0, 0, 0.3)",
};
};
//
const getSubtitleStyle = () => {
const subtitleContent = content.layer7_subtitle_content;
return {
position: "absolute",
left: "200px",
top: "820px",
width: "680px",
textAlign: "center",
color: subtitleContent.color || "#333333",
fontFamily: subtitleContent.font_name || "Microsoft YaHei",
fontSize: "40px",
zIndex: 10,
};
};
// logo
const getLogoStyle = () => {
const logoContent = content.layer5_logo_content;
return {
position: "absolute",
left: "50px",
top: "50px",
color: logoContent.color || "#000000",
fontFamily: "Arial, sans-serif",
fontSize: "24px",
fontWeight: "bold",
zIndex: 10,
};
};
return {
layout,
content,
containerStyle,
getImageStyle,
getTitleStyle,
getSubtitleStyle,
getLogoStyle,
};
},
};
</script>
<style scoped>
.poster-container {
margin: 0 auto;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
}
.image-layer {
position: absolute;
}
.text-layer {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
}
.title {
font-size: 80px;
font-weight: bold;
}
.subtitle {
font-size: 40px;
}
.logo {
font-size: 24px;
font-weight: bold;
}
</style>

BIN
outputs/vue_generated.psd Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

View File

@ -25,6 +25,12 @@ tqdm==4.66.1
colorama==0.4.6
loguru==0.7.2
# PSD文件支持
psd-tools==1.10.0
# 日志和进度显示(可选)
rich==13.3.5
# 数据处理和存储
pandas==2.1.3
sqlalchemy==2.0.23

View File

@ -0,0 +1,263 @@
'''
* @file DeepSeekPromptGenerator.py
* @brief Generate optimized image prompts using DeepSeek API
*
* @author WuYingwen
* @GitHub @wuyingwen10
* @Contact 2211537@mail.nankai.edu.cn
* @date 2025-06-10
* @version v1.0.0
*
* @note
* - Uses DeepSeek API for prompt optimization
* - Supports multiple API configurations
*
* @copyright
* (c) 2025 Nankai University
'''
import requests
import json
import os
import sys
from datetime import datetime
SYSTEM_PROMPT_TEMPLATE = """
As an AI prompt engineering expert, please generate a prompt that meets the following requirements based on the topic I provide. Note: You should follow the style of the example (emulating the writing style only, not the content) and transform the user's request into a detailed prompt.
Requirements (strictly adhere to all six):
1: Use simple natural language sentences to describe the scene. Avoid overly long or complex sentence structures. Do not use special symbols like *.
2: Express in English.
3: Provide only the prompt content without any explanations or notes.
4: Each prompt must be at least 50 words but no more than 200 words.
5: Avoid ambiguous expressions.
6: Add "no text, no AI style" at the beginning.
Example:
no text, no AI style
Cartoon-Style Nankai University Main Building,
vividly depicted with rounded edges and pastel gradients, the iconic Gothic-Revival structure stands majestically. Crimson brick façade contrasts with golden-glowing arched windows, while whimsical cloud-shaped eaves drip melted clock details. A giant smiling sun hangs low, casting honey-golden rays through simplified pine trees, creating striped shadows dancing on marble stairs.
Translucent ghostly scholars from 1919 float near pillars holding glowing books, their outlines shimmering like liquid mercury. Oversized autumn leaves (stylized as maple-red origami) spiral around twin bell towers chiming visible musical notes. Puddles on the ground mirror upside-down building reflections rippling with calculus formulas.
Environment:
Surreal candy-pink sunset gradients blend into starry indigo sky above. Playful squirrels wearing tiny graduation caps scamper across emerald lawns textured like green velvet.
"""
API_CONFIGS = [
{
"name": "DeepSeek Official Chat API",
"model": "deepseek-chat",
"api_key": "sk-36de33a3827f43398ed027e733dbd74a",
"base_url": "https://api.deepseek.com"
},
{
"name": "DeepSeek-R1 Backup",
"model": "deepseek-r1",
"api_key": "sk-36de33a3827f43398ed027e733dbd74a",
"base_url": "https://cloud.infini-ai.com/maas/v1/"
},
{
"name": "DeepSeek-V3 Backup",
"model": "deepseek-v3",
"api_key": "sk-36de33a3827f43398ed027e733dbd74a",
"base_url": "https://cloud.infini-ai.com/maas/v1/"
}
]
def generate_prompt(user_topic):
"""Generate optimized prompt using DeepSeek API"""
full_prompt = SYSTEM_PROMPT_TEMPLATE + f"\n\nTopic: {user_topic}"
for config in API_CONFIGS:
try:
print(f"Attempting API: {config['name']}...")
endpoint = f"{config['base_url']}/chat/completions"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {config['api_key']}"
}
payload = {
"model": config["model"],
"messages": [{"role": "user", "content": full_prompt}],
"temperature": 0.7,
"max_tokens": 2000,
"stream": False
}
response = requests.post(endpoint, headers=headers, json=payload, timeout=30)
response.raise_for_status()
result = response.json()
return result['choices'][0]['message']['content'].strip()
except Exception as e:
print(f"Error with {config['name']}: {str(e)}")
continue
raise Exception("All API attempts failed")
def save_deepseek_output(prompt_content, output_prefix):
"""Save DeepSeek output to file with the same naming pattern as images"""
output_dir = "../outputs/deepseek_output"
os.makedirs(output_dir, exist_ok=True)
timestamp = datetime.now().strftime("%Y%m%d%H%M%S%f")[:-3]
filename = f"{output_prefix}_{timestamp}.txt"
file_path = os.path.join(output_dir, filename)
with open(file_path, "w", encoding="utf-8") as f:
f.write(prompt_content)
return file_path
def test_multiple_topics():
"""测试多个主题的提示词生成"""
test_topics = [
"设计一张南开大学的海报,要求风格为卡通风格,包含南开大学的标志性建筑和校园元素。",
"创建一个关于人工智能与未来科技的海报",
"设计一张关于环保主题的宣传海报"
]
print(f"{'-'*50}\n🧪 开始测试多个主题的提示词生成\n{'-'*50}")
results = []
for i, topic in enumerate(test_topics, 1):
print(f"\n📝 测试主题 {i}: {topic}")
try:
start_time = datetime.now()
prompt = generate_prompt(topic)
end_time = datetime.now()
# 计算执行时间
execution_time = (end_time - start_time).total_seconds()
# 保存提示词
prefix = f"测试_{i}"
output_file = save_deepseek_output(prompt, prefix)
# 截断显示(如果太长)
display_prompt = prompt[:200] + "..." if len(prompt) > 200 else prompt
results.append({
"topic": topic,
"success": True,
"time": execution_time,
"output_file": output_file,
"prompt_length": len(prompt)
})
print(f"✅ 成功生成提示词 ({len(prompt)} 字符, {execution_time:.2f}秒)")
print(f"📄 预览: {display_prompt}")
print(f"💾 已保存到: {output_file}")
except Exception as e:
print(f"❌ 生成失败: {str(e)}")
results.append({
"topic": topic,
"success": False,
"error": str(e)
})
# 打印汇总结果
print(f"\n{'-'*50}\n📊 测试结果汇总\n{'-'*50}")
success_count = sum(1 for r in results if r.get("success", False))
print(f"✅ 成功: {success_count}/{len(test_topics)}")
if success_count > 0:
avg_time = sum(r["time"] for r in results if r.get("success", False)) / success_count
avg_length = sum(r["prompt_length"] for r in results if r.get("success", False)) / success_count
print(f"⏱️ 平均执行时间: {avg_time:.2f}")
print(f"📏 平均提示词长度: {avg_length:.0f}字符")
return results
def test_api_configs():
"""测试所有API配置"""
print(f"{'-'*50}\n🧪 测试所有API配置\n{'-'*50}")
test_topic = "测试API配置的简单主题"
for i, config in enumerate(API_CONFIGS, 1):
print(f"\n🔌 测试API配置 {i}: {config['name']}")
print(f" 模型: {config['model']}")
print(f" URL: {config['base_url']}")
try:
# 构建提示词
full_prompt = SYSTEM_PROMPT_TEMPLATE + f"\n\nTopic: {test_topic}"
# 准备请求
endpoint = f"{config['base_url']}/chat/completions"
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {config['api_key']}"
}
payload = {
"model": config["model"],
"messages": [{"role": "user", "content": full_prompt}],
"temperature": 0.7,
"max_tokens": 100, # 减少token以加快测试
"stream": False
}
# 发送请求
start_time = datetime.now()
print(f" 🕒 发送请求...")
response = requests.post(endpoint, headers=headers, json=payload, timeout=10)
end_time = datetime.now()
execution_time = (end_time - start_time).total_seconds()
# 检查响应
response.raise_for_status()
result = response.json()
# 输出结果
print(f" ✅ API工作正常! 响应时间: {execution_time:.2f}")
print(f" 🔑 响应状态码: {response.status_code}")
print(f" 📦 模型回复: {result['choices'][0]['message']['content'][:50]}...")
except Exception as e:
print(f" ❌ API测试失败: {str(e)}")
def main():
"""主函数,运行多个测试"""
print(f"🚀 DeepSeek提示词生成器测试 - {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
# 运行标准测试
user_topic = "设计一张南开大学的海报,要求风格为卡通风格,包含南开大学的标志性建筑和校园元素。"
print(f"🔍 标准测试 - 主题: {user_topic}")
try:
prompt = generate_prompt(user_topic)
output_file = save_deepseek_output(prompt, "南开大学海报")
print(f"✅ 标准测试成功!")
print(f"📄 生成的提示词: {prompt[:100]}...")
print(f"💾 已保存到: {output_file}")
except Exception as e:
print(f"❌ 标准测试失败: {str(e)}")
# 询问用户是否运行更多测试
print("\n是否运行更多测试? (输入数字选择)")
print("1. 测试多个主题")
print("2. 测试API配置")
print("3. 运行所有测试")
print("0. 退出")
choice = input("请选择 (默认0): ").strip() or "0"
if choice == "1":
test_multiple_topics()
elif choice == "2":
test_api_configs()
elif choice == "3":
test_multiple_topics()
test_api_configs()
else:
print("退出测试。")
if __name__ == "__main__":
main()

View File

@ -0,0 +1,260 @@
'''
* @file GenerateImages.py
* @brief Generate images from text descriptions.
*
* @author WuYingwen
* @GitHub @wuyingwen10
* @Contact 2211537@mail.nankai.edu.cn
* @date 2025-06-08
* @version v1.0.2
*
* @details
* Core functionality:
* - Generate images from user-provided text prompts;
* - Generate optimized prompt statements based on user input;
* - Provides a clean interface for generating images from text prompts
*
* @note
* - For local server connections: Update COMFYUI_ENDPOINT with target address + port;
* - Timestamps prevent filename conflicts during image generation,perform simple string matching if necessary;
* - Filename format: "<file_prefix>_<timestamp>.png" (e.g., mountains_202507011210902.png);
* - Contact author for technical support;
*
* @interface
* generate_images_interface(
* user_topic: str,
* width: int,
* height: int,
* batch_size: int,
* file_prefix: str
* ) -> tuple
*
* @copyright
* (c) 2025 Nankai University
'''
import json
import os
import sys
import time
import uuid
import random
from datetime import datetime
from websocket import create_connection, WebSocketTimeoutException, WebSocketConnectionClosedException
import urllib.request
import urllib.parse
from DeepSeekPromptGenerator import generate_prompt, save_deepseek_output
def generate_images_interface(user_topic, width, height, batch_size, file_prefix):
deepseek_output_path = ""
try:
system_prompt = generate_prompt(user_topic)
deepseek_output_path = save_deepseek_output(system_prompt, file_prefix)
except Exception as e:
print(f"Prompt optimization failed: {str(e)}")
output_dir = 'output'
comfyui_server = '127.0.0.1:8188'
default_workflow = './workflows/flux_work.json'
temp_dir = './workflows/temp'
os.makedirs(temp_dir, exist_ok=True)
processed_workflow = os.path.join(temp_dir, f"processed_workflow_{uuid.uuid4().hex}.json")
workflow_file = preprocess_workflow(
system_prompt=user_topic,
width=width,
height=height,
batch_size=batch_size,
input_json=default_workflow,
output_json=processed_workflow
)
os.makedirs(output_dir, exist_ok=True)
client_id = str(uuid.uuid4())
image_files = generate_images(
workflow_file=workflow_file,
server_address=comfyui_server,
output_dir=output_dir,
client_id=client_id,
file_prefix=file_prefix
)
return (deepseek_output_path, image_files)
def generate_images_info(user_input_analysis, system_prompt):
width = user_input_analysis.get('width', 1024)
height = user_input_analysis.get('height', 768)
batch_size = user_input_analysis.get('batch_size', 1)
file_prefix = user_input_analysis.get('file_prefix', 'image')
OUTPUT_DIR = 'output'
COMFYUI_SERVER = '127.0.0.1:8188'
DEFAULT_WORKFLOW = './workflows/flux_work.json'
TEMP_DIR = './workflows/temp'
os.makedirs(TEMP_DIR, exist_ok=True)
PROCESSED_WORKFLOW = os.path.join(TEMP_DIR, f"processed_workflow_{uuid.uuid4().hex}.json")
workflow_file = preprocess_workflow(
system_prompt=system_prompt,
width=width,
height=height,
batch_size=batch_size,
input_json=DEFAULT_WORKFLOW,
output_json=PROCESSED_WORKFLOW
)
os.makedirs(OUTPUT_DIR, exist_ok=True)
client_id = str(uuid.uuid4())
image_files = generate_images(
workflow_file=workflow_file,
server_address=COMFYUI_SERVER,
output_dir=OUTPUT_DIR,
client_id=client_id,
file_prefix=file_prefix
)
image_list = []
for file_path in image_files:
filename = os.path.basename(file_path)
name_without_ext = os.path.splitext(filename)[0]
image_info = {
"image_name": name_without_ext,
"image_type": "png",
"image_description": system_prompt,
"image_dimensions": f"{width}x{height}"
}
image_list.append(image_info)
return image_list
def preprocess_workflow(system_prompt, width, height, batch_size, input_json='flux_work.json', output_json='processed_workflow.json'):
try:
with open(input_json, 'r', encoding='utf-8') as f:
workflow = json.load(f)
workflow['31']['inputs']['system_prompt'] = system_prompt
workflow['27']['inputs']['width'] = str(width)
workflow['27']['inputs']['height'] = str(height)
workflow['27']['inputs']['batch_size'] = str(batch_size)
with open(output_json, 'w', encoding='utf-8') as f:
json.dump(workflow, f, indent=2, ensure_ascii=False)
print(f"Workflow updated and saved to: {output_json}")
return output_json
except Exception as e:
print(f"Error processing workflow: {str(e)}")
sys.exit(1)
def queue_prompt(prompt, server_address, client_id):
payload = {"prompt": prompt, "client_id": client_id}
data = json.dumps(payload).encode('utf-8')
request = urllib.request.Request(f"http://{server_address}/prompt", data=data)
return json.loads(urllib.request.urlopen(request).read())
def get_image(filename, subfolder, folder_type, server_address):
params = {"filename": filename, "subfolder": subfolder, "type": folder_type}
url_values = urllib.parse.urlencode(params)
with urllib.request.urlopen(f"http://{server_address}/view?{url_values}") as response:
return response.read()
def get_history(prompt_id, server_address):
with urllib.request.urlopen(f"http://{server_address}/history/{prompt_id}") as response:
return json.loads(response.read())
def retrieve_images(ws, prompt, server_address, client_id, timeout=600):
prompt_id = queue_prompt(prompt, server_address, client_id)['prompt_id']
print(f'Prompt ID: {prompt_id}')
images_data = {}
start_time = time.time()
while True:
if time.time() - start_time > timeout:
print(f"Timeout: Execution took longer than {timeout} seconds")
break
try:
data = ws.recv()
if isinstance(data, str):
message = json.loads(data)
if message['type'] == 'executing':
content = message['data']
if content['node'] is None and content['prompt_id'] == prompt_id:
print('Execution completed')
break
except Exception as e:
print(f"Error receiving data: {str(e)}")
break
history = get_history(prompt_id, server_address).get(prompt_id, {})
if not history:
print("No history found for this prompt")
return {}
for node_id, node_data in history['outputs'].items():
if 'images' in node_data:
image_collection = []
for image in node_data['images']:
try:
img_data = get_image(image['filename'], image['subfolder'], image['type'], server_address)
image_collection.append({
'data': img_data,
'filename': image['filename'],
'subfolder': image['subfolder'],
'type': image['type']
})
except Exception as e:
print(f"Error retrieving image: {str(e)}")
images_data[node_id] = image_collection
print(f'Retrieved {len(images_data)} image outputs')
return images_data
def generate_images(workflow_file, server_address, output_dir, client_id, file_prefix="image"):
try:
with open(workflow_file, 'r', encoding='utf-8') as f:
workflow = json.load(f)
seed = random.randint(1, 10**8)
print(f'Using seed: {seed}')
workflow['25']['inputs']['noise_seed'] = seed
ws_url = f"ws://{server_address}/ws?clientId={client_id}"
ws = create_connection(ws_url, timeout=600)
images = retrieve_images(ws, workflow, server_address, client_id)
ws.close()
saved_files = []
if images:
for node_id, img_list in images.items():
for i, img in enumerate(img_list):
timestamp = datetime.now().strftime("%Y%m%d%H%M%S%f")[:-3]
filename = f"{file_prefix}_{timestamp}.png"
file_path = os.path.join(output_dir, filename)
try:
with open(file_path, "wb") as f:
f.write(img['data'])
saved_files.append(file_path)
print(f'Saved: {file_path}')
except Exception as e:
print(f"Error saving image: {str(e)}")
return saved_files
except Exception as e:
print(f"Image generation failed: {str(e)}")
return []

View File

@ -1,14 +0,0 @@
from export_psd import create_psd_from_images
if __name__ == "__main__":
image_list = [
'../images/background.jpg',
'../images/nankai.jpg',
'../images/aaai.png',
# Add more images as needed
]
create_psd_from_images(
image_paths=image_list,
output_path='../outputs/combined_output.psd'
)

View File

@ -86,15 +86,15 @@ def create_psd_from_images(
if __name__ == "__main__":
# 示例用法
image_list = [
'../images/background.jpg', # 底层图片
'../images/nankai.jpg', # 中间图片
'../images/aaai.png', # 顶层图片
# 可以根据需要添加更多图片
]
# 示例用法
preassigned_img_list_path=[
"../outputs/background.png",
"../outputs/lotus.jpg",
"../outputs/nankai.png",
"../outputs/stamp.jpg"
]
create_psd_from_images(
image_paths=image_list,
image_paths=preassigned_img_list_path,
output_path='../outputs/combined_output.psd'
)

View File

@ -48,7 +48,7 @@ load_dotenv()
deepseek_url = 'https://api.deepseek.com/v1' # set to be compatible with the OpenAI API
deepseek_api = os.getenv("DEEPSEEK_API_KEY")
if not deepseek_api:
raise ValueError("DEEPSEEK_API_KEY not set!")
raise ValueError("DEEPSEEK_API_KEY not set!")
def call_deepseek(
messages=None,

View File

@ -156,9 +156,6 @@ def create_psd_from_fixed_images(output_path: str) -> Optional[str]:
def run_pipeline(user_input: str = None) -> Optional[str]:
"""
简化的海报生成流程
"""
try:
print(f"{Fore.MAGENTA}{'=' * 50}")
print(f"{Fore.MAGENTA}🎨 海报生成流程启动 🎨")
@ -269,9 +266,6 @@ def health_check():
@app.post("/api/generate-poster", response_model=ApiResponse)
async def generate_poster_api(request: PosterRequest):
"""
简化的海报生成API接口
"""
try:
session_folder, session_id = get_session_folder(request.session_id)

View File

@ -1,208 +0,0 @@
# 自动执行流程说明文档
本流程通过多个脚本与配置文件协作,自动生成海报的排版、文案、图像并输出 PSD 文件,最终通过 API 提供服务。
---
## 一、自动执行流程的步骤
### 步骤 1: 配置加载
**目标**:加载必要的配置信息(如 API 密钥、字体规则、Prompt 模板)。
**涉及文件**
- `.env`:加载 DeepSeek API 密钥等环境变量。
- `configs/fonts.yaml`:加载字体与配色规则。
- `configs/prompts.json`:加载图像生成 Prompt 模板。
**过程**
- 使用 `dotenv` 加载 `.env` 中的 `DEEPSEEK_API_KEY`
- 使用 `yaml``json` 库加载 `fonts.yaml``prompts.json`
**输出**:配置对象(字典或类),供后续步骤使用。
---
### 步骤 2: 排版生成
**目标**:使用 LLM 生成海报的排版结构Vue 组件)。
**涉及文件**
- `scripts/generate_layout.py`:调用 DeepSeek API 生成 Vue 组件代码。
**过程**
- 调用 `generate_layout.py` 中的 `generate_vue_code` 函数。
- 传入从 `prompts.json` 动态读取的 Prompt结合字体规则生成 Vue 代码。
**输出**Vue 组件代码,保存为 `outputs/generated_code.vue`
---
### 步骤 3: 文案生成
**目标**:生成海报文案内容(标题、副标题、活动描述等)。
**涉及文件**
- `scripts/generate_text.py`:调用 LLM 生成文案。
**过程**
- 调用脚本生成端午节相关文案(如“端午安康”、“包粽子比赛”)。
- 文案可按 `prompts.json` 中模板动态调整。
**输出**:文案内容(字符串或字典),供后续步骤使用。
---
### 步骤 4: 图像生成
**目标**:使用 ComfyUI 生成海报图层。
**涉及文件**
- `comfyui_flows/layer_generation.json`:定义图层生成流程。
- `scripts/generate_images.py`:调用 ComfyUI API 生成图层。
- `images/`:存储背景、前景、文字图层。
**过程**
- 运行 `generate_images.py`,加载 `layer_generation.json`
- 根据排版与文案生成:
- `background.png`
- `foreground.png`
- `text_overlay.png`
**输出**:图像文件保存到 `images/` 目录。
---
### 步骤 5: 合成海报
**目标**:将图层合成为最终海报。
**涉及文件**
- `scripts/compose_poster.py`:合成图层脚本。
- `outputs/final_poster.png`:合成结果。
**过程**
- 读取 `generated_code.vue` 中的排版位置信息。
- 使用 `image_utils.py` 对图层进行合成。
**输出**`final_poster.png`
---
### 步骤 6: 导出 PSD 文件
**目标**:导出 PSD 文件以便后期修改。
**涉及文件**
- `scripts/export_psd.py`PSD 导出脚本。
- `outputs/final_poster.psd`:导出的 PSD 文件。
**过程**
- 将 `final_poster.png` 转换为 PSD。
- 保留图层信息。
**输出**`final_poster.psd`
---
### 步骤 7: 提供前端接口
**目标**:将结果通过 API 提供给前端调用。
**涉及文件**
- `run_pipeline.py`:协调整体流程并定义 API 接口。
**过程**
- 使用 `FastAPI``Flask` 创建端点(如 `/generate_poster`)。
- 接收前端请求,依次调用上述所有步骤。
- 返回最终文件的 URL 或文件流。
**输出**HTTP 响应,包含 `final_poster.png` 链接或文件流。
---
## 二、如何实现自动执行流程
### 环境准备
- **依赖安装**:确保 `requirements.txt` 包含以下依赖:
- `openai`
- `python-dotenv`
- `PyYAML`
- `requests`(用于 ComfyUI API 调用)
- `Pillow`(图像处理)
- `psd-tools`PSD 导出)
- **API 密钥配置**:在 `.env` 文件中添加以下字段:
```env
DEEPSEEK_API_KEY=your_api_key
COMFYUI_API_KEY=your_comfyui_key
```python
import os
from dotenv import load_dotenv
from scripts.generate_layout import generate_vue_code
from scripts.generate_text import generate_text # 假设存在
from scripts.generate_images import generate_images # 假设存在
from scripts.compose_poster import compose_poster # 假设存在
from scripts.export_psd import export_psd # 假设存在
import yaml
import json
from fastapi import FastAPI, HTTPException
from fastapi.responses import FileResponse
# 加载环境变量和配置
load_dotenv()
app = FastAPI()
with open("configs/fonts.yaml", "r", encoding="utf-8") as f:
fonts_config = yaml.safe_load(f)
with open("configs/prompts.json", "r", encoding="utf-8") as f:
prompts_config = json.load(f)
# 一键执行流程
def run_pipeline():
try:
# 步骤 1: 排版生成
layout_code = generate_vue_code()
with open("../outputs/generated_code.vue", "w", encoding="utf-8") as f:
f.write(layout_code)
# 步骤 2: 文案生成
text_content = generate_text(prompts_config.get("text_prompt", ""))
# 步骤 3: 图像生成
generate_images(
workflow_path="comfyui_flows/layer_generation.json",
text_content=text_content,
output_dir="images/"
)
# 步骤 4: 合成海报
compose_poster(
layout_path="../outputs/generated_code.vue",
image_dir="images/",
output_path="../outputs/final_poster.png"
)
# 步骤 5: 导出 PSD
export_psd(
input_path="../outputs/final_poster.png",
output_path="../outputs/final_poster.psd"
)
return "../outputs/final_poster.png"
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
# API 端点
@app.get("/generate_poster")
async def generate_poster():
output_path = run_pipeline()
return FileResponse(output_path, media_type="image/png")
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
```

View File

@ -101,7 +101,7 @@ def save_vue_file(vue_code: str, file_path: str):
print(f"{Fore.RED}❌ Vue文件保存失败: {e}{Style.RESET_ALL}")
def create_temp_config(user_input: str = None) -> str:
def create_temp_config(user_input: Optional[str] = None) -> str:
"""动态生成临时配置文件"""
if not user_input:
user_input = "默认海报配置"
@ -199,8 +199,11 @@ def llm_user_analysis(user_input: str) -> Dict:
try:
result, _ = call_deepseek(prompt=analysis_prompt, system_prompt=system_prompt, temperature=0.3)
# 确保result是字符串类型
result_str = str(result) if result is not None else ""
# 解析JSON
json_str = result.strip()
json_str = result_str.strip()
if "```json" in json_str:
json_str = json_str.split("```json")[1].split("```")[0].strip()
elif json_str.startswith("```") and json_str.endswith("```"):

View File

@ -0,0 +1,226 @@
{
"6": {
"inputs": {
"text": [
"31",
0
],
"clip": [
"11",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"13",
0
],
"vae": [
"10",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE解码"
}
},
"9": {
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"8",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "保存图像"
}
},
"10": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "加载VAE"
}
},
"11": {
"inputs": {
"clip_name1": "t5xxl_fp16.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "双CLIP加载器"
}
},
"12": {
"inputs": {
"unet_name": "flux1-dev.safetensors",
"weight_dtype": "default"
},
"class_type": "UNETLoader",
"_meta": {
"title": "UNet加载器"
}
},
"13": {
"inputs": {
"noise": [
"25",
0
],
"guider": [
"22",
0
],
"sampler": [
"16",
0
],
"sigmas": [
"17",
0
],
"latent_image": [
"27",
0
]
},
"class_type": "SamplerCustomAdvanced",
"_meta": {
"title": "自定义采样器(高级)"
}
},
"16": {
"inputs": {
"sampler_name": "euler"
},
"class_type": "KSamplerSelect",
"_meta": {
"title": "K采样器选择"
}
},
"17": {
"inputs": {
"scheduler": "simple",
"steps": 25,
"denoise": 1,
"model": [
"30",
0
]
},
"class_type": "BasicScheduler",
"_meta": {
"title": "基本调度器"
}
},
"22": {
"inputs": {
"model": [
"30",
0
],
"conditioning": [
"26",
0
]
},
"class_type": "BasicGuider",
"_meta": {
"title": "基本引导器"
}
},
"25": {
"inputs": {
"noise_seed": 142213168350829
},
"class_type": "RandomNoise",
"_meta": {
"title": "随机噪波"
}
},
"26": {
"inputs": {
"guidance": 3.5,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "Flux引导"
}
},
"27": {
"inputs": {
"width": "1080",
"height": "1920",
"batch_size": "2"
},
"class_type": "EmptySD3LatentImage",
"_meta": {
"title": "空Latent图像SD3"
}
},
"30": {
"inputs": {
"max_shift": 1.1500000000000001,
"base_shift": 0.5000000000000001,
"width": 1024,
"height": 1024,
"model": [
"12",
0
]
},
"class_type": "ModelSamplingFlux",
"_meta": {
"title": "采样算法Flux"
}
},
"31": {
"inputs": {
"user_prompt": "作为一个AI提示词专家请你仿照范例根据我给出的主题生成一条符合下列要求的提示词来让CLIP模型可以更好地理解画面主体。注意你需要仿照下面的示例详细分析仅仿照写法而不仿照任何内容将用户的需求转化为详细的提示词。\\n 要求共六条,请严格遵守:\\n 1 用自然语言简单句来描述画面,请避免出现过于长的,或者格式过于复杂的句子,句子中不要出现*等特殊符号。\\n 2.用英语表达。 \\n 3.直接给出prompt内容即可不需要任何解释和说明。\\n 4. 每条prompt至少50词不超过200词。\\n 5.避免模棱两可的说法。\\n 6.描述的最开始加入“no text, no AI style”\\n 例如:\nCartoon-Style Nankai University Main Building,\nvividly depicted with rounded edges and pastel gradients, the iconic Gothic-Revival structure stands majestically. Crimson brick façade contrasts with golden-glowing arched windows, while whimsical cloud-shaped eaves drip melted clock details. A giant smiling sun hangs low, casting honey-golden rays through simplified pine trees, creating striped shadows dancing on marble stairs.\n\nTranslucent ghostly scholars from 1919 float near pillars holding glowing books, their outlines shimmering like liquid mercury. Oversized autumn leaves (stylized as maple-red origami) spiral around twin bell towers chiming visible musical notes. Puddles on the ground mirror upside-down building reflections rippling with calculus formulas.\n\nEnvironment:\nSurreal candy-pink sunset gradients blend into starry indigo sky above. Playful squirrels wearing tiny graduation caps scamper across emerald lawns textured like green velvet.",
"system_prompt": "端午节庆祝",
"enable_history": false,
"max_history": 10,
"history_json": "",
"save_path": "./chat_history.json",
"api_config": [
"32",
0
]
},
"class_type": "DeepSeekChat",
"_meta": {
"title": "LLM Model Input Box"
}
},
"32": {
"inputs": {
"config_name": "DeepSeek官方Chat API",
"temperature": 1,
"max_tokens": 512,
"stream": false,
"api_key": ""
},
"class_type": "DeepSeekAPIConfig",
"_meta": {
"title": "LLM API Model Selector"
}
}
}

View File

@ -0,0 +1,226 @@
{
"6": {
"inputs": {
"text": [
"31",
0
],
"clip": [
"11",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"13",
0
],
"vae": [
"10",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE解码"
}
},
"9": {
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"8",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "保存图像"
}
},
"10": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "加载VAE"
}
},
"11": {
"inputs": {
"clip_name1": "t5xxl_fp16.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "双CLIP加载器"
}
},
"12": {
"inputs": {
"unet_name": "flux1-dev.safetensors",
"weight_dtype": "default"
},
"class_type": "UNETLoader",
"_meta": {
"title": "UNet加载器"
}
},
"13": {
"inputs": {
"noise": [
"25",
0
],
"guider": [
"22",
0
],
"sampler": [
"16",
0
],
"sigmas": [
"17",
0
],
"latent_image": [
"27",
0
]
},
"class_type": "SamplerCustomAdvanced",
"_meta": {
"title": "自定义采样器(高级)"
}
},
"16": {
"inputs": {
"sampler_name": "euler"
},
"class_type": "KSamplerSelect",
"_meta": {
"title": "K采样器选择"
}
},
"17": {
"inputs": {
"scheduler": "simple",
"steps": 25,
"denoise": 1,
"model": [
"30",
0
]
},
"class_type": "BasicScheduler",
"_meta": {
"title": "基本调度器"
}
},
"22": {
"inputs": {
"model": [
"30",
0
],
"conditioning": [
"26",
0
]
},
"class_type": "BasicGuider",
"_meta": {
"title": "基本引导器"
}
},
"25": {
"inputs": {
"noise_seed": 142213168350829
},
"class_type": "RandomNoise",
"_meta": {
"title": "随机噪波"
}
},
"26": {
"inputs": {
"guidance": 3.5,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "Flux引导"
}
},
"27": {
"inputs": {
"width": "1080",
"height": "1920",
"batch_size": "2"
},
"class_type": "EmptySD3LatentImage",
"_meta": {
"title": "空Latent图像SD3"
}
},
"30": {
"inputs": {
"max_shift": 1.1500000000000001,
"base_shift": 0.5000000000000001,
"width": 1024,
"height": 1024,
"model": [
"12",
0
]
},
"class_type": "ModelSamplingFlux",
"_meta": {
"title": "采样算法Flux"
}
},
"31": {
"inputs": {
"user_prompt": "作为一个AI提示词专家请你仿照范例根据我给出的主题生成一条符合下列要求的提示词来让CLIP模型可以更好地理解画面主体。注意你需要仿照下面的示例详细分析仅仿照写法而不仿照任何内容将用户的需求转化为详细的提示词。\\n 要求共六条,请严格遵守:\\n 1 用自然语言简单句来描述画面,请避免出现过于长的,或者格式过于复杂的句子,句子中不要出现*等特殊符号。\\n 2.用英语表达。 \\n 3.直接给出prompt内容即可不需要任何解释和说明。\\n 4. 每条prompt至少50词不超过200词。\\n 5.避免模棱两可的说法。\\n 6.描述的最开始加入“no text, no AI style”\\n 例如:\nCartoon-Style Nankai University Main Building,\nvividly depicted with rounded edges and pastel gradients, the iconic Gothic-Revival structure stands majestically. Crimson brick façade contrasts with golden-glowing arched windows, while whimsical cloud-shaped eaves drip melted clock details. A giant smiling sun hangs low, casting honey-golden rays through simplified pine trees, creating striped shadows dancing on marble stairs.\n\nTranslucent ghostly scholars from 1919 float near pillars holding glowing books, their outlines shimmering like liquid mercury. Oversized autumn leaves (stylized as maple-red origami) spiral around twin bell towers chiming visible musical notes. Puddles on the ground mirror upside-down building reflections rippling with calculus formulas.\n\nEnvironment:\nSurreal candy-pink sunset gradients blend into starry indigo sky above. Playful squirrels wearing tiny graduation caps scamper across emerald lawns textured like green velvet.",
"system_prompt": "端午节海报,传统风格",
"enable_history": false,
"max_history": 10,
"history_json": "",
"save_path": "./chat_history.json",
"api_config": [
"32",
0
]
},
"class_type": "DeepSeekChat",
"_meta": {
"title": "LLM Model Input Box"
}
},
"32": {
"inputs": {
"config_name": "DeepSeek官方Chat API",
"temperature": 1,
"max_tokens": 512,
"stream": false,
"api_key": ""
},
"class_type": "DeepSeekAPIConfig",
"_meta": {
"title": "LLM API Model Selector"
}
}
}

View File

@ -0,0 +1,226 @@
{
"6": {
"inputs": {
"text": [
"31",
0
],
"clip": [
"11",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"13",
0
],
"vae": [
"10",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE解码"
}
},
"9": {
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"8",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "保存图像"
}
},
"10": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "加载VAE"
}
},
"11": {
"inputs": {
"clip_name1": "t5xxl_fp16.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "双CLIP加载器"
}
},
"12": {
"inputs": {
"unet_name": "flux1-dev.safetensors",
"weight_dtype": "default"
},
"class_type": "UNETLoader",
"_meta": {
"title": "UNet加载器"
}
},
"13": {
"inputs": {
"noise": [
"25",
0
],
"guider": [
"22",
0
],
"sampler": [
"16",
0
],
"sigmas": [
"17",
0
],
"latent_image": [
"27",
0
]
},
"class_type": "SamplerCustomAdvanced",
"_meta": {
"title": "自定义采样器(高级)"
}
},
"16": {
"inputs": {
"sampler_name": "euler"
},
"class_type": "KSamplerSelect",
"_meta": {
"title": "K采样器选择"
}
},
"17": {
"inputs": {
"scheduler": "simple",
"steps": 25,
"denoise": 1,
"model": [
"30",
0
]
},
"class_type": "BasicScheduler",
"_meta": {
"title": "基本调度器"
}
},
"22": {
"inputs": {
"model": [
"30",
0
],
"conditioning": [
"26",
0
]
},
"class_type": "BasicGuider",
"_meta": {
"title": "基本引导器"
}
},
"25": {
"inputs": {
"noise_seed": 142213168350829
},
"class_type": "RandomNoise",
"_meta": {
"title": "随机噪波"
}
},
"26": {
"inputs": {
"guidance": 3.5,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "Flux引导"
}
},
"27": {
"inputs": {
"width": "1080",
"height": "1920",
"batch_size": "2"
},
"class_type": "EmptySD3LatentImage",
"_meta": {
"title": "空Latent图像SD3"
}
},
"30": {
"inputs": {
"max_shift": 1.1500000000000001,
"base_shift": 0.5000000000000001,
"width": 1024,
"height": 1024,
"model": [
"12",
0
]
},
"class_type": "ModelSamplingFlux",
"_meta": {
"title": "采样算法Flux"
}
},
"31": {
"inputs": {
"user_prompt": "作为一个AI提示词专家请你仿照范例根据我给出的主题生成一条符合下列要求的提示词来让CLIP模型可以更好地理解画面主体。注意你需要仿照下面的示例详细分析仅仿照写法而不仿照任何内容将用户的需求转化为详细的提示词。\\n 要求共六条,请严格遵守:\\n 1 用自然语言简单句来描述画面,请避免出现过于长的,或者格式过于复杂的句子,句子中不要出现*等特殊符号。\\n 2.用英语表达。 \\n 3.直接给出prompt内容即可不需要任何解释和说明。\\n 4. 每条prompt至少50词不超过200词。\\n 5.避免模棱两可的说法。\\n 6.描述的最开始加入“no text, no AI style”\\n 例如:\nCartoon-Style Nankai University Main Building,\nvividly depicted with rounded edges and pastel gradients, the iconic Gothic-Revival structure stands majestically. Crimson brick façade contrasts with golden-glowing arched windows, while whimsical cloud-shaped eaves drip melted clock details. A giant smiling sun hangs low, casting honey-golden rays through simplified pine trees, creating striped shadows dancing on marble stairs.\n\nTranslucent ghostly scholars from 1919 float near pillars holding glowing books, their outlines shimmering like liquid mercury. Oversized autumn leaves (stylized as maple-red origami) spiral around twin bell towers chiming visible musical notes. Puddles on the ground mirror upside-down building reflections rippling with calculus formulas.\n\nEnvironment:\nSurreal candy-pink sunset gradients blend into starry indigo sky above. Playful squirrels wearing tiny graduation caps scamper across emerald lawns textured like green velvet.",
"system_prompt": "端午节海报,传统风格",
"enable_history": false,
"max_history": 10,
"history_json": "",
"save_path": "./chat_history.json",
"api_config": [
"32",
0
]
},
"class_type": "DeepSeekChat",
"_meta": {
"title": "LLM Model Input Box"
}
},
"32": {
"inputs": {
"config_name": "DeepSeek官方Chat API",
"temperature": 1,
"max_tokens": 512,
"stream": false,
"api_key": ""
},
"class_type": "DeepSeekAPIConfig",
"_meta": {
"title": "LLM API Model Selector"
}
}
}

View File

@ -0,0 +1,226 @@
{
"6": {
"inputs": {
"text": [
"31",
0
],
"clip": [
"11",
0
]
},
"class_type": "CLIPTextEncode",
"_meta": {
"title": "CLIP Text Encode (Positive Prompt)"
}
},
"8": {
"inputs": {
"samples": [
"13",
0
],
"vae": [
"10",
0
]
},
"class_type": "VAEDecode",
"_meta": {
"title": "VAE解码"
}
},
"9": {
"inputs": {
"filename_prefix": "ComfyUI",
"images": [
"8",
0
]
},
"class_type": "SaveImage",
"_meta": {
"title": "保存图像"
}
},
"10": {
"inputs": {
"vae_name": "ae.safetensors"
},
"class_type": "VAELoader",
"_meta": {
"title": "加载VAE"
}
},
"11": {
"inputs": {
"clip_name1": "t5xxl_fp16.safetensors",
"clip_name2": "clip_l.safetensors",
"type": "flux",
"device": "default"
},
"class_type": "DualCLIPLoader",
"_meta": {
"title": "双CLIP加载器"
}
},
"12": {
"inputs": {
"unet_name": "flux1-dev.safetensors",
"weight_dtype": "default"
},
"class_type": "UNETLoader",
"_meta": {
"title": "UNet加载器"
}
},
"13": {
"inputs": {
"noise": [
"25",
0
],
"guider": [
"22",
0
],
"sampler": [
"16",
0
],
"sigmas": [
"17",
0
],
"latent_image": [
"27",
0
]
},
"class_type": "SamplerCustomAdvanced",
"_meta": {
"title": "自定义采样器(高级)"
}
},
"16": {
"inputs": {
"sampler_name": "euler"
},
"class_type": "KSamplerSelect",
"_meta": {
"title": "K采样器选择"
}
},
"17": {
"inputs": {
"scheduler": "simple",
"steps": 25,
"denoise": 1,
"model": [
"30",
0
]
},
"class_type": "BasicScheduler",
"_meta": {
"title": "基本调度器"
}
},
"22": {
"inputs": {
"model": [
"30",
0
],
"conditioning": [
"26",
0
]
},
"class_type": "BasicGuider",
"_meta": {
"title": "基本引导器"
}
},
"25": {
"inputs": {
"noise_seed": 142213168350829
},
"class_type": "RandomNoise",
"_meta": {
"title": "随机噪波"
}
},
"26": {
"inputs": {
"guidance": 3.5,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "Flux引导"
}
},
"27": {
"inputs": {
"width": "1080",
"height": "1920",
"batch_size": "2"
},
"class_type": "EmptySD3LatentImage",
"_meta": {
"title": "空Latent图像SD3"
}
},
"30": {
"inputs": {
"max_shift": 1.1500000000000001,
"base_shift": 0.5000000000000001,
"width": 1024,
"height": 1024,
"model": [
"12",
0
]
},
"class_type": "ModelSamplingFlux",
"_meta": {
"title": "采样算法Flux"
}
},
"31": {
"inputs": {
"user_prompt": "作为一个AI提示词专家请你仿照范例根据我给出的主题生成一条符合下列要求的提示词来让CLIP模型可以更好地理解画面主体。注意你需要仿照下面的示例详细分析仅仿照写法而不仿照任何内容将用户的需求转化为详细的提示词。\\n 要求共六条,请严格遵守:\\n 1 用自然语言简单句来描述画面,请避免出现过于长的,或者格式过于复杂的句子,句子中不要出现*等特殊符号。\\n 2.用英语表达。 \\n 3.直接给出prompt内容即可不需要任何解释和说明。\\n 4. 每条prompt至少50词不超过200词。\\n 5.避免模棱两可的说法。\\n 6.描述的最开始加入“no text, no AI style”\\n 例如:\nCartoon-Style Nankai University Main Building,\nvividly depicted with rounded edges and pastel gradients, the iconic Gothic-Revival structure stands majestically. Crimson brick façade contrasts with golden-glowing arched windows, while whimsical cloud-shaped eaves drip melted clock details. A giant smiling sun hangs low, casting honey-golden rays through simplified pine trees, creating striped shadows dancing on marble stairs.\n\nTranslucent ghostly scholars from 1919 float near pillars holding glowing books, their outlines shimmering like liquid mercury. Oversized autumn leaves (stylized as maple-red origami) spiral around twin bell towers chiming visible musical notes. Puddles on the ground mirror upside-down building reflections rippling with calculus formulas.\n\nEnvironment:\nSurreal candy-pink sunset gradients blend into starry indigo sky above. Playful squirrels wearing tiny graduation caps scamper across emerald lawns textured like green velvet.",
"system_prompt": "端午节海报,传统风格",
"enable_history": false,
"max_history": 10,
"history_json": "",
"save_path": "./chat_history.json",
"api_config": [
"32",
0
]
},
"class_type": "DeepSeekChat",
"_meta": {
"title": "LLM Model Input Box"
}
},
"32": {
"inputs": {
"config_name": "DeepSeek官方Chat API",
"temperature": 1,
"max_tokens": 512,
"stream": false,
"api_key": ""
},
"class_type": "DeepSeekAPIConfig",
"_meta": {
"title": "LLM API Model Selector"
}
}
}