Compare commits

...

10 Commits

Author SHA1 Message Date
Wang Xiuqiang
9040947491 将vue代码修改为按照模板进行生成 2025-07-12 17:22:40 +08:00
Wang Xiuqiang
397b6fb1ef v 0.5.0 更新基座的README.md 2025-07-05 04:30:04 +08:00
Wang Xiuqiang
a86b258a88 vesion 0.5.0 基座版本 2025-07-05 04:24:43 +08:00
cyborvirtue
295fbb0cb4 PSD注释添加 2025-07-04 23:37:53 +08:00
cyborvirtue
50acade06b PSD实现 2025-07-04 23:30:34 +08:00
Wang Xiuqiang
20802db28a 重构run_pipeline和generate_layout
将辅助函数移动整合到utils.py当中
2025-07-03 11:47:48 +08:00
Wang Xiuqiang
6da2bda08c run_pipline本地流程可以跑通,增加前端接口 2025-07-02 22:05:43 +08:00
Wang Xiuqiang
a29e1c8db0 合并代码仓库 2025-07-01 22:54:02 +08:00
Wang Xiuqiang
90fe8dbd11 搭建 pipeline framework 2025-06-09 16:08:14 +08:00
Wang Xiuqiang
5eec48a889 合并了文案和导出psd格式的代码,为后续工作做准备 2025-06-03 20:44:12 +08:00
90 changed files with 10698 additions and 497 deletions

0
.vscode/settings.json vendored Normal file
View File

0
.vscode/tasks.json vendored Normal file
View File

217
README.md
View File

@ -1,63 +1,186 @@
# ai_service
# 基于多种 LLMs 组合以及 ComfyUI 参与的定制化用户海报生成的智能融合 ai 系统
## LLM 调用部分
## 概述
### 功能组件
使用 DeepSeek API 提供的 LLM大型语言模型功能用于生成 React 组件代码,主要服务于端午节活动海报的排版设计。当前实现的功能包括:
- **代码生成**根据提示prompt生成 React 组件代码,专注于排版位置(不包含样式描述)。
- **分层排版**:生成包含背景图层、主体图层、活动亮点和页脚的 React 组件
AI 海报生成系统集成 DeepSeek、Kimi、ComfyUI 三大 AI 模型,一键生成 Vue 组件代码和 PSD 文件。
- **文件保存**:将生成的 React 代码保存到指定路径。
**核心功能**:
### 如何调用
1. **环境准备**
- 确保已安装 Python 环境和必要依赖(`openai`、`python-dotenv`等)。
- 在项目根目录的 `.env` 文件中配置 `DEEPSEEK_API_KEY`
- 🤖 **AI 驱动**: DeepSeek 分析 + Kimi 文案 + ComfyUI 图片
- 🎨 **一键生成**: 输入需求 → Vue 代码 + PSD 文件
- 📱 **REST API**: 统一接口,支持前端集成
- 🎭 **预定义模板**: lotus.jpg, nku.png, stamp.jpg, background.png
- 🖼️ **自动合成**: 多图层 PSD 文件生成
2. **运行脚本**
- 直接运行 `generate_layout.py` 脚本:
```bash
python generate_layout.py
```
- 该脚本会自动调用 DeepSeek API 生成 React 组件代码,并将其保存到指定路径。
默认为``output/generated_code.jsx``,可以根据需要修改。
## 系统架构
```
前端 → FastAPI(8000) → AI模型集群
Vue代码 + PSD文件
```
## 快速开始
### 环境准备
## 图层叠加和PSD导出部分
### 功能组件
- **图层合成**:根据生成的布局配置,将各个图层叠加在一起,生成完整的海报图像。
- **PSD导出**将合成的海报图像保存为标准的PSD格式同时保留各个图层的独立性方便后续编辑。
### 如何调用
1. **环境准备**
```bash
conda create -n ai_service python=3.8
# 创建虚拟环境
conda create -n ai_service python=3.11
conda activate ai_service
# 安装依赖
pip install -r requirements.txt
# 配置API密钥
cp .env.example .env
# 编辑 .env 文件,添加:
# DEEPSEEK_API_KEY=your_key
# MOONSHOT_API_KEY=your_key
```
2. **运行脚本**
### 启动服务
```bash
python export_psd.py #简单生成
python export_psd_from_json.py #从json文件加载布局并生成
python PSD_test.py #在run_pipline.py中的调用方法
cd scripts
python run_pipeline.py # 选择: 2 (API服务器)
```
该脚本会自动调用图层合成模块生成完整海报图像并将其保存为标准PSD格式。
## 文案生成
### 功能组件
使用 kimi API 提供的 LLM大型语言模型功能用于生成海报文案设计。当前实现的功能包括
### 验证服务
- **标题生成**:根据海报主题生成适合的标题。
- **副标题生成**:提供与主题相关的副标题或说明文案。
- **字体与颜色建议**:为生成的文案提供适合的字体和颜色建议。
```bash
curl http://localhost:8000/health
```
### 如何调用
1. **环境准备**
- 确保已安装 Python 环境和必要依赖(`openai`、`python-dotenv`等)。
- 在项目根目录的 `.env` 文件中配置 `MOONSHOT_API_KEY`
## API 使用
2. **运行脚本**
- 直接运行 `generate_text.py` 脚本:
```bash
python generate_text.py
```
- 该脚本会自动调用 kimi API 生成适合海报主题的标题、副标题和 Logo 文案,并提供字体和颜色建议,并将其保存到指定路径。
默认为``output/poster_content.json``,可以根据需要修改。
### 生成海报
```bash
curl -X POST http://localhost:8000/api/generate-poster \
-H "Content-Type: application/json" \
-d '{"user_input": "端午节海报,传统风格"}'
```
### 下载文件
```bash
curl "http://localhost:8000/api/download/psd?session_id=SESSION_ID" -o poster.psd
curl "http://localhost:8000/api/download/vue?session_id=SESSION_ID" -o poster.vue
```
## 项目结构
```
ai_service/
├── scripts/ # 核心脚本
│ ├── run_pipeline.py # API服务器
│ ├── utils.py # 工具函数
│ ├── generate_layout.py # Vue代码生成
│ ├── generate_text.py # 文案生成
│ ├── flux_con.py # 图片生成
│ └── export_psd_from_json.py # PSD合成
├── configs/ # 配置文件
│ ├── vue_templates.yaml # Vue模板
│ └── font.yaml # 字体配置
├── outputs/ # 输出目录
└── workflows/ # ComfyUI工作流
```
## 核心模块
| 模块 | 功能 | AI 模型 |
| ------------------------- | ------------ | -------- |
| `utils.py` | 用户输入分析 | DeepSeek |
| `flux_con.py` | 图片生成 | ComfyUI |
| `generate_text.py` | 文案生成 | Kimi |
| `generate_layout.py` | Vue 代码生成 | DeepSeek |
| `export_psd_from_json.py` | PSD 合成 | - |
## 使用示例
### JavaScript 调用
```javascript
const response = await fetch("http://localhost:8000/api/generate-poster", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ user_input: "春节海报,红色背景" }),
});
const result = await response.json();
console.log("Vue代码:", result.data.vue_code);
```
### Python 调用
```python
import requests
response = requests.post('http://localhost:8000/api/generate-poster',
json={"user_input": "端午节海报,传统风格"})
result = response.json()
if result["status"] == "success":
print("生成成功!")
print("Vue代码:", result["data"]["vue_code"])
```
### 本地测试
```bash
cd scripts
python run_pipeline.py # 选择: 1 (本地测试)
# 输入: "春节海报,红色背景,现代风格"
```
## 部署
### Docker 部署
```dockerfile
FROM python:3.11
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["uvicorn", "scripts.run_pipeline:app", "--host", "0.0.0.0", "--port", "8000"]
```
### PM2 部署
```bash
pm2 start "uvicorn scripts.run_pipeline:app --host 0.0.0.0 --port 8000" --name poster-api
```
### Nginx 反向代理
```nginx
server {
listen 80;
location / {
proxy_pass http://localhost:8000;
}
}
```
## 故障排查
### 常见问题
```bash
# 检查API密钥
echo $DEEPSEEK_API_KEY
# 测试ComfyUI连接
curl http://101.201.50.90:8188/system_stats
# 检查端口占用
netstat -tulpn | grep 8000
```
## 更新日志
### v 0.5.0(2025-07-05)
跑通全流程

View File

View File

@ -1,83 +1,41 @@
# 颜色常量
NAMING_COLORS:
NANKAI_PURPLE: "#7E0C6E"
LOGO_WHITE: "#FFFFFF"
DARK_TEXT_ON_LIGHT_BG: "#000000" # 示例深色文字
LIGHT_TEXT_ON_DARK_BG: "#f4efd9" # 示例浅色文字
# 可用字体列表
# name: 字体文件在系统中的名称或前端能识别的名称
# tags: 用于规则匹配的标签
default_logo_text: ""
available_fonts:
- name: "FZLanTingHei-ExtraBold-GB" # 方正兰亭特黑简体 (假设这是实际的font-family名)
displayName: "方正兰亭特黑简体"
tags: ["现代", "力量感", "标题", "正式", "无衬线", "醒目"]
- name: "Microsoft YaHei"
displayName: "微软雅黑"
tags: ["现代", "清晰"]
roles: ["title", "subtitle", "content"]
- name: "SimHei"
displayName: "黑体"
tags: ["通用", "标准"]
roles: ["title", "subtitle", "content"]
- name: "FZLanTingHei-ExtraBold-GB"
displayName: "方正兰亭黑-特粗"
tags: ["粗体", "标题"]
roles: ["title"]
- name: "Source Han Sans CN"
displayName: "思源黑体"
tags: ["现代", "国际化"]
roles: ["title", "subtitle", "content"]
- name: "Adobe Song Std L" # adobe宋体 (L 通常表示 Light weight)
displayName: "Adobe 宋体 Std L"
tags: ["传统", "正文", "经典", "宋体"]
roles: ["subtitle", "content"]
NAMING_COLORS:
primary: "#1976D2"
secondary: "#424242"
accent: "#FF5722"
background_light: "#FFFFFF"
background_dark: "#212121"
text_light: "#000000"
text_dark: "#FFFFFF"
- name: "SimHei" # 黑体 简
displayName: "黑体 (简体)"
tags: ["通用", "简约", "正文", "无衬线", "清晰"]
roles: ["title", "subtitle", "content"] # 黑体用途广泛
- name: "Hiragino Sans GB W3" # 冬青黑体 (W3 通常表示字重)
displayName: "冬青黑体 W3"
tags: ["现代", "清晰", "正文", "优雅", "无衬线"]
roles: ["subtitle", "content"]
# 核心样式规则
# 主题 -> 图层ID -> 样式定义
STYLE_RULES:
"世界读书日": # 对应海报主题
"layer6_title": # 对应文字图层6大标题
font_prefs: # 字体选择偏好
- name: "ImpactfulModernSans" # 首选这个名字的字体
- tags: ["title", "bold", "modern_sans"] # 如果首选找不到,则找带这些标签的
font_size_category: "largest"
color_on_light_bg: DARK_TEXT_ON_LIGHT_BG # 使用上面定义的颜色名
color_on_dark_bg: LIGHT_TEXT_ON_DARK_BG
position_hint: "图片上方、居中、不遮挡图像"
"layer7_subtitle": # 对应文字图层7小字/文案
font_prefs:
- name: "ReadableBodySans"
- tags: ["body", "readable_sans"]
font_size_category: "small_below_title"
color_on_light_bg: DARK_TEXT_ON_LIGHT_BG
color_on_dark_bg: LIGHT_TEXT_ON_DARK_BG
position_hint: "标题下方"
modern:
primary_font: "Microsoft YaHei"
secondary_font: "Source Han Sans CN"
traditional:
primary_font: "SimHei"
secondary_font: "Microsoft YaHei"
"南开校庆":
"layer6_title":
font_prefs:
- name: "南开官方标准黑体"
- tags: ["formal", "title"]
font_size_category: "largest"
color_on_light_bg: NANKAI_PURPLE
color_on_dark_bg: LOGO_WHITE
position_hint: "图片上方、居中、庄重"
"通用默认": # 如果主题未匹配,则使用这里的规则
"default_title": # 给一个默认的标题图层ID
font_prefs:
- tags: ["title", "bold"]
font_size_category: "largest"
color_on_light_bg: "#1A1A1A"
color_on_dark_bg: "#E5E5E5"
"default_body":
font_prefs:
- tags: ["body", "readable_sans"]
font_size_category: "normal"
color_on_light_bg: "#000000"
color_on_dark_bg: "#ffffff"
# Logo的颜色规则 (独立于普通文字图层,像是对图像素材的选择)
LOGO_RULES:
"layer5_nankai_logo":
description: "南开大学官方logo位于四角预留空隙"
color_on_light_bg: NANKAI_PURPLE
color_on_dark_bg: LOGO_WHITE
default_position: "bottom"
default_size: "medium"
fallback_text: "活动主办方"

959
configs/vue_templates.yaml Normal file
View File

@ -0,0 +1,959 @@
# Vue模板配置文件
# 为不同海报类型预定义Vue组件模板
vue_templates:
# 插画风模板
illustration:
name: "插画风海报"
description: "4层结构插画底图+文字图层"
layers:
- name: "插画底图"
type: "background"
description: "AI生成的通用建筑插图彩色插画色调和谐"
- name: "主标题"
type: "text"
content: "见微知著记录南开"
description: "最大号字体,放置在不遮挡主体的相对空白处"
- name: "南开大学logo"
type: "logo"
description: "南开大学标识"
- name: "机构名称"
type: "text"
content: "南开大学融媒体中心"
description: "底部居中放置"
template: |
<template>
<div class="poster-container illustration-theme" :style="containerStyle">
<!-- 插画底图层 -->
<div class="background-layer">
<img :src="backgroundImage" alt="插画背景" class="background-image" />
</div>
<!-- 内容层 -->
<div class="content-layer">
<!-- 主标题 -->
<div class="main-title-section">
<h1 class="primary-title">{{ mainTitle }}</h1>
</div>
<!-- 南开logo -->
<div class="logo-section">
<img src="../outputs/nankai.png" alt="南开大学" class="nankai-logo" />
</div>
<!-- 机构名称 -->
<div class="organization-section">
<h2 class="organization-name">{{ organizationName }}</h2>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'IllustrationPoster',
data() {
return {
mainTitle: '见微知著记录南开',
organizationName: '南开大学融媒体中心',
backgroundImage: '../outputs/background.png'
}
},
computed: {
containerStyle() {
return {
width: '1080px',
height: '1920px',
position: 'relative',
overflow: 'hidden',
background: 'linear-gradient(135deg, #f5f7fa, #c3cfe2)'
}
}
}
}
</script>
<style scoped>
.poster-container {
margin: 0 auto;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
}
.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.9;
}
.content-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.main-title-section {
position: absolute;
top: 15%;
left: 8%;
width: 40%;
}
.primary-title {
font-size: 72px;
font-weight: bold;
color: #2c3e50;
text-shadow: 2px 2px 4px rgba(255, 255, 255, 0.8);
line-height: 1.2;
font-family: 'SimHei', 'Microsoft YaHei', sans-serif;
}
.logo-section {
position: absolute;
top: 45%;
right: 10%;
width: 200px;
height: 200px;
}
.nankai-logo {
width: 100%;
height: 100%;
object-fit: contain;
filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.2));
}
.organization-section {
position: absolute;
bottom: 8%;
left: 50%;
transform: translateX(-50%);
text-align: center;
}
.organization-name {
font-size: 36px;
color: #34495e;
font-weight: 500;
font-family: 'Microsoft YaHei', sans-serif;
text-shadow: 1px 1px 2px rgba(255, 255, 255, 0.8);
}
</style>
# 中秋节模板
festival:
name: "中秋节海报"
description: "8层结构背景+遮罩+装饰+logo+多文字层"
layers:
- name: "背景图层"
type: "background"
description: "AI生成节日插画"
- name: "纯色遮罩"
type: "overlay"
description: "插画主色调遮罩"
- name: "小插图背景"
type: "decoration"
description: "节日元素插图"
- name: "南开logo"
type: "logo"
- name: "单位名称"
type: "text"
content: "南开大学"
- name: "节日名称"
type: "text"
content: "中秋节"
- name: "目的主题"
type: "text"
content: "月圆人团圆"
- name: "日期元素"
type: "text"
content: "2025年10月6日"
template: |
<template>
<div class="poster-container festival-theme" :style="containerStyle">
<!-- 背景图层 -->
<div class="background-layer">
<img :src="backgroundImage" alt="节日背景" class="background-image" />
</div>
<!-- 纯色遮罩层 -->
<div class="color-overlay" :style="overlayStyle"></div>
<!-- 装饰元素层 -->
<div class="decoration-layer">
<img :src="decorationImage" alt="节日装饰" class="decoration-image" />
</div>
<!-- 内容层 -->
<div class="content-layer">
<!-- 南开logo -->
<div class="logo-section">
<img src="../outputs/nankai.png" alt="南开大学" class="nankai-logo" />
</div>
<!-- 单位名称 -->
<div class="university-section">
<h1 class="university-name">{{ universityName }}</h1>
</div>
<!-- 节日名称 -->
<div class="festival-section">
<h2 class="festival-name">{{ festivalName }}</h2>
</div>
<!-- 目的主题 -->
<div class="theme-section">
<div class="theme-background"></div>
<h3 class="theme-text">{{ themeText }}</h3>
</div>
<!-- 日期元素 -->
<div class="date-section">
<div class="date-background"></div>
<p class="date-text">{{ dateText }}</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'FestivalPoster',
data() {
return {
universityName: '南开大学',
festivalName: '中秋节',
themeText: '月圆人团圆',
dateText: '2025年10月6日',
backgroundImage: '../outputs/background.png',
decorationImage: '../outputs/lotus.jpg',
mainColor: '#d4a574' // 中秋主色调
}
},
computed: {
containerStyle() {
return {
width: '1080px',
height: '1920px',
position: 'relative',
overflow: 'hidden'
}
},
overlayStyle() {
return {
backgroundColor: this.mainColor,
opacity: 0.3
}
}
}
}
</script>
<style scoped>
.poster-container {
margin: 0 auto;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}
.background-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.background-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.color-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.decoration-layer {
position: absolute;
top: 60%;
right: 5%;
width: 300px;
height: 300px;
z-index: 3;
opacity: 0.6;
}
.decoration-image {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
filter: blur(1px);
}
.content-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 4;
}
.logo-section {
position: absolute;
top: 8%;
left: 8%;
width: 150px;
height: 150px;
}
.nankai-logo {
width: 100%;
height: 100%;
object-fit: contain;
filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.3));
}
.university-section {
position: absolute;
top: 25%;
left: 50%;
transform: translateX(-50%);
text-align: center;
}
.university-name {
font-size: 48px;
color: #2c3e50;
font-weight: bold;
font-family: 'SimHei', 'Microsoft YaHei', sans-serif;
text-shadow: 2px 2px 4px rgba(255, 255, 255, 0.8);
}
.festival-section {
position: absolute;
top: 35%;
left: 50%;
transform: translateX(-50%);
text-align: center;
}
.festival-name {
font-size: 96px;
color: #d4a574;
font-weight: bold;
font-family: 'SimSun', 'KaiTi', serif;
text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
}
.theme-section {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%);
text-align: center;
position: relative;
}
.theme-background {
position: absolute;
top: -20px;
left: -40px;
width: calc(100% + 80px);
height: calc(100% + 40px);
background: linear-gradient(135deg, rgba(212, 165, 116, 0.2), rgba(212, 165, 116, 0.1));
border-radius: 20px;
z-index: -1;
}
.theme-text {
font-size: 56px;
color: #8b4513;
font-weight: 500;
font-family: 'KaiTi', serif;
text-shadow: 1px 1px 3px rgba(255, 255, 255, 0.6);
}
.date-section {
position: absolute;
bottom: 12%;
left: 50%;
transform: translateX(-50%);
text-align: center;
position: relative;
}
.date-background {
position: absolute;
top: -15px;
left: -30px;
width: calc(100% + 60px);
height: calc(100% + 30px);
background: linear-gradient(135deg, rgba(212, 165, 116, 0.3), rgba(212, 165, 116, 0.2));
border-radius: 15px;
z-index: -1;
}
.date-text {
font-size: 32px;
color: #654321;
font-weight: 400;
font-family: 'Microsoft YaHei', sans-serif;
margin: 0;
}
</style>
# 通用模板保留原有的lotus模板作为备用
lotus.jpg:
theme: "荷花主题"
style: "传统优雅"
template: |
<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('{{ title_content }}')
const subtitle = ref('{{ subtitle_content }}')
const logoText = ref('{{ logo_content }}')
</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>
nku.png:
theme: "南开大学"
style: "学术正式"
template: |
<template>
<div class="poster-container nku-theme">
<div class="background-layer">
<img src="../outputs/background.png" alt="背景" class="background-image" />
</div>
<div class="content-layer">
<div class="header-section">
<img src="../outputs/nku.png" alt="南开大学logo" class="nku-logo" />
</div>
<div class="title-section">
<h1 class="main-title nku-title">{{ title }}</h1>
<h2 class="subtitle nku-subtitle">{{ subtitle }}</h2>
</div>
<div class="main-content nku-content">
<div class="academic-decoration">
<div class="knowledge-symbol"></div>
</div>
</div>
<div class="footer-section">
<div class="university-info">
<span class="university-name">{{ logoText }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const title = ref('{{ title_content }}')
const subtitle = ref('{{ subtitle_content }}')
const logoText = ref('{{ logo_content }}')
</script>
<style scoped>
.poster-container {
width: 1080px;
height: 1920px;
position: relative;
overflow: hidden;
background: linear-gradient(180deg, #7E0C6E, #4a0845);
}
.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.3;
}
.content-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.header-section {
position: absolute;
top: 8%;
left: 50%;
transform: translateX(-50%);
}
.nku-logo {
width: 120px;
height: auto;
}
.title-section {
position: absolute;
top: 25%;
left: 50%;
transform: translateX(-50%);
text-align: center;
width: 85%;
}
.nku-title {
font-size: 58px;
font-weight: bold;
color: #ffffff;
text-shadow: 3px 3px 6px rgba(0,0,0,0.5);
margin-bottom: 25px;
font-family: 'Microsoft YaHei', sans-serif;
}
.nku-subtitle {
font-size: 28px;
color: #f0f0f0;
margin-bottom: 40px;
line-height: 1.4;
}
.nku-content {
position: absolute;
top: 55%;
left: 50%;
transform: translate(-50%, -50%);
width: 80%;
}
.knowledge-symbol {
width: 150px;
height: 150px;
background: rgba(255,255,255,0.1);
border: 3px solid rgba(255,255,255,0.3);
border-radius: 50%;
margin: 0 auto;
position: relative;
}
.knowledge-symbol::before {
content: '知';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 48px;
color: #ffffff;
font-family: 'SimSun', serif;
}
.footer-section {
position: absolute;
bottom: 8%;
left: 50%;
transform: translateX(-50%);
}
.university-name {
font-size: 22px;
color: #ffffff;
font-weight: 500;
letter-spacing: 2px;
}
</style>
stamp.jpg:
theme: "印章装饰"
style: "传统文化"
template: |
<template>
<div class="poster-container stamp-theme">
<div class="background-layer">
<img src="../outputs/background.png" alt="背景" class="background-image" />
</div>
<div class="content-layer">
<div class="title-section">
<h1 class="main-title stamp-title">{{ title }}</h1>
<h2 class="subtitle stamp-subtitle">{{ subtitle }}</h2>
</div>
<div class="main-content stamp-content">
<div class="stamp-decoration">
<img src="../outputs/stamp.jpg" alt="印章" class="stamp-image" />
</div>
</div>
<div class="footer-section">
<div class="traditional-footer">
<span class="logo-text">{{ logoText }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const title = ref('{{ title_content }}')
const subtitle = ref('{{ subtitle_content }}')
const logoText = ref('{{ logo_content }}')
</script>
<style scoped>
.poster-container {
width: 1080px;
height: 1920px;
position: relative;
overflow: hidden;
background: linear-gradient(45deg, #faf0e6, #f5e6d3);
}
.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.4;
}
.content-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.title-section {
position: absolute;
top: 18%;
left: 50%;
transform: translateX(-50%);
text-align: center;
width: 85%;
}
.stamp-title {
font-size: 56px;
font-weight: bold;
color: #8B4513;
text-shadow: 2px 2px 4px rgba(0,0,0,0.2);
margin-bottom: 20px;
font-family: 'SimSun', serif;
}
.stamp-subtitle {
font-size: 26px;
color: #A0522D;
margin-bottom: 40px;
line-height: 1.5;
font-family: 'KaiTi', cursive;
}
.stamp-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 60%;
text-align: center;
}
.stamp-image {
width: 200px;
height: 200px;
object-fit: contain;
filter: drop-shadow(4px 4px 8px rgba(0,0,0,0.3));
}
.footer-section {
position: absolute;
bottom: 12%;
left: 50%;
transform: translateX(-50%);
}
.logo-text {
font-size: 20px;
color: #8B4513;
font-weight: 500;
font-family: 'SimSun', serif;
}
</style>
background.png:
theme: "通用背景"
style: "简约现代"
template: |
<template>
<div class="poster-container modern-theme">
<div class="background-layer">
<img src="../outputs/background.png" alt="背景" class="background-image" />
</div>
<div class="content-layer">
<div class="title-section">
<h1 class="main-title modern-title">{{ title }}</h1>
<h2 class="subtitle modern-subtitle">{{ subtitle }}</h2>
</div>
<div class="main-content modern-content">
<div class="modern-decoration">
<div class="geometric-shape"></div>
</div>
</div>
<div class="footer-section">
<div class="modern-footer">
<span class="logo-text">{{ logoText }}</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
const title = ref('{{ title_content }}')
const subtitle = ref('{{ subtitle_content }}')
const logoText = ref('{{ logo_content }}')
</script>
<style scoped>
.poster-container {
width: 1080px;
height: 1920px;
position: relative;
overflow: hidden;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.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.7;
}
.content-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.title-section {
position: absolute;
top: 22%;
left: 50%;
transform: translateX(-50%);
text-align: center;
width: 90%;
}
.modern-title {
font-size: 60px;
font-weight: 700;
color: #ffffff;
text-shadow: 2px 2px 8px rgba(0,0,0,0.4);
margin-bottom: 25px;
font-family: 'Microsoft YaHei', sans-serif;
}
.modern-subtitle {
font-size: 30px;
color: #f0f0f0;
margin-bottom: 40px;
line-height: 1.4;
font-weight: 300;
}
.modern-content {
position: absolute;
top: 55%;
left: 50%;
transform: translate(-50%, -50%);
width: 70%;
}
.geometric-shape {
width: 180px;
height: 180px;
background: rgba(255,255,255,0.1);
border: 2px solid rgba(255,255,255,0.3);
transform: rotate(45deg);
margin: 0 auto;
backdrop-filter: blur(10px);
}
.footer-section {
position: absolute;
bottom: 10%;
left: 50%;
transform: translateX(-50%);
}
.logo-text {
font-size: 24px;
color: #ffffff;
font-weight: 400;
letter-spacing: 1px;
}
</style>

Binary file not shown.

126
docs/接口文档.md Normal file
View File

@ -0,0 +1,126 @@
# AI海报生成系统 API文档
## 系统架构
```
前端 → FastAPI(8000) → ComfyUI(101.201.50.90:8188)
Vue代码 + PSD文件
```
## API端点
### 1. 健康检查
**GET** `/health`
```json
{
"status": "healthy",
"timestamp": "2025-01-02T20:30:00"
}
```
### 2. 生成海报
**POST** `/api/generate-poster`
**请求**:
```json
{
"user_input": "端午节海报,传统风格",
"session_id": "可选"
}
```
**响应**:
```json
{
"status": "success",
"message": "海报生成完成",
"data": {
"vue_code": "完整Vue组件代码",
"suggestions": {
"layer5_logo_content": {
"text": "主办方",
"color": "#000000"
},
"layer6_title_content": {
"content": "端午安康",
"font_name": "SimHei",
"color": "#7E0C6E"
},
"layer7_subtitle_content": {
"content": "粽叶飘香,龙舟竞渡",
"font_name": "Microsoft YaHei",
"color": "#000000"
}
},
"analysis_result": {
"main_theme": "端午节祝福",
"width": 1080,
"height": 1920,
"keywords": ["端午节", "传统", "荷花"]
},
"file_size_mb": 5.93,
"generated_images": 2
},
"session_id": "会话ID"
}
```
### 3. 文件下载
**GET** `/api/download/{file_type}?session_id={session_id}`
参数: `file_type` = `vue` | `psd` | `json`
### 4. 会话状态
**GET** `/api/status/{session_id}`
```json
{
"session_id": "会话ID",
"files": {
"vue_file": true,
"psd_file": true,
"content_file": true
},
"folder": "会话文件夹路径"
}
```
## 使用示例
### JavaScript
```javascript
const response = await fetch('http://localhost:8000/api/generate-poster', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_input: "春节海报,红色背景" })
});
const result = await response.json();
if (result.status === 'success') {
// 下载文件
const url = `http://localhost:8000/api/download/psd?session_id=${result.session_id}`;
window.open(url);
}
```
### Python
```python
import requests
response = requests.post('http://localhost:8000/api/generate-poster',
json={"user_input": "端午节海报,传统风格"})
result = response.json()
if result["status"] == "success":
session_id = result["session_id"]
# 下载PSD文件
psd_url = f"http://localhost:8000/api/download/psd?session_id={session_id}"
psd_response = requests.get(psd_url)
with open("poster.psd", "wb") as f:
f.write(psd_response.content)
```

0
docs/问题.md Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
outputs/background.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

BIN
outputs/background.zip Normal file

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.

Binary file not shown.

BIN
outputs/final_poster.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

BIN
outputs/final_poster.psd Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

View File

@ -1,47 +0,0 @@
```jsx
import React from 'react';
const DragonBoatFestivalPoster = () => {
return (
<div style={{ position: 'relative', width: '1080px', height: '1920px' }}>
{/* 背景图层 */}
<div style={{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }}></div>
{/* 主体图层 */}
<div style={{ position: 'absolute', top: '25%', left: '50%', transform: 'translate(-50%, -50%)', textAlign: 'center' }}>
<h1></h1>
<h2></h2>
</div>
{/* 活动亮点 */}
<div style={{ position: 'absolute', bottom: '25%', left: '50%', transform: 'translateX(-50%)', width: '80%' }}>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '20px' }}>
<div style={{ textAlign: 'center' }}>
<div></div>
<h3></h3>
<p></p>
</div>
<div style={{ textAlign: 'center' }}>
<div></div>
<h3></h3>
<p></p>
</div>
<div style={{ textAlign: 'center' }}>
<div></div>
<h3></h3>
<p></p>
</div>
</div>
</div>
{/* 页脚 */}
<div style={{ position: 'absolute', bottom: '5%', left: '50%', transform: 'translateX(-50%)', textAlign: 'center' }}>
<p></p>
<div></div>
</div>
</div>
);
};
export default DragonBoatFestivalPoster;
```

240
outputs/generated_code.vue Normal file
View File

@ -0,0 +1,240 @@
<template>
<div class="poster-container festival-theme" :style="containerStyle">
<!-- 背景图层 -->
<div class="background-layer">
<img :src="backgroundImage" alt="节日背景" class="background-image" />
</div>
<!-- 纯色遮罩层 -->
<div class="color-overlay" :style="overlayStyle"></div>
<!-- 装饰元素层 -->
<div class="decoration-layer">
<img :src="decorationImage" alt="节日装饰" class="decoration-image" />
</div>
<!-- 内容层 -->
<div class="content-layer">
<!-- 南开logo -->
<div class="logo-section">
<img src="../outputs/nankai.png" alt="南开大学" class="nankai-logo" />
</div>
<!-- 单位名称 -->
<div class="university-section">
<h1 class="university-name">{{ universityName }}</h1>
</div>
<!-- 节日名称 -->
<div class="festival-section">
<h2 class="festival-name">{{ festivalName }}</h2>
</div>
<!-- 目的主题 -->
<div class="theme-section">
<div class="theme-background"></div>
<h3 class="theme-text">{{ themeText }}</h3>
</div>
<!-- 日期元素 -->
<div class="date-section">
<div class="date-background"></div>
<p class="date-text">{{ dateText }}</p>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'FestivalPoster',
data() {
return {
universityName: '南开大学',
festivalName: '端午节',
themeText: '粽叶飘香,龙舟竞渡',
dateText: '2025年07月12日',
backgroundImage: '../outputs/background.png',
decorationImage: '../outputs/lotus.jpg',
mainColor: '#d4a574' //
}
},
computed: {
containerStyle() {
return {
width: '1080px',
height: '1920px',
position: 'relative',
overflow: 'hidden'
}
},
overlayStyle() {
return {
backgroundColor: this.mainColor,
opacity: 0.3
}
}
}
}
</script>
<style scoped>
.poster-container {
margin: 0 auto;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
}
.background-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 1;
}
.background-image {
width: 100%;
height: 100%;
object-fit: cover;
}
.color-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 2;
}
.decoration-layer {
position: absolute;
top: 60%;
right: 5%;
width: 300px;
height: 300px;
z-index: 3;
opacity: 0.6;
}
.decoration-image {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 50%;
filter: blur(1px);
}
.content-layer {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 4;
}
.logo-section {
position: absolute;
top: 8%;
left: 8%;
width: 150px;
height: 150px;
}
.nankai-logo {
width: 100%;
height: 100%;
object-fit: contain;
filter: drop-shadow(0 2px 8px rgba(0, 0, 0, 0.3));
}
.university-section {
position: absolute;
top: 25%;
left: 50%;
transform: translateX(-50%);
text-align: center;
}
.university-name {
font-size: 48px;
color: #2c3e50;
font-weight: bold;
font-family: 'SimHei', 'Microsoft YaHei', sans-serif;
text-shadow: 2px 2px 4px rgba(255, 255, 255, 0.8);
}
.festival-section {
position: absolute;
top: 35%;
left: 50%;
transform: translateX(-50%);
text-align: center;
}
.festival-name {
font-size: 96px;
color: #d4a574;
font-weight: bold;
font-family: 'SimSun', 'KaiTi', serif;
text-shadow: 3px 3px 6px rgba(0, 0, 0, 0.3);
}
.theme-section {
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%);
text-align: center;
position: relative;
}
.theme-background {
position: absolute;
top: -20px;
left: -40px;
width: calc(100% + 80px);
height: calc(100% + 40px);
background: linear-gradient(135deg, rgba(212, 165, 116, 0.2), rgba(212, 165, 116, 0.1));
border-radius: 20px;
z-index: -1;
}
.theme-text {
font-size: 56px;
color: #8b4513;
font-weight: 500;
font-family: 'KaiTi', serif;
text-shadow: 1px 1px 3px rgba(255, 255, 255, 0.6);
}
.date-section {
position: absolute;
bottom: 12%;
left: 50%;
transform: translateX(-50%);
text-align: center;
position: relative;
}
.date-background {
position: absolute;
top: -15px;
left: -30px;
width: calc(100% + 60px);
height: calc(100% + 30px);
background: linear-gradient(135deg, rgba(212, 165, 116, 0.3), rgba(212, 165, 116, 0.2));
border-radius: 15px;
z-index: -1;
}
.date-text {
font-size: 32px;
color: #654321;
font-weight: 400;
font-family: 'Microsoft YaHei', sans-serif;
margin: 0;
}
</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
}
}
}
}

BIN
outputs/lotus.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

BIN
outputs/nankai.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
outputs/nku.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

@ -4,13 +4,13 @@
"color": "#000000"
},
"layer6_title_content": {
"content": "世界读书日",
"font_name": "FZLanTingHei-ExtraBold-GB",
"content": "端午节",
"font_name": "SimHei",
"color": "#000000"
},
"layer7_subtitle_content": {
"content": "阅古今中外,启智慧之门",
"font_name": "Adobe Song Std L",
"color": "#4F4F4F"
"content": "粽叶飘香,龙舟竞渡",
"font_name": "Microsoft YaHei",
"color": "#7E0C6E"
}
}

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>

3
outputs/prompts.yaml Normal file
View File

@ -0,0 +1,3 @@
description: 'Generated prompt based on user input: 端午节海报,包含背景、活动亮点和图标'
generated_at: 02:50 PM HKT on Monday, June 09, 2025
user_prompt: 端午节海报,包含背景、活动亮点和图标

BIN
outputs/stamp.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

37
outputs/temp_config.yaml Normal file
View File

@ -0,0 +1,37 @@
available_fonts:
- displayName: 微软雅黑
name: Microsoft YaHei
roles:
- title
- subtitle
- content
tags:
- 现代
- 清晰
- displayName: 黑体
name: SimHei
roles:
- title
- subtitle
- content
tags:
- 通用
- 标准
default_logo_text: ''
vue_templates:
background.png:
style: 简约现代
template_name: background_template
theme: 通用背景
lotus.jpg:
style: 传统优雅
template_name: lotus_template
theme: 荷花主题
nku.png:
style: 学术正式
template_name: nku_template
theme: 南开大学
stamp.jpg:
style: 传统文化
template_name: stamp_template
theme: 印章装饰

31
outputs/temp_prompts.yaml Normal file
View File

@ -0,0 +1,31 @@
LOGO_RULES:
default_position: bottom
fallback_text: 活动主办方
NAMING_COLORS:
accent: '#FF5722'
primary: '#1976D2'
secondary: '#424242'
STYLE_RULES:
modern:
primary_font: Microsoft YaHei
secondary_font: SimHei
available_fonts:
- displayName: 微软雅黑
name: Microsoft YaHei
roles:
- title
- subtitle
- content
tags:
- 现代
- 清晰
- displayName: 黑体
name: SimHei
roles:
- title
- subtitle
- content
tags:
- 通用
- 标准
default_logo_text: ''

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

58
requirements.txt Normal file
View File

@ -0,0 +1,58 @@
# LLM和API相关
fastapi==0.104.1
uvicorn==0.24.0
python-dotenv==1.0.0
requests==2.31.0
httpx==0.25.1
pydantic==2.4.2
# 图像处理
Pillow==10.1.0
numpy==1.26.2
opencv-python==4.8.1.78
photoshop-python-api==0.19.0 # PSD文件处理
# 深度学习和AI
torch==2.1.1
transformers==4.35.2
diffusers==0.24.0
accelerate==0.24.1
# 工具和辅助库
python-multipart==0.0.6
pyyaml==6.0.1
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
pymongo==4.6.0
redis==5.0.1
# 测试和开发工具
pytest==7.4.3
black==23.11.0
isort==5.12.0
mypy==1.7.0
# Web服务和异步
aiohttp==3.9.0
websockets==12.0
gunicorn==21.2.0
# 文件处理
python-magic==0.4.27
python-multipart==0.0.6
aiofiles==23.2.1
# 监控和日志
prometheus-client==0.19.0
sentry-sdk==1.32.0

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'
)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

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

@ -1,197 +1,637 @@
"""
测试文件从JSON配置文件创建PSD文件
支持通过配置文件精确控制图层位置和属性
"""
* @file export_psd_from_json.py
* @brief PSD导出模块基于Vue模板配置生成PSD文件
* 支持从Vue模板解析图层信息文本样式和位置信息
*
* @author 徐海潆 (2212180@mail.nankai.edu.cn)
* @date 2025.7.4
* @version v2.0.0
*
* @details
* 本文件主要实现
* - Vue模板配置文件解析和图层信息提取
* - CSS样式解析和透明度字体颜色等属性提取
* - 图片和文本图层的创建和位置计算
* - PSD文件生成和图层叠加处理
* - 字体加载和文本渲染功能
* - 图像缩放对齐和透明度处理
*
* @note
* - 支持多种图片格式和字体文件加载
* - 自动处理图层z-index排序和透明度设置
* - 提供图片路径自动查找功能
* - 生成预览图和缩略图便于查看效果
* - 兼容PIL和psd-tools库进行图像处理
*
* @usage
* # 从Vue模板配置创建PSD文件
* create_psd_from_vue_config(
* vue_templates_path='configs/vue_templates.yaml',
* output_path='outputs/design.psd',
* template_name='nku.png',
* content_data={'title_content': '标题', 'subtitle_content': '副标题'}
* )
*
* # 从图片列表创建简单PSD文件
* create_psd_from_images(
* image_paths=['image1.jpg', 'image2.png'],
* output_path='outputs/simple.psd'
* )
*
* # 快速运行
* python export_psd_from_json.py
* # 需完善
* 字体加载需要接口
* @copyright
* (c) 2025 砚生项目组
*/
"""
import json
import yaml
import re
from psd_tools import PSDImage
from PIL import Image
from PIL import Image, ImageDraw, ImageFont
from psd_tools.constants import Compression
import os
from typing import List, Tuple
from typing import List, Tuple, Optional, Dict, Any
# 导入PixelLayer类用于从PIL图像创建图层
from psd_tools.api.layers import PixelLayer
def create_psd_from_config(config_file: str) -> None:
"""
从JSON配置文件创建PSD文件
参数:
config_file: JSON配置文件路径
"""
# 确保配置文件存在
if not os.path.exists(config_file):
raise FileNotFoundError(f"配置文件不存在: {config_file}")
# 读取JSON配置文件
with open(config_file, 'r', encoding='utf-8') as f:
config = json.load(f)
try:
# 1. 从配置创建PSD文件
canvas = config['canvas']
psd = PSDImage.new(
canvas['mode'],
(canvas['width'], canvas['height'])
)
# 2. 根据配置添加图层
for layer_config in config['layers']:
# 打开图片
image = Image.open(layer_config['image_path'])
# 获取位置信息
position = layer_config['position']
left = position['left']
top = position['top']
# 创建图层
layer = PixelLayer.frompil(
image,
psd,
layer_config['name'],
top,
left,
Compression.RLE
)
# 设置图层可见性
layer.visible = layer_config.get('visible', True)
psd.append(layer)
# 3. 确保所有图层都是可见的
for layer in psd:
if not layer.visible:
print(f"图层 {layer.name} 不可见,正在设置为可见")
layer.visible = True
# 4. 生成合成图像并更新PSD文件的图像数据
composite_image = psd.composite(force=True)
psd._record.image_data.set_data(
[channel.tobytes() for channel in composite_image.split()],
psd._record.header
)
# 5. 保存PSD文件
output_config = config['output']
output_path = output_config['path']
# 确保输出目录存在
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
psd.save(output_path)
print(f"PSD文件已成功创建保存在: {output_path}")
# 6. 生成预览(如果配置中启用)
if output_config.get('generate_preview', False):
preview_path = os.path.splitext(output_path)[0] + "_预览.png"
composite_image.save(preview_path)
print(f"预览已保存在: {preview_path}")
# 7. 验证PSD文件结构
saved_psd = PSDImage.open(output_path)
print(f"PSD文件信息: {saved_psd}")
print(f"图层数量: {len(saved_psd)}")
for i, layer in enumerate(saved_psd):
print(f"图层 {i}: {layer.name}, 位置: ({layer.left}, {layer.top}), 大小: {layer.width}x{layer.height}")
except Exception as e:
print(f"创建PSD文件时出错: {e}")
def create_psd_from_images(
image_paths: List[str],
output_path: str,
canvas_size: Tuple[int, int] = (1000, 800),
mode: str = 'RGB'
) -> None:
"""
从图片列表创建PSD文件将图片从底到顶堆叠保留原有功能
参数:
image_paths: 图片路径列表
output_path: 保存PSD文件的路径
canvas_size: PSD画布大小格式为(宽度, 高度)
mode: PSD文件的颜色模式
"""
# 确保输出目录存在
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
try:
# 1. 创建一个新的PSD文件
psd = PSDImage.new(mode, canvas_size)
# 2. 打开并添加每个图片作为图层
for i, img_path in enumerate(image_paths):
# 打开图片
image = Image.open(img_path)
# 计算居中位置
left = (canvas_size[0] - image.width) // 2
top = (canvas_size[1] - image.height) // 2
# 根据图片文件名创建图层名称
layer_name = f"layer {i+1} - {os.path.basename(img_path)}"
# 创建并添加图层
layer = PixelLayer.frompil(image, psd, layer_name, top, left, Compression.RLE)
# 确保图层可见
layer.visible = True
psd.append(layer)
# 确保所有图层都是可见的
for layer in psd:
if not layer.visible:
print(f"图层 {layer.name} 不可见,正在设置为可见")
layer.visible = True
# 生成合成图像
composite_image = psd.composite(force=True)
# 更新PSD文件的图像数据
psd._record.image_data.set_data([channel.tobytes() for channel in composite_image.split()], psd._record.header)
# 3. 保存PSD文件
psd.save(output_path)
print(f"PSD文件已成功创建保存在: {output_path}")
# 4. 生成并保存预览
preview_path = os.path.splitext(output_path)[0] + "_预览.png"
composite_image.save(preview_path)
print(f"预览已保存在: {preview_path}")
# 5. 验证PSD文件结构
saved_psd = PSDImage.open(output_path)
print(f"PSD文件信息: {saved_psd}")
print(f"图层数量: {len(saved_psd)}")
for i, layer in enumerate(saved_psd):
print(f"图层 {i}: {layer.name}, 位置: ({layer.left}, {layer.top}), 大小: {layer.width}x{layer.height}")
except Exception as e:
print(f"创建PSD文件时出错: {e}")
if __name__ == "__main__":
# 方法1: 使用JSON配置文件
print("=== 使用JSON配置文件创建PSD ===")
create_psd_from_config('../configs/example.json')
print("\n" + "="*50 + "\n")
# 方法2: 使用原有的图片列表方法(保留兼容性)
print("=== 使用图片列表创建PSD居中布局===")
image_list = [
'../images/background.jpg', # 底层图片
'../images/nankai.jpg', # 中间图片
'../images/aaai.png', # 顶层图片
# 可以根据需要添加更多图片
]
create_psd_from_images(
image_paths=image_list,
output_path='../outputs/combined_output.psd'
)
# 导入PixelLayer类
from psd_tools.api.layers import PixelLayer
def parse_vue_template_config(vue_templates_path: str, font_config_path: str = None) -> Dict[str, Any]:
"""
解析Vue模板配置
参数:
vue_templates_path: Vue模板配置文件路径
font_config_path: 字体配置文件路径可选
返回:
解析后的配置字典
"""
try:
# 读取Vue模板配置
with open(vue_templates_path, 'r', encoding='utf-8') as f:
vue_config = yaml.safe_load(f)
config = {'vue_templates': vue_config.get('vue_templates', {})}
# 读取字体配置(如果提供)
if font_config_path and os.path.exists(font_config_path):
with open(font_config_path, 'r', encoding='utf-8') as f:
font_config = yaml.safe_load(f)
config['font_config'] = font_config
print(f"成功加载Vue模板配置: {len(config['vue_templates'])} 个模板")
return config
except Exception as e:
print(f"解析配置文件失败: {e}")
return {}
def extract_layer_info_from_vue(template_content: str) -> List[Dict[str, Any]]:
"""
从Vue模板内容中提取图层信息
参数:
template_content: Vue模板内容字符串
返回:
图层信息列表
"""
layers = []
try:
# 解析所有图片图层(包括背景)
img_pattern = r'<img[^>]*src="([^"]+)"[^>]*(?:class="([^"]*)"|alt="([^"]*)")[^>]*/?>'
img_matches = re.findall(img_pattern, template_content, re.IGNORECASE)
for i, (img_src, css_class, alt_text) in enumerate(img_matches):
img_filename = os.path.basename(img_src)
layer_name = alt_text or css_class or f'image_{i+1}'
# 从CSS中提取样式包括透明度
styles = extract_css_styles(template_content, css_class) if css_class else {}
# 根据图片类型和CSS类设置位置和大小
if 'background' in css_class.lower() or 'background' in img_filename.lower():
position = {'left': 0, 'top': 0} # 背景图片从左上角开始
size = {'canvas_fit': True} # 背景图片填满整个画布
opacity = styles.get('opacity', 100) # 从CSS获取透明度默认100
z_index = 1
elif 'nku' in img_filename.lower():
position = {'align': 'center-top', 'offset': {'y': 150}}
size = {'width': 120, 'height': 120}
opacity = styles.get('opacity', 100)
z_index = 10 + i
elif 'stamp' in img_filename.lower():
position = {'align': 'center', 'offset': {'y': 200}}
size = {'width': 200, 'height': 200}
opacity = styles.get('opacity', 100)
z_index = 10 + i
elif 'lotus' in img_filename.lower():
position = {'align': 'center'}
size = {'scale': 0.8}
opacity = styles.get('opacity', 100)
z_index = 10 + i
else:
position = {'align': 'center'}
size = {'scale': 1.0}
opacity = styles.get('opacity', 100)
z_index = 10 + i
layers.append({
'name': layer_name,
'type': 'image',
'image_path': img_filename,
'position': position,
'size': size,
'opacity': opacity,
'z_index': z_index
})
# 解析文本图层
text_patterns = [
(r'<h1[^>]*class="[^"]*title[^"]*"[^>]*>\{\{\s*(\w+)\s*\}\}</h1>', 'title', 60, '#000000'),
(r'<h2[^>]*class="[^"]*subtitle[^"]*"[^>]*>\{\{\s*(\w+)\s*\}\}</h2>', 'subtitle', 30, '#333333')
]
for pattern, text_type, default_size, default_color in text_patterns:
matches = re.findall(pattern, template_content)
for i, var_name in enumerate(matches):
# 从CSS中提取样式
styles = extract_css_styles(template_content, text_type)
layers.append({
'name': f'{text_type}_{i+1}',
'type': 'text',
'text': {
'text': f'{{{{ {var_name}_content }}}}',
'font_size': styles.get('font_size', default_size),
'color': styles.get('color', default_color),
'font_family': styles.get('font_family', 'Microsoft YaHei')
},
'position': styles.get('position', {'align': 'center-top', 'offset': {'y': 300 + i * 100}}),
'opacity': styles.get('opacity', 100), # 从CSS获取透明度默认100
'z_index': 20 + i
})
print(f"从Vue模板中提取了 {len(layers)} 个图层")
return layers
except Exception as e:
print(f"解析Vue模板失败: {e}")
return []
def extract_css_styles(template_content: str, element_type: str) -> Dict[str, Any]:
"""
从Vue模板的CSS中提取样式信息
"""
styles = {}
try:
# 查找对应的CSS类
css_pattern = rf'\.{element_type}[^{{]*\{{([^}}]+)\}}'
css_matches = re.findall(css_pattern, template_content, re.DOTALL)
for css_block in css_matches:
# 提取字体大小
font_size_match = re.search(r'font-size:\s*(\d+)px', css_block)
if font_size_match:
styles['font_size'] = int(font_size_match.group(1))
# 提取颜色
color_match = re.search(r'color:\s*(#[0-9a-fA-F]{6}|#[0-9a-fA-F]{3}|\w+)', css_block)
if color_match:
styles['color'] = color_match.group(1)
# 提取字体家族
font_family_match = re.search(r'font-family:\s*[\'"]*([\'";}]+)[\'"]', css_block)
if font_family_match:
styles['font_family'] = font_family_match.group(1).strip()
# 提取透明度
opacity_match = re.search(r'opacity:\s*([0-9.]+)', css_block)
if opacity_match:
opacity_value = float(opacity_match.group(1))
# 将0-1的透明度值转换为0-100的百分比
styles['opacity'] = int(opacity_value * 100)
except Exception as e:
print(f"提取CSS样式失败: {e}")
return styles
def create_text_image(text_config: dict, canvas_size: tuple) -> Image.Image:
"""
使用PIL创建文本图像
"""
text = text_config['text']
font_size = text_config.get('font_size', 24)
color = text_config.get('color', '#000000')
font_family = text_config.get('font_family', 'arial.ttf')
# 处理颜色格式
if isinstance(color, str) and color.startswith('#'):
color = tuple(int(color[i:i+2], 16) for i in (1, 3, 5))
elif isinstance(color, list):
color = tuple(color)
try:
font = ImageFont.truetype(font_family, font_size)
except (OSError, IOError):
try:
font = ImageFont.load_default()
print(f"警告: 无法加载字体 {font_family},使用默认字体")
except:
font = None
# 创建临时图像来测量文本尺寸
temp_img = Image.new('RGBA', (1, 1), (0, 0, 0, 0))
temp_draw = ImageDraw.Draw(temp_img)
if font:
bbox = temp_draw.textbbox((0, 0), text, font=font)
text_width = bbox[2] - bbox[0]
text_height = bbox[3] - bbox[1]
else:
text_width = len(text) * font_size * 0.6
text_height = font_size * 1.2
text_width, text_height = int(text_width), int(text_height)
# 添加边距
margin = 20
img_width = text_width + margin * 2
img_height = text_height + margin * 2
# 创建文本图像
text_img = Image.new('RGBA', (img_width, img_height), (0, 0, 0, 0))
draw = ImageDraw.Draw(text_img)
if font:
draw.text((margin, margin), text, fill=color, font=font)
else:
draw.text((margin, margin), text, fill=color)
print(f"创建文本图像: '{text}', 尺寸: {img_width}x{img_height}")
return text_img
def calculate_position(position_config: dict, canvas_size: tuple, image_size: tuple) -> tuple:
"""
计算图层的最终位置
"""
canvas_width, canvas_height = canvas_size
image_width, image_height = image_size
left = position_config.get('left', 0)
top = position_config.get('top', 0)
# 处理对齐方式
if 'align' in position_config:
align = position_config['align']
if align in ['center', 'center-center', 'center-top', 'center-bottom']:
left = (canvas_width - image_width) // 2
elif align in ['right', 'right-center', 'right-top', 'right-bottom']:
left = canvas_width - image_width
if align in ['center', 'center-center', 'left-center', 'right-center']:
top = (canvas_height - image_height) // 2
elif align in ['bottom', 'left-bottom', 'center-bottom', 'right-bottom']:
top = canvas_height - image_height
# 处理偏移量
if 'offset' in position_config:
offset = position_config['offset']
left += offset.get('x', 0)
top += offset.get('y', 0)
return left, top
def resize_image(image: Image.Image, size_config: dict, canvas_size: tuple = None) -> Image.Image:
"""
根据配置调整图像大小
"""
if not size_config:
return image
current_width, current_height = image.size
# 处理canvas_fit选项让图片填满整个画布
if size_config.get('canvas_fit') and canvas_size:
canvas_width, canvas_height = canvas_size
return image.resize((canvas_width, canvas_height), Image.Resampling.LANCZOS)
if 'width' in size_config and 'height' in size_config:
new_width = size_config['width']
new_height = size_config['height']
elif 'scale' in size_config:
scale = size_config['scale']
new_width = int(current_width * scale)
new_height = int(current_height * scale)
elif 'width' in size_config:
new_width = size_config['width']
aspect_ratio = current_height / current_width
new_height = int(new_width * aspect_ratio)
elif 'height' in size_config:
new_height = size_config['height']
aspect_ratio = current_width / current_height
new_width = int(new_height * aspect_ratio)
else:
return image
return image.resize((new_width, new_height), Image.Resampling.LANCZOS)
def find_image_path(image_filename: str) -> Optional[str]:
"""
查找图片文件的完整路径
"""
search_paths = [
'../outputs',
'../images',
'./outputs',
'./images',
os.path.dirname(os.path.abspath(__file__)) + '/../outputs',
os.path.dirname(os.path.abspath(__file__)) + '/../images'
]
for search_path in search_paths:
full_path = os.path.join(search_path, image_filename)
if os.path.exists(full_path):
return full_path
return None
def create_psd_from_vue_config(vue_templates_path: str,
output_path: str,
canvas_size: Tuple[int, int] = (1080, 1920),
template_name: str = None,
content_data: Dict[str, str] = None,
font_config_path: str = None) -> Optional[str]:
"""
从Vue模板配置创建PSD文件
参数:
vue_templates_path: Vue模板配置文件路径
output_path: 输出PSD文件路径
canvas_size: 画布大小
template_name: 指定使用的模板名称
content_data: 文本内容数据
font_config_path: 字体配置文件路径
返回:
成功时返回输出路径失败时返回None
"""
try:
print(f"开始从Vue配置创建PSD文件: {output_path}")
# 解析配置
config = parse_vue_template_config(vue_templates_path, font_config_path)
if not config or not config.get('vue_templates'):
print("配置解析失败或没有找到Vue模板")
return None
vue_templates = config['vue_templates']
# 选择模板
if template_name and template_name in vue_templates:
selected_template = vue_templates[template_name]
print(f"使用指定模板: {template_name}")
else:
template_name = list(vue_templates.keys())[0]
selected_template = vue_templates[template_name]
print(f"使用默认模板: {template_name}")
# 提取图层信息
template_content = selected_template.get('template', '')
layers_info = extract_layer_info_from_vue(template_content)
if not layers_info:
print("没有提取到图层信息")
return None
# 处理文本内容替换
if content_data:
for layer in layers_info:
if layer.get('type') == 'text' and 'text' in layer:
text_content = layer['text']['text']
for key, value in content_data.items():
text_content = text_content.replace(f'{{{{ {key} }}}}', str(value))
layer['text']['text'] = text_content
# 创建PSD文件
return create_psd_from_layers(layers_info, output_path, canvas_size)
except Exception as e:
print(f"从Vue配置创建PSD失败: {e}")
import traceback
traceback.print_exc()
return None
def create_psd_from_layers(layers_info: List[Dict[str, Any]],
output_path: str,
canvas_size: Tuple[int, int]) -> Optional[str]:
"""
从图层信息创建PSD文件
"""
try:
# 确保输出目录存在
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
# 创建PSD文件
psd = PSDImage.new('RGB', canvas_size)
print(f"创建画布: {canvas_size[0]}x{canvas_size[1]}, 模式: RGB")
# 按z_index排序图层
sorted_layers = sorted(layers_info, key=lambda x: x.get('z_index', 0))
for i, layer_info in enumerate(sorted_layers):
layer_name = layer_info.get('name', f'layer_{i+1}')
print(f"\n处理图层 {i+1}: {layer_name}")
if layer_info['type'] == 'image':
# 处理图片图层
image_path = find_image_path(layer_info['image_path'])
if not image_path:
print(f"警告: 找不到图片文件 {layer_info['image_path']},跳过")
continue
image = Image.open(image_path)
print(f"原始图像尺寸: {image.size}")
# 调整图像大小
if 'size' in layer_info:
image = resize_image(image, layer_info['size'], canvas_size)
print(f"图像尺寸调整: {image.size}")
# 计算位置
left, top = calculate_position(layer_info.get('position', {}), canvas_size, image.size)
print(f"计算位置: left={left}, top={top}")
# 创建图层
layer = PixelLayer.frompil(image, psd, layer_name, top, left, Compression.RLE)
elif layer_info['type'] == 'text':
# 处理文本图层
print(f"创建文本图层: '{layer_info['text']['text']}'")
text_image = create_text_image(layer_info['text'], canvas_size)
# 计算位置
left, top = calculate_position(layer_info.get('position', {}), canvas_size, text_image.size)
print(f"计算位置: left={left}, top={top}")
# 创建图层
layer = PixelLayer.frompil(text_image, psd, layer_name, top, left, Compression.RLE)
else:
print(f"未知图层类型: {layer_info['type']},跳过")
continue
# 设置透明度
opacity = layer_info.get('opacity', 100)
if hasattr(layer, 'opacity'):
layer.opacity = opacity
print(f"设置图层透明度: {opacity}%")
# 确保图层可见
layer.visible = True
psd.append(layer)
print(f"成功添加图层: {layer_name}, 位置: ({left}, {top})")
print("\n生成合成图像...")
# 生成合成图像
composite_image = psd.composite(force=True)
# 更新PSD文件的图像数据
psd._record.image_data.set_data([channel.tobytes() for channel in composite_image.split()], psd._record.header)
# 保存PSD文件
psd.save(output_path)
print(f"\nPSD文件已成功创建保存在: {output_path}")
# 生成预览
preview_path = os.path.splitext(output_path)[0] + "_预览.png"
composite_image.save(preview_path)
print(f"预览已保存在: {preview_path}")
# 生成缩略图
thumbnail_path = os.path.splitext(output_path)[0] + "_缩略图.png"
thumbnail = composite_image.copy()
thumbnail.thumbnail((400, 300), Image.Resampling.LANCZOS)
thumbnail.save(thumbnail_path)
print(f"缩略图已保存在: {thumbnail_path}")
# 验证PSD文件
print("\n=== PSD文件结构验证 ===")
saved_psd = PSDImage.open(output_path)
print(f"PSD文件信息: {saved_psd}")
print(f"图层数量: {len(saved_psd)}")
for i, layer in enumerate(saved_psd):
print(f"图层 {i}: {layer.name}, 位置: ({layer.left}, {layer.top}), 大小: {layer.width}x{layer.height}, 可见: {layer.visible}")
return output_path
except Exception as e:
print(f"创建PSD文件失败: {e}")
import traceback
traceback.print_exc()
return None
# 为了兼容run_pipeline.py中的调用保留这个函数
def create_psd_from_images(image_paths: List[str],
output_path: str,
canvas_size: Tuple[int, int] = (1080, 1920),
mode: str = 'RGB') -> None:
"""
从图片列表创建PSD文件简化版保持兼容性
"""
try:
os.makedirs(os.path.dirname(os.path.abspath(output_path)), exist_ok=True)
psd = PSDImage.new(mode, canvas_size)
print(f"创建画布: {canvas_size[0]}x{canvas_size[1]}, 模式: {mode}")
for i, img_path in enumerate(image_paths):
if not os.path.exists(img_path):
print(f"警告: 图像文件不存在,跳过: {img_path}")
continue
image = Image.open(img_path)
print(f"处理图片 {i+1}: {os.path.basename(img_path)}, 尺寸: {image.size}")
# 居中布局
left = (canvas_size[0] - image.width) // 2
top = (canvas_size[1] - image.height) // 2
layer_name = f"layer {i+1} - {os.path.basename(img_path)}"
layer = PixelLayer.frompil(image, psd, layer_name, top, left, Compression.RLE)
layer.visible = True
psd.append(layer)
print(f"添加图层: {layer_name}, 位置: ({left}, {top})")
# 生成合成图像
composite_image = psd.composite(force=True)
psd._record.image_data.set_data([channel.tobytes() for channel in composite_image.split()], psd._record.header)
# 保存文件
psd.save(output_path)
print(f"PSD文件已成功创建保存在: {output_path}")
# 生成预览
preview_path = os.path.splitext(output_path)[0] + "_预览.png"
composite_image.save(preview_path)
print(f"预览已保存在: {preview_path}")
except Exception as e:
print(f"创建PSD文件时出错: {e}")
if __name__ == "__main__":
import sys
# 示例: 使用Vue模板配置创建PSD
print("=== 从Vue模板配置创建PSD ===")
vue_config_path = "../configs/vue_templates.yaml"
font_config_path = "../configs/font.yaml"
if os.path.exists(vue_config_path):
try:
content_data = {
"title_content": "AI海报生成系统",
"subtitle_content": "智能设计,一键生成"
}
result_path = create_psd_from_vue_config(
vue_templates_path=vue_config_path,
output_path="../outputs/vue_generated.psd",
template_name="nku.png",
content_data=content_data,
font_config_path=font_config_path if os.path.exists(font_config_path) else None
)
if result_path:
print(f"Vue模板PSD创建成功: {result_path}")
else:
print("Vue模板PSD创建失败")
except Exception as e:
print(f"Vue模板PSD创建失败: {e}")
import traceback
traceback.print_exc()
else:
print(f"配置文件不存在: {vue_config_path}")
print("\n使用方法:")
print(" python export_psd_from_json.py # 运行Vue模板示例")

302
scripts/flux_con.py Normal file
View File

@ -0,0 +1,302 @@
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 export_psd import *
from colorama import init, Fore, Back, Style
init(autoreset=True)
def comfyui_img_info(user_input_analysis_result, system_prompt):
"""
根据提示词分析结果生成图片并返回parse_imglist列表
参数:
user_input_analysis_result: 用户输入的分析结果字典
system_prompt: 用户输入的system prompt内容
返回:
parse_imglist (list): 图片解析列表包含图片信息的字典
"""
print(f"{Fore.CYAN}🎨 开始图片生成流程...{Style.RESET_ALL}")
# 从分析结果中提取参数
width = user_input_analysis_result.get('width', 1024)
height = user_input_analysis_result.get('height', 768)
batch_size = user_input_analysis_result.get('batch_size', 1)
print(f"{Fore.YELLOW}📐 图片参数: {Style.BRIGHT}{width}x{height}{Style.RESET_ALL}, 批次大小: {Style.BRIGHT}{batch_size}{Style.RESET_ALL}")
# 配置参数
WORKING_DIR = '../outputs'
COMFYUI_ENDPOINT = '101.201.50.90:8188'
DEFAULT_WORKFLOW = '../workflows/flux_work.json'
TEMP_WORKFLOW_DIR = '../workflows/temp'
# 创建临时目录
os.makedirs(TEMP_WORKFLOW_DIR, exist_ok=True)
PROCESSED_WORKFLOW = os.path.join(TEMP_WORKFLOW_DIR, f"processed_workflow_{uuid.uuid4().hex}.json")
print(f"{Fore.BLUE}⚙️ 正在预处理工作流...{Style.RESET_ALL}")
# 1. 预处理工作流
workflow_file = preprocess_workflow(
system_prompt=system_prompt,
width=width,
height=height,
batch_size=batch_size,
input_json=DEFAULT_WORKFLOW,
output_json=PROCESSED_WORKFLOW
)
# 2. 准备输出目录
os.makedirs(WORKING_DIR, exist_ok=True)
# 创建客户端ID
client_id = str(uuid.uuid4())
print(f"{Fore.MAGENTA}🖼️ 连接ComfyUI服务器进行图片生成...{Style.RESET_ALL}")
# 生成图像
saved_files = generate_images(
workflow_file=workflow_file,
server_address=COMFYUI_ENDPOINT,
output_dir=WORKING_DIR,
client_id=client_id
)
# 构建parse_imglist
parse_imglist = []
for file_path in saved_files:
# 提取图片信息
filename = os.path.basename(file_path)
name_without_ext = os.path.splitext(filename)[0]
# 构造图片信息字典
img_info = {
"picture_name": name_without_ext,
"picture_type": "png",
"picture_description": system_prompt,
"picture_size": f"{width}x{height}"
}
parse_imglist.append(img_info)
print(f"{Fore.GREEN}✅ 图片生成完成,共生成 {Style.BRIGHT}{len(parse_imglist)}{Style.RESET_ALL} 张图片")
return parse_imglist
def preprocess_workflow(system_prompt, width, height, batch_size, input_json='flux_work.json', output_json='processed_workflow.json'):
"""
预处理工作流文件更新系统提示和图像参数
"""
print(f"{Fore.BLUE}⚙️ 预处理工作流: {input_json}{Style.RESET_ALL}")
try:
# 使用UTF-8编码读取文件
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)
# 使用UTF-8编码保存更新后的工作流
with open(output_json, 'w', encoding='utf-8') as f:
json.dump(workflow, f, indent=2, ensure_ascii=False)
print(f"{Fore.GREEN}✅ 工作流已更新并保存到: {output_json}{Style.RESET_ALL}")
return output_json
except Exception as e:
print(f"{Fore.RED}❌ 预处理工作流出错: {str(e)}{Style.RESET_ALL}")
sys.exit(1)
def queue_prompt(prompt, server_address, client_id):
"""向服务器队列发送提示信息"""
p = {"prompt": prompt, "client_id": client_id}
data = json.dumps(p).encode('utf-8')
req = urllib.request.Request(f"http://{server_address}/prompt", data=data)
return json.loads(urllib.request.urlopen(req).read())
def get_image(filename, subfolder, folder_type, server_address):
"""获取生成的图像"""
data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
url_values = urllib.parse.urlencode(data)
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 get_images(ws, prompt, server_address, client_id, timeout=600):
"""获取生成的所有图像"""
prompt_id = queue_prompt(prompt, server_address, client_id)['prompt_id']
print(f'{Fore.CYAN}🎲 提示ID: {Style.BRIGHT}{prompt_id}{Style.RESET_ALL}')
output_images = {}
start_time = time.time()
while True:
if time.time() - start_time > timeout:
print(f"{Fore.RED}⏰ 超时:等待执行超过{timeout}{Style.RESET_ALL}")
break
try:
out = ws.recv()
if isinstance(out, str):
message = json.loads(out)
if message['type'] == 'executing':
data = message['data']
if data['node'] is None and data['prompt_id'] == prompt_id:
print(f'{Fore.GREEN}✅ 执行完成{Style.RESET_ALL}')
break
except Exception as e:
print(f"{Fore.RED}❌ 接收消息出错: {str(e)}{Style.RESET_ALL}")
break
history = get_history(prompt_id, server_address).get(prompt_id, {})
if not history:
print(f"{Fore.RED}❌ 未找到该提示的历史记录{Style.RESET_ALL}")
return {}
for node_id, node_output in history['outputs'].items():
if 'images' in node_output:
images_output = []
for image in node_output['images']:
try:
image_data = get_image(image['filename'], image['subfolder'], image['type'], server_address)
images_output.append({
'data': image_data,
'filename': image['filename'],
'subfolder': image['subfolder'],
'type': image['type']
})
except Exception as e:
print(f"{Fore.RED}❌ 获取图像错误: {str(e)}{Style.RESET_ALL}")
output_images[node_id] = images_output
print(f'{Fore.GREEN}📊 获取到 {Style.BRIGHT}{len(output_images)}{Style.RESET_ALL} 组图像输出')
return output_images
def generate_images(workflow_file, server_address, output_dir, client_id):
"""生成图像主函数"""
print(f"{Fore.MAGENTA}🖼️ 开始连接ComfyUI服务器: {server_address}{Style.RESET_ALL}")
try:
# 使用UTF-8编码加载工作流
with open(workflow_file, 'r', encoding='utf-8') as f:
workflow_data = json.load(f)
# 使用随机种子
seed = random.randint(1, 10**8)
print(f'{Fore.CYAN}🎲 使用种子: {Style.BRIGHT}{seed}{Style.RESET_ALL}')
# 更新种子
workflow_data['25']['inputs']['noise_seed'] = seed
# 创建WebSocket连接
ws_url = f"ws://{server_address}/ws?clientId={client_id}"
ws = create_connection(ws_url, timeout=600)
print(f"{Fore.YELLOW}⏳ 正在生成图片,请稍候...{Style.RESET_ALL}")
# 获取图像
images = get_images(ws, workflow_data, server_address, client_id)
ws.close()
# 保存图像
saved_files = []
if images:
print(f"{Fore.GREEN}💾 开始保存生成的图片...{Style.RESET_ALL}")
for node_id, image_list in images.items():
for i, img in enumerate(image_list):
timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
filename = f"{seed}_{timestamp}_{i}.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'{Fore.GREEN}✅ 已保存: {Style.BRIGHT}{file_path}{Style.RESET_ALL}')
except Exception as e:
print(f"{Fore.RED}❌ 保存图像错误: {str(e)}{Style.RESET_ALL}")
return saved_files
except Exception as e:
print(f"{Fore.RED}❌ 生成图像出错: {str(e)}{Style.RESET_ALL}")
return []
if __name__ == "__main__":
# 配置参数
WORKING_DIR = 'output'
COMFYUI_ENDPOINT = '101.201.50.90:8188'
DEFAULT_WORKFLOW = './workflows/flux_work.json'
TEMP_WORKFLOW_DIR = '../workflows/temp'
# 从命令行获取输入参数
if len(sys.argv) != 5:
print("用法: python test.py <prompt> <width> <height> <batch_size>")
print("示例: python test.py \"南开大学图书馆,大雨天\" 2048 1024 1")
sys.exit(1)
system_prompt = sys.argv[1]
width = int(sys.argv[2])
height = int(sys.argv[3])
batch_size = int(sys.argv[4])
# 创建临时目录
os.makedirs(TEMP_WORKFLOW_DIR, exist_ok=True)
# 创建临时文件路径
PROCESSED_WORKFLOW = os.path.join(TEMP_WORKFLOW_DIR, f"processed_workflow_{uuid.uuid4().hex}.json")
# 1. 预处理工作流
workflow_file = preprocess_workflow(
system_prompt=system_prompt,
width=width,
height=height,
batch_size=batch_size,
input_json=DEFAULT_WORKFLOW,
output_json=PROCESSED_WORKFLOW
)
# 2. 准备输出目录
os.makedirs(WORKING_DIR, exist_ok=True)
# 创建客户端ID
client_id = str(uuid.uuid4())
print(f"系统提示: {system_prompt}")
print(f"图像尺寸: {width}x{height}")
print(f"批次大小: {batch_size}")
print(f"工作流文件: {workflow_file}")
print(f"客户端ID: {client_id}")
print(f"开始使用ComfyUI生成图像: {COMFYUI_ENDPOINT}")
start_time = time.time()
# 生成图像
print(f"\n===== 开始生成图像 =====")
saved_files = generate_images(
workflow_file=workflow_file,
server_address=COMFYUI_ENDPOINT,
output_dir=WORKING_DIR,
client_id=client_id
)
# 输出结果
elapsed = time.time() - start_time
print(f"\n处理完成,耗时 {elapsed:.2f}")
print(f"共生成 {len(saved_files)} 张图像")
print(f"保存位置: {WORKING_DIR}")

View File

@ -1,61 +1,67 @@
"""
@file generate_layout.py
@brief Vue组件代码生成模块
基于DeepSeek API生成响应式Vue 3组件布局代码支持预定义模板
@author 王秀强 (2310460@mail.nankai.edu.cn)
@date 2025.5.19
@version v0.5.2
@details
本文件主要实现
- DeepSeek API调用封装和错误处理
- Vue 3 Composition API组件代码生成
- 海报布局的动态排版和样式生成
- 预定义Vue模板系统
- 增强Vue代码生成逻辑
- 代码清理和格式化处理
@note
- 需要配置DEEPSEEK_API_KEY环境变量
- 支持流式和非流式响应模式
- 生成的Vue代码包含完整的templatescript和style部分
- 具备指数退避重试机制处理API限流
- 支持基于图片类型的预定义模板
@usage
# 生成Vue组件代码
vue_code = generate_vue_code_enhanced("生成端午节海报Vue组件", parse_imglist, suggestions)
save_code(vue_code, "../outputs/poster.vue")
@copyright
(c) 2025 砚生项目组
"""
import os
import yaml
from openai import OpenAI
from dotenv import load_dotenv
import time
import logging
from colorama import init, Fore, Back, Style
from typing import List, Dict, Optional
# 初始化colorama
init(autoreset=True)
# === Config LLM call ===
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!")
# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# === prompts and parameters ===
def call_deepseek(
messages=None,
system_prompt="你是一个擅长前端开发的AI专注于生成Vue.js代码。",
prompt=None,
model='deepseek-chat',
temperature=0.6,
max_tokens=1000,
max_tokens=2000,
stream=False,
max_retries=3,
):
"""
调用 DeepSeek API,支持多轮对话和流式/非流式响应
Args:
messages (list): 对话消息列表格式为[{"role": "user", "content": "..."},...]
如果提供则优先使用否则根据 system_prompt和 prompt 构造.
system_prompt (str): 系统提示词仅在 message 未提供时使用.
prompt (str): 用户提示词仅在 message 未提供时使用.
model (str): 模型名称默认为 'deepseek-chat'
temperature (float): 温度参数控制生成文本的随机性默认为 0.6
max_tokens (int): 最大生成 token 数量默认为 1000
stream (bool): 是否使用流式响应默认为 False
max_retries (int): 最大重试次数默认为 3
Returns:
tuple: (result, usage)
- result (str): 非流式返回字符串(回复内容),流式返回生成器(逐块内容).
- usage (dict): token使用统计(非流式返回 Usage 对象,流式返回 None).
Raises:
ValueError: 如果 message prompt 都为空或参数无效
Exception: 如果 API 调用失败且达到最大重试次数
"""
# 初始化 OpenAI 客户端
client = OpenAI(
api_key=deepseek_api,
base_url=deepseek_url,
)
"""调用 DeepSeek API,支持多轮对话和流式/非流式响应"""
client = OpenAI(api_key=deepseek_api, base_url=deepseek_url)
# 参数验证
if messages is None:
@ -84,57 +90,284 @@ def call_deepseek(
stream=stream
)
# 流式响应
if stream:
# 流式响应处理
def stream_generator():
usage = None
for chunk in response:
if chunk.choices[0].delta.content is not None:
if hasattr(chunk, 'choices') and chunk.choices[0].delta.content is not None:
yield chunk.choices[0].delta.content
return usage
return stream_generator(), None
else:
# 非流式响应
content = response.choices[0].message.content
return content, response.usage
if hasattr(response, 'choices') and response.choices:
content = response.choices[0].message.content
usage = getattr(response, 'usage', None)
return content, usage
return "", None
except Exception as e:
if hasattr(e, 'status_code') and e.status_code == 429: # 限流
logger.warning(f"请求过于频繁,正在重试... (尝试 {attempt + 1}/{max_retries})")
if hasattr(e, 'status_code') and getattr(e, 'status_code') == 429:
time.sleep(2 ** attempt) # 指数退避
else:
logger.error(f"API 调用失败:{str(e)}")
elif attempt == max_retries - 1:
raise
else:
time.sleep(1)
raise Exception("达到最大重试次数API 调用失败")
def generate_vue_code(prompt=None):
prompt = (
"生成一个React组件代码用于端午节活动海报包含以下部分并指定排版位置"
"1. 背景图层div占据整个组件区域。"
"2. 主体图层div位于顶部1/4处居中包含标题和副标题。"
"3. 活动亮点div位于底部1/4处居中使用网格布局展示三项活动每项包含图标、标题和描述"
"4. 页脚div位于底部居中包含主办单位信息和logo图片。"
"组件尺寸为1080x1920px布局使用absolute定位仅关注排版位置不包含任何样式描述如颜色、字体、阴影、动画等"
"仅生成React代码本身不包含说明性文字、注释或Markdown格式。"
)
def load_vue_templates() -> Dict:
"""加载预定义的Vue模板配置"""
from utils import load_vue_templates as utils_load_templates
return utils_load_templates()
def get_template_by_images(parse_imglist: List[Dict]) -> Optional[str]:
"""根据图片列表选择合适的预定义模板"""
templates = load_vue_templates()
if not templates or not parse_imglist:
return None
# 使用utils中的函数确定模板类型
from utils import determine_template_type as utils_determine_type
template_choice = utils_determine_type(parse_imglist)
if template_choice in templates:
return templates[template_choice]['template']
# 备用:检查特定文件名
for img_info in parse_imglist:
img_name = img_info.get('picture_name', '')
if img_name in templates:
return templates[img_name]['template']
return None
def determine_template_type(parse_imglist: List[Dict]) -> str:
"""根据图片信息确定模板类型"""
from utils import determine_template_type as utils_determine_type
return utils_determine_type(parse_imglist)
def generate_layout_prompt(user_input_analysis_result: Dict, parse_imglist: List[Dict], suggestions: Optional[Dict] = None) -> str:
"""根据用户分析结果动态生成Vue布局提示"""
width = user_input_analysis_result.get("width", 1080)
height = user_input_analysis_result.get("height", 1920)
theme = user_input_analysis_result.get("main_theme", "活动海报")
# 从用户分析中提取更多信息
style = user_input_analysis_result.get("style", "现代简约")
color_scheme = user_input_analysis_result.get("color_scheme", "默认配色")
layout_type = user_input_analysis_result.get("layout_type", "标准布局")
target_audience = user_input_analysis_result.get("target_audience", "一般用户")
# 构造图片信息
images_info = []
for i, img in enumerate(parse_imglist):
img_desc = f"图片{i+1}: {img['picture_name']} - {img['picture_description']}"
images_info.append(img_desc)
images_text = "\n".join(images_info) if images_info else "无特定图片资源"
# 构造文案信息
content_parts = []
if suggestions:
try:
if 'layer6_title_content' in suggestions:
title = suggestions['layer6_title_content'].get('content', theme)
content_parts.append(f"主标题: {title}")
if 'layer7_subtitle_content' in suggestions:
subtitle = suggestions['layer7_subtitle_content'].get('content', '精彩活动,敬请参与')
content_parts.append(f"副标题: {subtitle}")
if 'layer5_logo_content' in suggestions:
logo = suggestions['layer5_logo_content'].get('text', '')
if logo:
content_parts.append(f"Logo文字: {logo}")
except Exception:
content_parts = [f"主标题: {theme}", "副标题: 精彩活动,敬请参与"]
else:
content_parts = [f"主标题: {theme}", "副标题: 精彩活动,敬请参与"]
content_info = "\n".join([f"- {part}" for part in content_parts])
# 根据主题类型调整布局描述
layout_requirements = []
if "节日" in theme or "festival" in theme.lower():
layout_requirements = [
"背景图层: 使用节日主题背景,营造氛围",
"标题区域: 突出节日名称,位于画布上方,使用醒目字体",
"装饰元素: 添加节日相关装饰图案,分布在画面周围",
"日期信息: 在适当位置显示日期",
"Logo区域: 位于底部,展示主办方信息"
]
elif "校园" in theme or "大学" in theme or "学术" in theme:
layout_requirements = [
"背景图层: 使用校园或学术主题背景",
"标题区域: 学术风格标题位于画布上方1/3处",
"内容区域: 展示学术内容或校园风光,居中布局",
"信息栏: 显示相关学术信息或活动详情",
"Logo区域: 展示学校标识,位于底部"
]
else:
layout_requirements = [
"背景图层: 使用主题相关背景图片,占据整个组件区域",
"主标题: 位于画布上方1/3处居中显示突出主题",
"副标题: 位于主标题下方,居中显示,补充说明",
"内容区域: 合理布局图片和信息,保持视觉平衡",
"Logo区域: 位于底部,居中显示主办方信息"
]
layout_text = "\n".join([f"{i+1}. {req}" for i, req in enumerate(layout_requirements)])
system_prompt = f"你是一个专业的前端设计师,擅长根据用户需求生成{style}风格的Vue.js组件。请根据{target_audience}的审美偏好生成完整的Vue组件代码。"
prompt = f"""
请为"{theme}"主题设计一个Vue 3组件要求如下
基本信息
- 组件尺寸: {width}x{height}px
- 设计风格: {style}
- 配色方案: {color_scheme}
- 布局类型: {layout_type}
图片资源
{images_text}
文案内容
{content_info}
布局要求
{layout_text}
技术要求
- 使用Vue 3 Composition API
- 使用absolute或flex定位进行精确布局
- 包含完整的templatescript setup和style部分
- 确保响应式设计和良好的视觉效果
- 图片使用相对路径引用
- 样式要体现{style}的设计理念
请生成完整可用的Vue组件代码代码要简洁优雅符合{style}风格特点
"""
try:
result, _ = call_deepseek(prompt=prompt, system_prompt=system_prompt, temperature=0.4)
return result if isinstance(result, str) else ""
except Exception:
return ""
def fill_template_content(template: str, suggestions: Dict) -> str:
"""填充模板中的动态内容"""
from utils import extract_content_from_suggestions
try:
title_content, subtitle_content, logo_content = extract_content_from_suggestions(suggestions)
filled_template = template
# 根据模板类型进行替换
if 'illustration-theme' in template:
filled_template = filled_template.replace("'见微知著记录南开'", f"'{title_content}'")
filled_template = filled_template.replace("'南开大学融媒体中心'", f"'{subtitle_content}'")
if logo_content:
filled_template = filled_template.replace("'主办方'", f"'{logo_content}'")
elif 'festival-theme' in template:
filled_template = filled_template.replace("'南开大学'", "'南开大学'")
filled_template = filled_template.replace("'中秋节'", f"'{title_content}'")
filled_template = filled_template.replace("'月圆人团圆'", f"'{subtitle_content}'")
from datetime import datetime
current_date = datetime.now().strftime('%Y年%m月%d')
filled_template = filled_template.replace("'2025年10月6日'", f"'{current_date}'")
else:
# 通用替换
filled_template = filled_template.replace('{{ title_content }}', title_content)
filled_template = filled_template.replace('{{ subtitle_content }}', subtitle_content)
filled_template = filled_template.replace('{{ logo_content }}', logo_content)
return filled_template
except Exception:
return template
def generate_vue_code_enhanced(
user_input_analysis_result: Dict,
parse_imglist: List[Dict],
suggestions: Optional[Dict] = None,
prompt: Optional[str] = None
) -> str:
"""增强的Vue代码生成函数优先使用预定义模板"""
# 尝试使用预定义模板
template_code = get_template_by_images(parse_imglist)
if template_code and suggestions:
vue_code = fill_template_content(template_code, suggestions)
return vue_code
# 使用AI生成
if not prompt:
prompt = generate_layout_prompt(user_input_analysis_result, parse_imglist, suggestions)
return generate_vue_code(prompt)
def generate_vue_code(prompt):
"""Vue代码生成函数"""
system_prompt = (
"你是一个擅长前端开发的AI专注于生成React.js代码。"
"生成的代码仅关注排版位置使用absolute定位不包含任何样式描述如颜色、字体、阴影、动画等"
"确保代码符合React最佳实践仅生成代码本身。"
"你是一个擅长前端开发的AI专注于生成Vue.js代码。"
"请生成完整的Vue 3组件包含template、script setup和style部分。"
"确保代码结构清晰,语法正确,可以直接使用。"
"不要包含任何解释文字,只返回纯代码。"
)
try:
result, usage = call_deepseek(prompt=prompt, system_prompt=system_prompt, temperature=0.4)
# 使用utils中的代码清理函数
from utils import clean_vue_code
if result and isinstance(result, str):
cleaned_result = clean_vue_code(result)
if cleaned_result:
return cleaned_result
# 如果API失败返回简单的错误提示
return "<template><div>Vue代码生成失败</div></template>"
except Exception:
return "<template><div>Vue代码生成失败</div></template>"
result,usage = call_deepseek(prompt=prompt, system_prompt=system_prompt,temperature=0.4)
# print(result)
# print(usage)
return result
def save_code(code,file_path="../outputs/generated_code.jsx"):
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, "w", encoding="utf-8") as f:
f.write(code)
def save_code(code, file_path="../outputs/generated_code.vue"):
"""保存代码到文件"""
try:
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, "w", encoding="utf-8") as f:
f.write(code)
if os.path.exists(file_path):
file_size = os.path.getsize(file_path)
except Exception:
pass
if __name__ == "__main__":
vue_code = generate_vue_code()
# 简单测试
test_analysis = {"width": 1080, "height": 1920, "main_theme": "端午节海报"}
test_imglist = [
{"picture_name": "background", "picture_description": "背景图片"},
{"picture_name": "lotus", "picture_description": "荷花装饰"}
]
test_suggestions = {
"layer6_title_content": {"content": "端午安康"},
"layer7_subtitle_content": {"content": "粽叶飘香,龙舟竞渡"},
"layer5_logo_content": {"text": "主办方"}
}
vue_code = generate_vue_code_enhanced(test_analysis, test_imglist, test_suggestions)
save_code(vue_code)
print("React组件代码已生成并保存到outputs/generated_code.jsx")

View File

@ -4,6 +4,10 @@ from openai import OpenAI
from dotenv import load_dotenv
import json
import yaml
from colorama import init, Fore, Back, Style
# 初始化colorama
init(autoreset=True)
# 加载 .env 文件
load_dotenv()
@ -21,6 +25,9 @@ LOGO_RULES = {}
def load_config_from_file(file_path):
"""从 YAML 文件加载配置"""
global DEFAULT_LOGO_TEXT, AVAILABLE_FONTS, NAMING_COLORS, STYLE_RULES, LOGO_RULES
print(f"{Fore.BLUE}📁 正在加载配置文件: {file_path}{Style.RESET_ALL}")
try:
with open(file_path, 'r', encoding='utf-8') as file:
config_data = yaml.safe_load(file)
@ -32,36 +39,42 @@ def load_config_from_file(file_path):
LOGO_RULES = config_data.get("LOGO_RULES", {})
if not AVAILABLE_FONTS:
print("警告:未能从 YAML 配置中加载可用字体列表,或列表为空。")
print(f"{Fore.YELLOW}⚠️ 警告:未能从 YAML 配置中加载可用字体列表,或列表为空。{Style.RESET_ALL}")
AVAILABLE_FONTS = [{"name": "SimHei", "displayName": "黑体 (简体)", "tags": ["通用"], "roles": ["title", "subtitle", "content"]}]
print(f"{Fore.CYAN}📝 已使用默认字体配置{Style.RESET_ALL}")
else:
print(f"{Fore.GREEN}✅ 成功加载 {Style.BRIGHT}{len(AVAILABLE_FONTS)}{Style.RESET_ALL} 个字体配置")
print("YAML 配置文件加载成功。")
print(f"默认 Logo 文字: {DEFAULT_LOGO_TEXT if DEFAULT_LOGO_TEXT else '未设置'}")
print(f"{Fore.GREEN}✅ YAML 配置文件加载成功。{Style.RESET_ALL}")
print(f"{Fore.CYAN}📝 默认 Logo 文字: {Style.BRIGHT}{DEFAULT_LOGO_TEXT if DEFAULT_LOGO_TEXT else '未设置'}{Style.RESET_ALL}")
except yaml.YAMLError as e:
print(f"解析 YAML 文件时发生错误: {e}")
print(f"{Fore.RED}解析 YAML 文件时发生错误: {e}{Style.RESET_ALL}")
AVAILABLE_FONTS = [{"name": "SimHei", "displayName": "黑体 (简体)", "tags": ["通用"], "roles": ["title", "subtitle", "content"]}]
print("已使用内部备用字体列表。")
print(f"{Fore.YELLOW}📝 已使用内部备用字体列表。{Style.RESET_ALL}")
except FileNotFoundError:
print(f"错误:未找到文件 {file_path}")
print(f"{Fore.RED}错误:未找到文件 {file_path}{Style.RESET_ALL}")
AVAILABLE_FONTS = [{"name": "SimHei", "displayName": "黑体 (简体)", "tags": ["通用"], "roles": ["title", "subtitle", "content"]}]
print("已使用内部备用字体列表。")
print(f"{Fore.YELLOW}📝 已使用内部备用字体列表。{Style.RESET_ALL}")
if not MOONSHOT_API_KEY:
print("错误:未能从环境变量中获取 MOONSHOT_API_KEY请检查 .env 文件。")
print(f"{Fore.RED}错误:未能从环境变量中获取 MOONSHOT_API_KEY请检查 .env 文件。{Style.RESET_ALL}")
exit()
# 初始化 OpenAI 客户端
try:
client = OpenAI(api_key=MOONSHOT_API_KEY, base_url="https://api.moonshot.cn/v1")
print("Kimi客户端初始化成功。")
print(f"{Fore.GREEN}Kimi客户端初始化成功。{Style.RESET_ALL}")
except Exception as e:
print(f"初始化OpenAI客户端失败: {e}")
print(f"{Fore.RED}初始化OpenAI客户端失败: {e}{Style.RESET_ALL}")
exit()
def extract_parameters_from_input(user_input):
"""
使用模型从用户输入中提取主题风格元素背景颜色和自定义Logo文字等信息
"""
print(f"{Fore.CYAN}🔍 正在提取参数: {Style.BRIGHT}{user_input[:50]}...{Style.RESET_ALL}")
extraction_prompt = f"""
你是一个专业的自然语言理解助手请从以下用户输入中提取海报设计的关键信息并严格按照JSON格式返回
用户输入{user_input}
@ -71,7 +84,7 @@ def extract_parameters_from_input(user_input):
"style_desc": "这里是海报的风格描述,例如:现代、简约、有文化气息",
"elements_to_include": ["这里是需要包含的元素,例如:南开大学教学楼", "书本", "阅读的人"],
"background_is_light": true,
"custom_logo_text": "这里是用户在输入中明确指定的、用作Logo的文字内容。例如如果用户说“Logo文字用技术创新研讨会则提取“技术创新研讨会”。如果用户没有明确指定Logo文字则返回null或空字符串。"
"custom_logo_text": "这里是用户在输入中明确指定的、用作Logo的文字内容。例如如果用户说'Logo文字用'技术创新研讨会'',则提取'技术创新研讨会'。如果用户没有明确指定Logo文字则返回null或空字符串。"
}}
注意对于 "background_is_light"如果用户输入明确提及背景色深浅则据此判断若未提及或无法判断默认为true (浅色)
对于 "custom_logo_text"仅当用户明确指定logo文字时才提取否则应为null或空字符串
@ -87,7 +100,7 @@ def extract_parameters_from_input(user_input):
temperature=0.2
)
response_content = completion.choices[0].message.content
print(f"--- 模型返回的参数提取结果 ---\n{response_content}\n--------------------------\n")
print(f"{Fore.GREEN}✅ 参数提取完成{Style.RESET_ALL}")
json_str = response_content.strip()
if "```json" in json_str:
@ -105,7 +118,7 @@ def extract_parameters_from_input(user_input):
return extracted_params
except Exception as e:
print(f"调用模型提取参数或解析JSON时发生错误: {e}")
print(f"{Fore.RED}调用模型提取参数或解析JSON时发生错误: {e}{Style.RESET_ALL}")
return {
"poster_theme": "默认主题",
"style_desc": "通用风格",
@ -168,6 +181,8 @@ def generate_text_content_for_layers(poster_theme, style_desc, background_is_lig
user_prompt = "\n".join(prompt_parts)
system_prompt_content = "你是一个专业的海报文案及设计元素建议助手。请严格按照用户要求的JSON格式输出确保内容符合设计原则、主题文化内涵并直接输出JSON内容不要包含任何修饰性或解释性的文字例如 '好的这是您要求的JSON''```json' 等标记。"
print(f"{Fore.BLUE}✍️ 正在生成文案内容...{Style.RESET_ALL}")
try:
completion = client.chat.completions.create(
model="moonshot-v1-8k",
@ -186,9 +201,11 @@ def generate_text_content_for_layers(poster_theme, style_desc, background_is_lig
json_str = json_str[3:-3].strip()
parsed_json = json.loads(json_str)
print(f"{Fore.GREEN}✅ 文案生成成功{Style.RESET_ALL}")
return parsed_json
except Exception as e:
print(f"调用Kimi或解析JSON时发生错误: {e}\n原始回复内容: {response_content if 'response_content' in locals() else 'N/A'}")
print(f"{Fore.RED}❌ 调用Kimi或解析JSON时发生错误: {e}{Style.RESET_ALL}")
print(f"{Fore.YELLOW}原始回复内容: {response_content if 'response_content' in locals() else 'N/A'}{Style.RESET_ALL}")
return {"error": f"LLM调用或解析失败: {e}"}
def get_poster_content_suggestions(user_input_string: str):
@ -196,12 +213,12 @@ def get_poster_content_suggestions(user_input_string: str):
主接口函数接收用户输入提取参数确定Logo文字并生成海报图层内容建议
返回包含建议内容的字典或包含错误信息的字典
"""
print(f"--- 开始处理用户输入: {user_input_string} ---")
print(f"{Fore.MAGENTA}--- 开始处理用户输入 ---{Style.RESET_ALL}")
# 1. 提取参数
extracted_params = extract_parameters_from_input(user_input_string)
if "error" in extracted_params:
print(f"参数提取过程中发生错误: {extracted_params['error']}")
print(f"{Fore.RED}参数提取过程中发生错误: {extracted_params['error']}{Style.RESET_ALL}")
return extracted_params # 返回包含错误信息的字典
poster_theme = extracted_params.get("poster_theme", "未知主题")
@ -210,20 +227,19 @@ def get_poster_content_suggestions(user_input_string: str):
background_is_light = extracted_params.get("background_is_light", True)
custom_logo_text = extracted_params.get("custom_logo_text")
print(f"\n--- 提取到的参数用于生成文案 ---")
print(f"主题: {poster_theme}")
print(f"风格: {style_desc}")
print(f"背景是否浅色: {background_is_light}")
print(f"用户指定Logo文字: {custom_logo_text if custom_logo_text else '未指定'}")
print(f"{Fore.YELLOW}📊 提取到的参数:")
print(f" 主题: {Style.BRIGHT}{poster_theme}{Style.RESET_ALL}")
print(f" 风格: {style_desc}")
print(f" 背景: {'浅色' if background_is_light else '深色'}")
print(f" Logo: {custom_logo_text if custom_logo_text else '未指定'}{Style.RESET_ALL}")
# 2. Logo文字选择逻辑
final_logo_text = DEFAULT_LOGO_TEXT # 默认为 ""
if custom_logo_text and custom_logo_text.strip(): # 如果用户指定了且不为空
final_logo_text = custom_logo_text.strip()
print(f"--- 使用用户自定义Logo文字: “{final_logo_text} ---")
print(f"{Fore.CYAN}📝 使用用户自定义Logo文字: “{Style.BRIGHT}{final_logo_text}{Style.RESET_ALL}")
else:
print(f"--- 使用默认Logo文字: “{final_logo_text}” ---")
print("--------------------------------\n")
print(f"{Fore.CYAN}📝 使用默认Logo文字: “{final_logo_text}{Style.RESET_ALL}")
# 3. 调用生成函数
generated_content = generate_text_content_for_layers(
@ -235,21 +251,15 @@ def get_poster_content_suggestions(user_input_string: str):
)
if "error" in generated_content:
print(f"内容生成过程中发生错误: {generated_content['error']}")
print(f"{Fore.RED}内容生成过程中发生错误: {generated_content['error']}{Style.RESET_ALL}")
else:
print("\n--- 成功生成的文案及设计建议 ---")
# print(json.dumps(generated_content, indent=2, ensure_ascii=False))
print(f"{Fore.GREEN}✅ 成功生成文案及设计建议{Style.RESET_ALL}")
return generated_content
if __name__ == "__main__":
# 用户自由输入示例
# user_input_example1 = "帮我设计一个关于'南开百年校庆'的海报风格要喜庆、现代Logo文字用'南开大学百年华诞',背景用浅红色。"
# user_input_example2 = "我要一个端午节的海报,中国风,深色背景。"
# user_input_example3 = "世界读书日海报,简约风格,元素包含打开的书和思考的人。"
load_config_from_file("./configs/font.yaml")
load_config_from_file("../configs/font.yaml")
user_input = input("请输入您的海报需求:")
@ -258,15 +268,13 @@ if __name__ == "__main__":
# 打印结果
if suggestions:
# print("\n--- 最终输出给调用者的内容 ---")
# print(json.dumps(suggestions, indent=2, ensure_ascii=False))
output_folder = "outputs"
output_folder = "../outputs"
output_file = os.path.join(output_folder, "poster_content.json")
try:
with open(output_file, "w", encoding="utf-8") as file:
json.dump(suggestions, file, indent=2, ensure_ascii=False)
print(f"\n--- 内容已成功保存到文件: {output_file} ---")
print(f"{Fore.GREEN}✅ 内容已成功保存到文件: {output_file}{Style.RESET_ALL}")
except Exception as e:
print(f"\n--- 保存到文件时发生错误: {e} ---")
print(f"{Fore.RED}❌ 保存到文件时发生错误: {e}{Style.RESET_ALL}")
else:
print("未生成任何内容,无法保存到文件。")
print(f"{Fore.RED}未生成任何内容,无法保存到文件。{Style.RESET_ALL}")

415
scripts/run_pipeline.py Normal file
View File

@ -0,0 +1,415 @@
"""
* @file run_pipeline.py
* @brief AI海报生成系统主服务入口和API服务器
* 集成多个AI模型提供统一的海报生成接口
*
* @author 王秀强 (2310460@mail.nankai.edu.cn)
* @date 2025.6.9
* @version v2.0.0
*
* @details
* 本文件主要实现
* - FastAPI服务器和RESTful API接口
* - 用户输入分析和海报生成流程编排
* - Vue组件代码生成和PSD文件合成
* - 会话管理和文件下载服务
* - 集成DeepSeekKimiComfyUI等AI服务
*
* @note
* - 依赖外部ComfyUI服务(101.201.50.90:8188)进行图片生成
* - 需要配置DEEPSEEK_API_KEY和MOONSHOT_API_KEY环境变量
* - PSD生成优先使用手动创建的模板文件
* - 支持CORS跨域访问生产环境需调整安全配置
*
* @usage
* # API服务器模式
* python run_pipeline.py
* # 选择: 2 (API服务器模式)
*
* # 本地测试模式
* python run_pipeline.py
* # 选择: 1 (本地测试模式)
*
* @copyright
* (c) 2025 砚生项目组
*/
"""
import os
import sys
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
from dotenv import load_dotenv
import json
import shutil
import uuid
from datetime import datetime
from typing import Optional
# 导入工具函数
from utils import (
print_step, print_result, get_session_folder,
llm_user_analysis, save_json_file, save_vue_file,
create_temp_config, CONFIG_PATHS
)
# 导入核心模块
from generate_layout import generate_vue_code_enhanced, save_code
from generate_text import load_config_from_file, get_poster_content_suggestions
from flux_con import comfyui_img_info
from export_psd_from_json import create_psd_from_images as create_psd_impl
# FastAPI相关
from fastapi import FastAPI
from fastapi.responses import FileResponse, JSONResponse
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
from colorama import init, Fore, Style
# 初始化colorama
init(autoreset=True)
# 加载环境变量
load_dotenv()
# FastAPI应用
app = FastAPI(title="AI海报生成系统API", version="2.0.0")
# 添加CORS中间件
app.add_middleware(
CORSMiddleware,
allow_origins=["*"], # 在生产环境中应该设置具体的域名
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 请求模型
class PosterRequest(BaseModel):
user_input: str
session_id: str = None
class ApiResponse(BaseModel):
status: str
message: str
data: dict = None
session_id: str = None
# 全局变量存储会话数据
sessions = {}
def create_psd_from_fixed_images(output_path: str) -> Optional[str]:
"""
使用固定的图片文件创建PSD文件
简化的PSD创建函数直接使用预定义的四个图片
"""
print(f"{Fore.CYAN}🎨 开始合成PSD文件...{Style.RESET_ALL}")
try:
# 使用固定的图片文件列表
fixed_image_files = ["background.png", "lotus.jpg", "nku.png", "stamp.jpg"]
image_paths = []
for img_file in fixed_image_files:
img_path = os.path.join(CONFIG_PATHS["output_folder"], img_file)
if os.path.exists(img_path):
image_paths.append(img_path)
print(f"{Fore.GREEN}✓ 找到图片: {img_file}{Style.RESET_ALL}")
else:
print(f"{Fore.YELLOW}⚠️ 图片不存在: {img_file}{Style.RESET_ALL}")
if not image_paths:
print(f"{Fore.RED}❌ 没有找到任何指定的图片文件{Style.RESET_ALL}")
return None
print(f"{Fore.CYAN}📋 将合并以下图片 (共{len(image_paths)}张):")
for i, path in enumerate(image_paths):
print(f" {i + 1}. {os.path.basename(path)}")
# 确保输出目录存在
os.makedirs(os.path.dirname(output_path), exist_ok=True)
# 调用PSD创建函数
create_psd_impl(
image_paths=image_paths,
output_path=output_path,
canvas_size=(1080, 1920),
mode='RGB'
)
print(f"{Fore.GREEN}✅ PSD文件创建成功: {output_path}{Style.RESET_ALL}")
# 验证PSD文件
if os.path.exists(output_path):
file_size = os.path.getsize(output_path) / (1024 * 1024)
print(f"{Fore.CYAN}📁 PSD文件大小: {file_size:.2f} MB{Style.RESET_ALL}")
return output_path
except Exception as e:
print(f"{Fore.RED}❌ PSD文件创建失败: {str(e)}{Style.RESET_ALL}")
import traceback
traceback.print_exc()
return None
def run_pipeline(user_input: str = None) -> Optional[str]:
try:
print(f"{Fore.MAGENTA}{'=' * 50}")
print(f"{Fore.MAGENTA}🎨 海报生成流程启动 🎨")
print(f"{'=' * 50}{Style.RESET_ALL}")
print_step(1, "生成临时配置")
temp_config_path = create_temp_config(user_input)
load_config_from_file(temp_config_path)
print_step(1, "生成临时配置", "完成")
print_step(2, "分析用户输入")
user_input_analysis_result = llm_user_analysis(user_input)
print_result("分析结果", user_input_analysis_result.get('main_theme', '未知'))
print_step(2, "分析用户输入", "完成")
print_step(3, "生成图片信息")
system_prompt = user_input_analysis_result["analyzed_prompt"]
parse_imglist = comfyui_img_info(user_input_analysis_result, system_prompt)
print_result("生成图片数量", len(parse_imglist))
print_step(3, "生成图片信息", "完成")
print_step(4, "生成文案建议")
suggestions = get_poster_content_suggestions(user_input_analysis_result["analyzed_prompt"])
# 保存文案到文件
suggestions_path = os.path.join(CONFIG_PATHS["output_folder"], "poster_content.json")
save_json_file(suggestions, suggestions_path)
print_step(4, "生成文案建议", "完成")
print_step(5, "生成Vue组件")
# 使用增强的Vue代码生成已移至generate_layout模块
vue_code = generate_vue_code_enhanced(
user_input_analysis_result,
parse_imglist,
suggestions
)
vue_path = os.path.join(CONFIG_PATHS["output_folder"], "generated_code.vue")
save_vue_file(vue_code, vue_path)
print_step(5, "生成Vue组件", "完成")
print_step(6, "合成PSD文件")
psd_path = os.path.join(CONFIG_PATHS["output_folder"], "final_poster.psd")
result_path = create_psd_from_fixed_images(psd_path)
if result_path:
print_step(6, "合成PSD文件", "完成")
else:
print_step(6, "合成PSD文件", "错误")
print(f"\n{Fore.GREEN}{'=' * 50}")
print(f"✅ 流程执行完成!")
print(f"{'=' * 50}{Style.RESET_ALL}")
return result_path
except Exception as e:
print_step("X", f"Pipeline执行", "错误")
print(f"{Fore.RED}错误详情: {str(e)}{Style.RESET_ALL}")
import traceback
traceback.print_exc()
return None
def run_local_pipeline(user_input: str = None):
"""
本地运行整个管道流程
"""
print(f"{Fore.CYAN}🎬 启动本地流程,输入: {Style.BRIGHT}{user_input}{Style.RESET_ALL}")
output_path = run_pipeline(user_input)
if output_path:
print(f"{Fore.GREEN}🎊 流程执行成功!")
print(f"{Fore.YELLOW}📁 生成文件:")
print(f" - Vue组件: {os.path.join(CONFIG_PATHS['output_folder'], 'generated_code.vue')}")
print(f" - PSD文件: {os.path.join(CONFIG_PATHS['output_folder'], 'final_poster.psd')}")
print(f" - 文案JSON: {os.path.join(CONFIG_PATHS['output_folder'], 'poster_content.json')}")
print(f"{Fore.CYAN}💡 查看 outputs/ 目录获取生成的文件{Style.RESET_ALL}")
else:
print(f"{Fore.RED}❌ 流程执行失败{Style.RESET_ALL}")
# === API路由 ===
@app.get("/")
def read_root():
return {
"message": "AI海报生成系统API v2.0",
"version": "2.0.0",
"features": [
"预定义Vue模板支持",
"简化的代码结构",
"优化的流程管理"
],
"endpoints": {
"generate_poster": "/api/generate-poster",
"download": "/api/download/{file_type}",
"health": "/health",
"status": "/api/status/{session_id}"
}
}
@app.get("/health")
def health_check():
return {"status": "healthy", "timestamp": datetime.now().isoformat()}
@app.post("/api/generate-poster", response_model=ApiResponse)
async def generate_poster_api(request: PosterRequest):
try:
session_folder, session_id = get_session_folder(request.session_id)
print(f"{Fore.BLUE}🎨 开始生成海报...{Style.RESET_ALL}")
print(f"{Fore.CYAN}用户输入: {request.user_input}{Style.RESET_ALL}")
# === 步骤1: 生成配置文件 ===
temp_config_path = create_temp_config(request.user_input)
load_config_from_file(temp_config_path)
# === 步骤2: 分析用户输入 ===
user_input_analysis_result = llm_user_analysis(request.user_input)
# === 步骤3: 生成图片信息 ===
system_prompt = user_input_analysis_result["analyzed_prompt"]
parse_imglist = comfyui_img_info(user_input_analysis_result, system_prompt)
# === 步骤4: 生成文案建议 ===
suggestions = get_poster_content_suggestions(user_input_analysis_result["analyzed_prompt"])
# 保存文案到会话文件夹
suggestions_path = os.path.join(session_folder, "poster_content.json")
save_json_file(suggestions, suggestions_path)
# === 步骤5: 生成Vue组件 ===
vue_code = generate_vue_code_enhanced(
user_input_analysis_result,
parse_imglist,
suggestions
)
vue_path = os.path.join(session_folder, "generated_code.vue")
save_vue_file(vue_code, vue_path)
# === 步骤6: 合成PSD文件 ===
psd_path = os.path.join(session_folder, "final_poster.psd")
psd_created = create_psd_from_fixed_images(psd_path)
# 返回API响应
return ApiResponse(
status="success",
message="海报生成完成",
data={
"vue_file": vue_path if os.path.exists(vue_path) else None,
"psd_file": psd_path if psd_created else None,
"content_file": suggestions_path,
"analysis_result": user_input_analysis_result,
"images_info": parse_imglist,
"suggestions": suggestions,
"vue_code": vue_code,
"file_size_mb": round(os.path.getsize(psd_path) / (1024 * 1024), 2) if psd_created else 0,
"generated_images": len(parse_imglist)
},
session_id=session_id
)
except Exception as e:
print(f"{Fore.RED}❌ API错误: {str(e)}{Style.RESET_ALL}")
import traceback
traceback.print_exc()
return ApiResponse(
status="error",
message=f"生成失败: {str(e)}",
data=None,
session_id=session_id if 'session_id' in locals() else None
)
@app.get("/api/download/{file_type}")
async def download_file(file_type: str, session_id: str = None):
"""下载生成的文件"""
try:
if session_id:
session_folder = os.path.join(CONFIG_PATHS["output_folder"], f"session_{session_id}")
else:
session_folder = CONFIG_PATHS["output_folder"]
file_mapping = {
"vue": ("generated_code.vue", "text/plain"),
"psd": ("final_poster.psd", "application/octet-stream"),
"json": ("poster_content.json", "application/json")
}
if file_type not in file_mapping:
return JSONResponse(status_code=400, content={"error": "不支持的文件类型"})
filename, media_type = file_mapping[file_type]
file_path = os.path.join(session_folder, filename)
if os.path.exists(file_path):
return FileResponse(
path=file_path,
media_type=media_type,
filename=filename
)
else:
return JSONResponse(status_code=404, content={"error": "文件不存在"})
except Exception as e:
return JSONResponse(status_code=500, content={"error": f"下载失败: {str(e)}"})
@app.get("/api/status/{session_id}")
async def get_session_status(session_id: str):
"""获取会话状态"""
try:
session_folder = os.path.join(CONFIG_PATHS["output_folder"], f"session_{session_id}")
if not os.path.exists(session_folder):
return JSONResponse(status_code=404, content={"error": "会话不存在"})
files_status = {
"vue_file": os.path.exists(os.path.join(session_folder, "generated_code.vue")),
"psd_file": os.path.exists(os.path.join(session_folder, "final_poster.psd")),
"content_file": os.path.exists(os.path.join(session_folder, "poster_content.json"))
}
return {
"session_id": session_id,
"files": files_status,
"folder": session_folder
}
except Exception as e:
return JSONResponse(status_code=500, content={"error": f"状态查询失败: {str(e)}"})
if __name__ == "__main__":
import uvicorn
print(f"{Fore.BLUE}🔧 运行模式选择:{Style.RESET_ALL}")
print(f"{Fore.YELLOW}1. 本地测试模式")
print(f"2. API服务器模式{Style.RESET_ALL}")
choice = input("请选择运行模式 (1/2): ").strip()
if choice == "1":
# 本地测试
test_input = input("请输入海报需求 (留空使用默认): ").strip()
if not test_input:
test_input = "端午节海报,传统风格"
run_local_pipeline(test_input)
else:
# 启动API服务器
print(f"{Fore.GREEN}🚀 启动API服务器 v2.0...{Style.RESET_ALL}")
uvicorn.run(app, host="0.0.0.0", port=8000)

View File

323
scripts/utils.py Normal file
View File

@ -0,0 +1,323 @@
# -*- coding: utf-8 -*-
"""
工具函数模块
整合所有辅助函数和公共功能
"""
import os
import uuid
import json
import yaml
from datetime import datetime
from dotenv import load_dotenv
from colorama import init, Fore, Style
from pathlib import Path
from typing import Dict, List, Optional, Tuple
# 初始化colorama
init(autoreset=True)
# 加载环境变量
load_dotenv()
# 配置路径
CONFIG_PATHS = {
"font": "../configs/font.yaml",
"output_folder": "../outputs/",
"workflows": "../workflows/",
"templates": "../configs/templates.yaml"
}
def print_step(step_num: int, description: str, status: str = "进行中"):
"""打印带颜色的步骤信息"""
if status == "进行中":
print(f"{Fore.BLUE}📋 步骤{step_num}: {description}...{Style.RESET_ALL}")
elif status == "完成":
print(f"{Fore.GREEN}✅ 步骤{step_num}: {description} - 完成{Style.RESET_ALL}")
elif status == "错误":
print(f"{Fore.RED}❌ 步骤{step_num}: {description} - 出错{Style.RESET_ALL}")
def print_result(key: str, value: str):
"""打印结果信息"""
print(f"{Fore.CYAN}📊 {key}: {value}{Style.RESET_ALL}")
def get_session_folder(session_id: Optional[str] = None) -> Tuple[str, str]:
"""获取会话专用的输出文件夹"""
if not session_id:
session_id = str(uuid.uuid4())
session_folder = os.path.join(CONFIG_PATHS["output_folder"], f"session_{session_id}")
os.makedirs(session_folder, exist_ok=True)
return session_folder, session_id
def load_config_file(config_type: str) -> Dict:
"""加载配置文件"""
config_path = CONFIG_PATHS.get(config_type)
if not config_path or not os.path.exists(config_path):
print(f"{Fore.YELLOW}⚠️ 配置文件不存在: {config_path},使用默认配置{Style.RESET_ALL}")
return {}
try:
with open(config_path, "r", encoding="utf-8") as f:
if config_path.endswith('.yaml') or config_path.endswith('.yml'):
config = yaml.safe_load(f)
else:
config = json.load(f)
print(f"{Fore.GREEN}✅ 配置文件加载成功: {config_path}{Style.RESET_ALL}")
return config
except Exception as e:
print(f"{Fore.RED}❌ 配置文件加载失败: {e}{Style.RESET_ALL}")
return {}
def save_json_file(data: Dict, file_path: str):
"""保存JSON文件"""
try:
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, "w", encoding="utf-8") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
print(f"{Fore.GREEN}✅ JSON文件已保存: {file_path}{Style.RESET_ALL}")
except Exception as e:
print(f"{Fore.RED}❌ JSON文件保存失败: {e}{Style.RESET_ALL}")
def save_vue_file(vue_code: str, file_path: str):
"""保存Vue文件"""
try:
os.makedirs(os.path.dirname(file_path), exist_ok=True)
with open(file_path, "w", encoding="utf-8") as f:
f.write(vue_code)
if os.path.exists(file_path):
file_size = os.path.getsize(file_path)
print(f"{Fore.GREEN}✅ Vue文件已保存: {file_path} ({file_size} 字节){Style.RESET_ALL}")
else:
print(f"{Fore.RED}❌ Vue文件保存失败{Style.RESET_ALL}")
except Exception as e:
print(f"{Fore.RED}❌ Vue文件保存失败: {e}{Style.RESET_ALL}")
def create_temp_config(user_input: Optional[str] = None) -> str:
"""动态生成临时配置文件"""
if not user_input:
user_input = "默认海报配置"
temp_config = {
"default_logo_text": "",
"available_fonts": [
{
"name": "Microsoft YaHei",
"displayName": "微软雅黑",
"tags": ["现代", "清晰"],
"roles": ["title", "subtitle", "content"]
},
{
"name": "SimHei",
"displayName": "黑体",
"tags": ["通用", "标准"],
"roles": ["title", "subtitle", "content"]
}
],
"vue_templates": {
"lotus.jpg": {
"theme": "荷花主题",
"style": "传统优雅",
"template_name": "lotus_template"
},
"nku.png": {
"theme": "南开大学",
"style": "学术正式",
"template_name": "nku_template"
},
"stamp.jpg": {
"theme": "印章装饰",
"style": "传统文化",
"template_name": "stamp_template"
},
"background.png": {
"theme": "通用背景",
"style": "简约现代",
"template_name": "background_template"
}
}
}
temp_config_path = os.path.join(CONFIG_PATHS["output_folder"], "temp_config.yaml")
with open(temp_config_path, 'w', encoding='utf-8') as f:
yaml.dump(temp_config, f, allow_unicode=True, default_flow_style=False)
print(f"{Fore.GREEN}✅ 临时配置文件已生成: {temp_config_path}{Style.RESET_ALL}")
return temp_config_path
# === 用户输入分析模块 (从 prompt_analysis.py 整合) ===
from generate_layout import call_deepseek
def llm_user_analysis(user_input: str) -> Dict:
"""
使用DeepSeek动态分析用户输入提取海报设计参数
"""
if not user_input:
user_input = "端午节海报,包含背景、活动亮点和图标"
print(f"{Fore.CYAN}🔍 正在分析用户输入: {Style.BRIGHT}{user_input}{Style.RESET_ALL}")
# 构建分析提示词
analysis_prompt = f"""
请分析以下用户输入的海报需求提取关键信息并以JSON格式返回
用户输入{user_input}
请严格按照以下JSON格式返回
{{
"analyzed_prompt": "原始用户输入",
"keywords": ["提取的关键词1", "关键词2", "关键词3"],
"width": 1080,
"height": 1920,
"batch_size": 2,
"poster_type": "海报类型(如:节日海报、活动海报、产品海报等)",
"main_theme": "主要主题",
"style_preference": "风格偏好(如:现代、传统、简约等)",
"color_preference": "颜色偏好(如:暖色调、冷色调、单色等)"
}}
注意
1. keywords应该包含3-5个最重要的关键词
2. 根据用户输入推断合适的海报类型
3. 尺寸默认为1080x1920除非用户明确指定
4. batch_size根据需求调整通常为1-4
5. 分析用户的风格和颜色偏好
"""
system_prompt = "你是一个专业的设计需求分析师擅长从用户描述中提取海报设计的关键参数。请严格按照JSON格式返回结果确保输出的JSON格式正确且完整。"
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_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("```"):
json_str = json_str[3:-3].strip()
analysis_result = json.loads(json_str)
print(f"{Fore.GREEN}✅ 分析完成! {Style.RESET_ALL}")
print(f"{Fore.YELLOW}📊 主题: {Style.BRIGHT}{analysis_result.get('main_theme', '未知')}{Style.RESET_ALL}")
print(f"{Fore.YELLOW}🎨 风格: {analysis_result.get('style_preference', '未设置')}")
print(f"{Fore.YELLOW}🔖 关键词: {', '.join(analysis_result.get('keywords', []))}{Style.RESET_ALL}")
return analysis_result
except Exception as e:
print(f"{Fore.RED}❌ 分析失败: {str(e)}{Style.RESET_ALL}")
# 返回默认值
return {
"analyzed_prompt": user_input,
"keywords": ["海报", "设计", "活动"],
"width": 1080,
"height": 1920,
"batch_size": 2,
"poster_type": "通用海报",
"main_theme": "默认主题",
"style_preference": "现代",
"color_preference": "暖色调"
}
def validate_file_exists(file_path: str) -> bool:
"""验证文件是否存在"""
exists = os.path.exists(file_path)
if exists:
print(f"{Fore.GREEN}✓ 文件存在: {os.path.basename(file_path)}{Style.RESET_ALL}")
else:
print(f"{Fore.YELLOW}⚠️ 文件不存在: {os.path.basename(file_path)}{Style.RESET_ALL}")
return exists
def get_file_info(file_path: str) -> Dict:
"""获取文件信息"""
if not os.path.exists(file_path):
return {"exists": False}
stat = os.stat(file_path)
return {
"exists": True,
"size": stat.st_size,
"size_mb": round(stat.st_size / (1024 * 1024), 2),
"modified": datetime.fromtimestamp(stat.st_mtime).isoformat()
}
# Vue模板工具函数
def load_vue_templates() -> Dict:
"""加载预定义的Vue模板配置"""
template_path = "../configs/vue_templates.yaml"
try:
with open(template_path, 'r', encoding='utf-8') as f:
templates = yaml.safe_load(f)
return templates.get('vue_templates', {})
except Exception:
return {}
def determine_template_type(parse_imglist: List[Dict]) -> str:
"""根据图片信息确定模板类型"""
for img_info in parse_imglist:
description = img_info.get('picture_description', '').lower()
name = img_info.get('picture_name', '').lower()
festival_keywords = ['中秋', '春节', '端午', '国庆', '元宵', '重阳', '节日', 'festival']
if any(keyword in description or keyword in name for keyword in festival_keywords):
return 'festival'
illustration_keywords = ['插画', '建筑', '校园', '大学', '教学楼', 'illustration', 'building']
if any(keyword in description or keyword in name for keyword in illustration_keywords):
return 'illustration'
return 'illustration'
def clean_vue_code(result: str) -> str:
"""清理Vue代码移除markdown标记"""
if not result:
return result
if "```vue" in result:
result = result.split("```vue")[1].split("```")[0].strip()
elif "```html" in result:
result = result.split("```html")[1].split("```")[0].strip()
elif result.startswith("```") and result.endswith("```"):
result = result[3:-3].strip()
return result
def extract_content_from_suggestions(suggestions: Dict) -> Tuple[str, str, str]:
"""从建议中提取文案内容"""
try:
title_content = suggestions.get('layer6_title_content', {}).get('content', '南开风采')
subtitle_content = suggestions.get('layer7_subtitle_content', {}).get('content', '百年学府,智慧之光')
logo_content = suggestions.get('layer5_logo_content', {}).get('text', '')
return title_content, subtitle_content, logo_content
except Exception:
return '南开风采', '百年学府,智慧之光', ''
if __name__ == "__main__":
# 测试工具函数
print(f"{Fore.MAGENTA}🧪 测试工具函数{Style.RESET_ALL}")
# 测试用户输入分析
test_input = "春节海报,红色背景,现代风格"
result = llm_user_analysis(test_input)
print(f"\n{Fore.GREEN}分析结果:")
print(json.dumps(result, indent=2, ensure_ascii=False))

0
scripts/问题.md Normal file
View File

292
workflows/flux_redux.json Normal file
View File

@ -0,0 +1,292 @@
{
"6": {
"inputs": {
"text": [
"45",
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": 20,
"denoise": 1,
"model": [
"30",
0
]
},
"class_type": "BasicScheduler",
"_meta": {
"title": "基本调度器"
}
},
"22": {
"inputs": {
"model": [
"30",
0
],
"conditioning": [
"41",
0
]
},
"class_type": "BasicGuider",
"_meta": {
"title": "基本引导器"
}
},
"25": {
"inputs": {
"noise_seed": 214516345808749
},
"class_type": "RandomNoise",
"_meta": {
"title": "随机噪波"
}
},
"26": {
"inputs": {
"guidance": 3.5,
"conditioning": [
"6",
0
]
},
"class_type": "FluxGuidance",
"_meta": {
"title": "Flux引导"
}
},
"27": {
"inputs": {
"width": 1024,
"height": 1024,
"batch_size": 4
},
"class_type": "EmptySD3LatentImage",
"_meta": {
"title": "空Latent图像SD3"
}
},
"30": {
"inputs": {
"max_shift": 1.15,
"base_shift": 0.5,
"width": 1024,
"height": 1024,
"model": [
"12",
0
]
},
"class_type": "ModelSamplingFlux",
"_meta": {
"title": "采样算法Flux"
}
},
"38": {
"inputs": {
"clip_name": "sigclip_vision_patch14_384.safetensors"
},
"class_type": "CLIPVisionLoader",
"_meta": {
"title": "加载CLIP视觉"
}
},
"39": {
"inputs": {
"crop": "center",
"clip_vision": [
"38",
0
],
"image": [
"40",
0
]
},
"class_type": "CLIPVisionEncode",
"_meta": {
"title": "CLIP视觉编码"
}
},
"40": {
"inputs": {
"image": "WechatIMG16695.jpeg"
},
"class_type": "LoadImage",
"_meta": {
"title": "加载图像"
}
},
"41": {
"inputs": {
"strength": 1,
"strength_type": "multiply",
"conditioning": [
"26",
0
],
"style_model": [
"42",
0
],
"clip_vision_output": [
"39",
0
]
},
"class_type": "StyleModelApply",
"_meta": {
"title": "应用风格模型"
}
},
"42": {
"inputs": {
"style_model_name": "flux1-redux-dev.safetensors"
},
"class_type": "StyleModelLoader",
"_meta": {
"title": "加载风格模型"
}
},
"45": {
"inputs": {
"user_prompt": "作为一个AI提示词专家请你仿照范例根据我给出的主题生成一条符合下列要求的提示词来让CLIP模型可以更好地理解画面主体。注意你的输出将提供给图生图image-to-image模型所以你只需要对用户输入中的风格和细节部分作扩展。\n 要求共五条,请严格遵守:\n 1 用自然语言简单句来描述画面,请避免出现过于长的,或者格式过于复杂的句子,句子中不要出现*等特殊符号。\n 2.用英语表达。 \n 3.直接给出prompt内容即可不需要解释和说明。\n 4. 每条prompt至少50词不超过200词。\n 5.避免模棱两可的说法。\n 例如:[Reference Image Weight: 0.7] Cartoonized Nankai University Main Building, \nGothic-Revival architecture with rounded edges, crimson bricks and golden arched windows (ultra-high texture details), whimsical cloud-shaped eaves dripping liquid clock gears (steampunk elements), soft pastel gradients. \nDynamic elements: \nTranslucent 1919-era scholar phantoms floating with glowing books (semi-transparent mercury texture), oversized origami maple leaves spiraling around twin bell towers (visible musical notes in air). \nEnvironment: \nSurreal candy-pink to indigo gradient sky, emerald velvet lawns with squirrels wearing graduation caps (playful proportions:1.5x). Ground puddles reflecting calculus formula ripples (mathematical glow effect). \nTechnical parameters: \nStudio Ghibli style, watercolor rendering, 8K resolution, cinematic lighting, symmetry composition, ultra-detailed lineart",
"system_prompt": "南开大学鸟瞰图3D电影高级风格。",
"enable_history": false,
"max_history": 10,
"history_json": "",
"save_path": "./chat_history.json",
"api_config": [
"46",
0
]
},
"class_type": "DeepSeekChat",
"_meta": {
"title": "LLM Model Input Box"
}
},
"46": {
"inputs": {
"config_name": "DeepSeek官方Chat API",
"temperature": 1,
"max_tokens": 512,
"stream": false,
"api_key": ""
},
"class_type": "DeepSeekAPIConfig",
"_meta": {
"title": "LLM API Model Selector"
}
}
}

226
workflows/flux_work.json Normal file
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": "{{width}}",
"height": "{{height}}",
"batch_size": "{{batch_size}}"
},
"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": "{{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": "腾讯的周年庆qq,wx要素齐全",
"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": "3"
},
"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": "3"
},
"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"
}
}
}

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"
}
}
}

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": "3"
},
"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"
}
}
}

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"
}
}
}

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": "3"
},
"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": "3"
},
"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"
}
}
}

34
接口文档.md Normal file
View File

@ -0,0 +1,34 @@
## Vue 模板系统
系统现在支持两种预定义的 Vue 模板:
### 1. 插画风模板 (illustration)
**适用场景**:通用建筑、校园、教学楼等主题
**结构**4 层布局
- 插画底图AI 生成的通用建筑插图,彩色插画,色调和谐
- 主标题:最大号字体,"见微知著记录南开",放置在不遮挡主体的相对空白处
- 南开 logo南开大学标识
- 机构名称:底部居中,"南开大学融媒体中心"
### 2. 节日模板 (festival)
**适用场景**:中秋节、春节、端午节等节日主题
**结构**8 层布局
- 背景图层AI 生成节日插画
- 纯色遮罩:插画主色调遮罩
- 小插图背景:节日元素插图
- 南开 logo大学标识
- 单位名称:南开大学
- 节日名称:具体节日
- 目的主题:节日祝福语
- 日期元素:当前日期
**模板自动选择逻辑**
- 检测图片描述中的关键词
- 节日关键词 → festival 模板
- 建筑/插画关键词 → illustration 模板
- 默认选择 illustration 模板