Compare commits

..
8 Commits
Author SHA1 Message Date
3218485270 b7f429db89 模板导出增强 + 模特性别分组 + 三合一提示词精简
1) 模板导出:识别「基码表-胸围」填 sku.bust(多个胸围列都填);申报价格模糊匹配多列统一按加价后价格填写;详情图文不再拼接 img_url_2;SPU 款式来源统一填「现货款」;商品产地国家简称映射(沙特→沙特阿拉伯)
2) 模特性别分组:model_features 按男女分组,按模板类目含男/女固定取对应性别模特(含 Pinterest 模式 pipeline)
3) 三合一提示词:去掉 DESIGN CONTENT 四要素描述(设计已由设计稿提供)
4) 生图尺寸:全部改为读 config 不再硬编码(设计图 compose.design_size / 合成图 compose.size / 种草图 seed_shot.size)
2026-08-26 18:05:11 +08:00
3218485270 e317547b8b 修复 Pinterest 分析节点:1) openai 后端兼容 LLM 返回裸数组([...])而非 {designs:[...]},避免 'list' object has no attribute 'get' 崩溃;2) mock 兜底改为真正调用 mock 后端,不再重复调失败的 openai 后端 2026-08-24 15:50:01 +08:00
3218485270 ca567ae198 修复 Pinterest 爬取全部失败:1) 共享 .chrome_session 登录态下 Chrome 单例,并发启动互相抢占导致 browser has been closed,并发强制为 1;2) 系统代理 6696 是 SOCKS5,之前按 HTTP 代理传给 Chrome 导致 ERR_CONNECTION_CLOSED,新增代理类型探测返回 socks5:// scheme;3) 爬取前一次性校验代理,失效时给出明确警告 2026-08-24 15:44:50 +08:00
3218485270 4f3cd52a40 修复「采集热点」长时间无响应:Google Trends 不可达/限流时快速回退缓存(连通性探测+逐词抓取时间预算+收紧超时),避免 24 个种子词干等 10 分钟 2026-08-24 15:32:23 +08:00
3218485270 646c8fa258 打包流程:新增一键打包脚本(不跑自检),打包时复制当前 Chrome 登录态到 dist;spec 内置 Playwright 驱动与 pinterest_scraper;冻结态会话目录指向 exe 同目录 2026-08-24 15:17:48 +08:00
3218485270 309d4a520c 新增 Pinterest 参考模式:独立于 Google Trends 的完整链路(12国种子词池 / LLM搜索词json_schema+防重复+已用词限100 / 并发爬图 / 多模态分析→原创简报 / 生图带爬取图参考图生图 / UI流程选择) 2026-08-24 15:02:01 +08:00
3218485270 2144c36e60 fetch 改为先抓取后回退缓存:成功采集就不用旧缓存,抓取失败才回退 collected_keywords.json 2026-08-24 14:07:03 +08:00
3218485270 3c341d2e78 修复种草图生成:以三合一主图为参考 img2img 生成,按颜色分配(每色优先、超出随机补足);新增 BR/CA/DE/ES/IT/PL/SA 七国配置与提示词;删除验证用测试脚本 2026-08-24 14:02:19 +08:00
142 changed files with 7444 additions and 908 deletions
+4
View File
@@ -1,4 +1,5 @@
# 构建产物
dist/
dist_*/
build*/
build_clean*/
@@ -17,6 +18,9 @@ logs/
# 缓存(可重新采集/生成)
.cache/
# Pinterest 登录态(首次手动登录后缓存,不入库)
pinterest_scraper/.chrome_session/
# 系统
.DS_Store
Thumbs.db
+16 -3
View File
@@ -4,12 +4,25 @@
a = Analysis(
['ui_app.py'],
pathex=[],
binaries=[],
# 显式指定 conda 的 OpenSSL DLL3.5.6,与 _ssl.pyd 匹配)。
# 若不指定,PyInstaller 会从 PATH 找到 MySQL Server 8.0 自带的 OpenSSL 3.0.15
# 导致 _ssl 加载失败:DLL load failed while importing _ssl。
binaries=[
('C:\\Users\\Admin\\miniconda3\\Library\\bin\\libssl-3-x64.dll', '.'),
('C:\\Users\\Admin\\miniconda3\\Library\\bin\\libcrypto-3-x64.dll', '.'),
],
datas=[('config.yaml', '.'), ('configs', 'configs'), ('prompts', 'prompts'),
('templates', 'templates'), ('basemap', 'basemap'),
('material_library', 'material_library')],
('material_library', 'material_library'),
# Playwright 驱动(Node.js driver):Pinterest 爬取用 playwright 控制系统 Chrome。
# 冻结后 _driver.py 按 inspect.getfile(playwright)/driver 定位,必须放 playwright/driver。
('C:\\Users\\Admin\\Desktop\\test模版\\design_agent\\pod_trend_agent\\.venv\\Lib\\site-packages\\playwright\\driver', 'playwright/driver')],
# 注意:db/ 不打进 exe —— 运行时常读 exe 旁 db/spu_sku.db(用户可随时替换取最新)
hiddenimports=['pytrends', 'pytrends.request', 'PIL', 'openpyxl'],
hiddenimports=['pytrends', 'pytrends.request', 'PIL', 'openpyxl',
# Pinterest 参考模式:scraper 包 + playwright + 异步下载依赖
'pinterest_scraper', 'pinterest_scraper.scraper',
'pinterest_scraper.pinterest_image_capture',
'playwright', 'playwright.async_api', 'aiohttp', 'aiofiles'],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 424 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 619 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 403 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 578 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 970 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 799 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 172 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 499 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 59 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 152 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

+68 -31
View File
@@ -1,12 +1,19 @@
# ===== POD 热点抓取 Agent 配置(LangGraph 工程化版)=====
# 目标国家(Google Trends 地区代码:US / GB / JP / AU / MX ...
# 目标国家(Google Trends 地区代码:US / GB / JP / AU / MX / DE / BR / SA / PL / ES / IT / CA ...
countries:
- US
- GB
- JP
- AU
- MX
- DE
- BR
- SA
- PL
- ES
- IT
- CA
# —— 可插拔数据源 ——
# 在 graph/sources/ 注册表里登记;这里列出要启用的。
@@ -22,20 +29,32 @@ sources:
# static: 仅用 yaml 写死种子,零动态(保留兼容,UI 未列出)。
seed_provider: mock
seed_provider_cfg:
max_style_seeds: 12 # style 种子总数上限(动态分配:固定种子优先 → 节日/月份主题 → 动态补位
max_related_seeds: 12 # related 种子总数上限(同上)
max_seeds: 24 # 种子总数上限(不再按类型分:从全部种子词统一池随机抽取,均分 style/related
trending_context_limit: 15
history_limit: 20
# —— Pinterest(官方 API v5,可选;默认关闭)——
# —— Pinterest 参考模式(独立于 Google Trends 采集,UI「Pinterest 参考模式」入口)——
# 流程:各国独立种子词池(configs/pinterest/<CC>.yaml) → LLM 按需生成搜索词(json_schema+防重复)
# → 爬图 → LLM 分析图片 → 构造提示词 → 生成设计
# 按需搜索:每次只生成 1 个搜索词,用完(爬取成功)才标记已用;简报不足时循环再搜,直到满足 SPU 数量。
pinterest:
enabled: false
access_token: "" # 填 Bearer Token,或用环境变量 PINTEREST_ACCESS_TOKEN
search_keywords:
- "trending fashion"
- "streetwear"
- "cottagecore"
page_size: 25
enabled: true
provider: openai # 搜索词/图片分析用 LLM 提供商(openai / mock
search_mode: direct # 搜索词生成方式:direct=跳过LLM,直接搜「种子词 t-shirt design」;llm=LLM按需生成搜索词
search_terms_per_run: 1 # 每次搜索词数量(direct 模式=从种子池随机取 N 个直接拼后缀;llm 模式=每次生成 1 个)
max_search_rounds: 0 # 搜索轮次上限(0=自动:目标 SPU 数×2,至少 5;防网络故障无限循环)
seed_sample: 40 # 每次从国家种子池随机抽取多少个种子词给 LLM
max_used_terms_in_prompt: 100 # 已用搜索词最多注入 LLM 提示词的个数(防 token 超限)
images_per_term: 40 # 每个搜索词爬取图片数量
analyze_per_term: 1 # 每次调用分析 1 张图(一张对应一个设计,一次 API 请求;简报带 image_index 全局 id 校验防错位)
analyze_concurrency: 6 # 并发分析线程数(多并发提取简报)
analyze_batch: 0 # 每轮从图池取多少张图分析(0=自动:一次补齐到目标所需/每词简报上限,让 pipeline 队列时刻满并发)
max_designs: 10 # 每个搜索词最多生成多少个设计简报
ref_images_per_design: 1 # 生图时每个设计附带几张爬取图作为参考(发给生图模型)
supply_attempts: 3 # 设计生成失败/侵权时,从图池取新图重新分析的最多尝试次数
err400_limit: 15 # 每个种子词累计 400(且错误含「内容/图片」)超限后放弃该种子词(多模态+生图合计)
scrape_concurrency: 1 # 同时爬取几个搜索词(共享 .chrome_session 登录态,Chrome 单例,必须=1)
headless: false # 爬取时是否无头(false=显示 Chrome 窗口,首次需手动登录)
# 跨源融合权重(按 source 标签,无需和为 1)
# 已下调 gt_trending(泛国家热点只作微弱信号),主力偏向 style+related(可印花型词)。
@@ -86,20 +105,21 @@ query_noise:
llm_screen:
enabled: true
provider: openai # openai(真 LLM,需 key/ mock(无 key 启发式兜底)
api_key: "sk-ws-H.EPXPIER.vRMT.MEUCIQDji_AHGl-EekYOftdLxEvFl2ZqCNtLDSp3Bqnaz0SRpgIgI4qPeVyIMMzutl9JakuYRv3zmFxkwc12c4aBcIL1gqE" # 留空则自动读取环境变量 LLM_API_KEY / OPENAI_API_KEY(推荐,避免密钥入库)
base_url: "https://ws-5rfjflubus647o7t.cn-beijing.maas.aliyuncs.com/compatible-mode/v1" # 自定义网关地址,也可用环境变量 LLM_BASE_URL 覆盖
model: "qwen3.7-max-preview" # 自定义模型名(任意 OpenAI 兼容模型)
api_key: "ark-607f7194-f253-4c55-a421-237317d7683e-2bf08" # 留空则自动读取环境变量 LLM_API_KEY / OPENAI_API_KEY(推荐,避免密钥入库)
base_url: "https://ark.cn-beijing.volces.com/api/v3" # 自定义网关地址,也可用环境变量 LLM_BASE_URL 覆盖
model: "doubao-seed-2-0-lite-260215" # 自定义模型名(任意 OpenAI 兼容模型)
temperature: 0.6
max_topics_per_call: 12
min_score: 0.0
keep_review: false # false = 待复核(review)直接过滤、不生成设计提示词,只留 safe
max_briefs: 0 # 简报数量上限(0=自动:按扩展后总任务数/SPU数,用多少生成多少)
# —— 固定提示词模板(规则写死,保证每条一致)——
# 由 motif + art_style + color_palette + composition 四要素按模板确定性拼出。
# v3countries.<CODE> 按国家覆盖 image_prompt(每国设计风格不同),顶层为兜底。
# 文字规则统一:英文可加可不加、适配印花即可;任何文字严禁政治/宗教/仇恨/暴力/性/品牌/商标/真实人物等敏感内容。
prompt_templates:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, US-market aesthetic: bold confident statement graphic, high contrast, clean modern vector, sporty or humorous mood, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a small slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, US-market aesthetic: bold confident statement graphic, high contrast, clean modern vector, sporty or humorous mood, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a small slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
wearable_prompt: "{motif}, {art_style}, {color_palette}, {composition}, printed centered on the chest of a flat-lay plain white t-shirt, print sized freely between about 15x18 cm and a max of 26x32 cm, scaled naturally to the artwork, not stretched, not full-bleed, studio lighting, e-commerce product photo, no human model"
composite_prompt: "【图片角色,按提交顺序】图1=模特实拍图(基底);图2=纯印花设计稿;图3=平铺衣服底图(只取衣服本身的底色与面料材质,忽略平铺图背景/桌面/场景,只保留面料颜色与质感)。
TASK: 把图2的印花设计印到图3底色的衣服上,并让图1的模特穿上“图3底色+图2印花”的衣服。
@@ -108,20 +128,33 @@ RULES:/n1.底色锁定:从图3提取衣服底色与面料,最终合成中必须1
3.主体遮罩:识别图1模特服装穿着区域(忽略皮肤/头发/背景/配饰),用合成面料完整覆盖,清除原衣服颜色与图案。
4.精准贴合:合成面料严格跟随图1衣服立体结构,褶皱/扭转处印花相应变形,杜绝“贴纸感”与“平面涂色感”。
5.光影融合:按图1环境光方向调整亮度/对比度,印花受光影响产生明暗变化但色号不偏移。
6.纯净输出:仅输出一张最终合成图;图1背景/人物/构图/光影100%不变,仅替换衣服印花与底色。
DESIGN CONTENT: {motif}, {art_style}, {color_palette}, {composition}."
6.纯净输出:仅输出一张最终合成图;图1背景/人物/构图/光影100%不变,仅替换衣服印花与底色。"
composite_negative: "garment changed, wrong color, distorted print, blurry, low-res, human model, body, extra objects, watermark, glow, 3d render, text unless part of design"
countries:
US:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, US-market aesthetic: bold confident statement graphic, high contrast, clean modern vector, sporty or humorous mood, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a small slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, US-market aesthetic: bold confident statement graphic, high contrast, clean modern vector, sporty or humorous mood, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a small slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
GB:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, UK-market aesthetic: witty understated British charm, heritage-inspired motifs, retro sportswear or punk-zine mood, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a small slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, UK-market aesthetic: witty understated British charm, heritage-inspired motifs, retro sportswear or punk-zine mood, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a small slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
JP:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, JP-market aesthetic: kawaii cute or clean minimal, soft pastel-friendly, polished neat lines, small cute mascot mood, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a small slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, JP-market aesthetic: kawaii cute or clean minimal, soft pastel-friendly, polished neat lines, small cute mascot mood, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a small slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
AU:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, AU-market aesthetic: laid-back coastal and outdoor vibe, nature-inspired, bright fresh energy, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a small slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, AU-market aesthetic: laid-back coastal and outdoor vibe, nature-inspired, bright fresh energy, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a small slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
MX:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, MX-market aesthetic: vibrant mexican folk art, sugar skull / loteria / aztec motifs, fiesta colors, festive cultural pride mood, size: choose freely between a MINIMUM print area of about 15x18 cm and a MAXIMUM of 26x32 cm, any size in this range fits, pick the one that best suits the design, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave balanced margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a Spanish slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, MX-market aesthetic: vibrant mexican folk art, sugar skull / loteria / aztec motifs, fiesta colors, festive cultural pride mood, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a Spanish slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
DE:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, DE-market aesthetic: bavarian-alpine folk charm, berlin street-art edge, bauhaus minimalism, cozy beer-garden and christmas-market mood, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a German slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
BR:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, BR-market aesthetic: vibrant tropical carnival energy, samba rhythm, football passion, bold beach and street-art colors, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a Portuguese slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
SA:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, SA-market aesthetic: elegant desert minimalism, arabian geometric patterns, falconry and starry-night calm, refined and conservative mood, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or an Arabic slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
PL:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, PL-market aesthetic: highland folk embroidery charm, wycinanki paper-cut patterns, slavic forest mystique, retro polish poster mood, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a Polish slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
ES:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, ES-market aesthetic: flamenco passion, andalusian tile patterns, mediterranean sunshine, festive fiesta energy, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a Spanish slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
IT:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, IT-market aesthetic: renaissance elegance, roman heritage, tuscan countryside warmth, la dolce vita retro charm, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or an Italian slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
CA:
image_prompt: "{motif}, {art_style}, {color_palette}, {composition}, standalone pure print design, print-ready artwork, isolated on pure white background, no background, no scene, no texture, no frame, no border, flat vector-like graphic, crisp clean edges, high resolution, ultra sharp, high contrast, CA-market aesthetic: maple-leaf pride, northern-lights wonder, rocky-mountain outdoors, cozy cottage and hockey spirit, size: the print artwork must be SMALL and CENTERED with clearly larger white margins around it, print area between about 15x18 cm and 26x32 cm, keep proportions, scale naturally to the content, do NOT stretch, do NOT fill the entire canvas, do NOT force full-bleed, leave wide balanced white margins around the artwork, no garment, no shirt, no model, no mannequin, no watermark, text: optional - add short original English words or a French slogan ONLY if they fit the print, or keep it text-free; any text must be safe, short and original; no brand names, no logos, no trademarked phrases, no real people names"
# —— 第三阶段 compose:生成纯印花设计稿 + 导出简报包(在 product 之前)——
# 用前 N 个 safe 简报的 image_prompt 调图像后端文生图,产物 output/<country>/designs/
@@ -130,11 +163,14 @@ DESIGN CONTENT: {motif}, {art_style}, {color_palette}, {composition}."
compose:
backend: "openai" # 生成设计稿的图像后端:openai(需 api_key/ mock(占位);留空=不生成
api_key: "sk-ef1f251f059f9c2f8cc397de4a84e96d65775e1f2d32bb13b69b23dafc24d111"
base_url: "https://api.tofastcode.xyz" # 自定义图像网关地址(默认 OpenAI)
base_url: "https://api.tofastcode.xyz" # 自定义图像网关地址(默认 OpenAI)——填 API 根路径(含 /v1),不要带 /images/edits 后缀,否则拼接路径 404
model: "gpt-image-2"
size: "1536×2048"
size: "1536x2048" # 合成图/种草图等非设计图的统一尺寸(3:4)
design_size: "1024x1024" # 纯印花设计稿尺寸(1:1
background: "transparent" # 生成透明背景 PNG(gpt-image 系列支持);留空=默认背景
seed: 0 # 随机种子:>0=固定(相同 seed 可复现,需网关支持);0/留空=每次随机
design_count: 1 # 用前 N 个 safe 简报生成设计稿(product 取第一个复用)
design_workers: 5 # 设计稿并发生成线程数(仅热点采集模式 compose 节点用;Pinterest 模式走 pipeline 总并发 product.concurrency
# —— 第五阶段 oss_upload:压缩(3:4 / ≥1340×1785 / <2MB+ 上传阿里云 OSS 图床 ——
# 产物(composite/printed/design/basemap)逐个压缩上传,URL 写回 *_url 字段。
@@ -146,15 +182,15 @@ oss:
oss_key_secret: "2Q25JohOI4GmovszvIw1NuVvUzM6PB"
enabled: true # false = 跳过上传(本地仅压缩或完全跳过)
# —— 第六阶段 seed_shot:种草图生成(在 oss_upload 之后)——
# 模板:configs/seed_shot_templates.yaml(提示词,占位符 [商品名称]/[材质]/[模特特征],可自定义添加)
# 模特特征:configs/model_features.yaml(随机取一条,可自定义添加
# [商品名称] ← product 的 cn_title[材质] ← db SPU.material[模特特征] ← yaml 随机
# 种草图同样压缩上传 OSS(货号计数与 oss_upload 共用续接)。
# —— 第六阶段 seed_shot:种草图选取(在 oss_upload 之后)——
# 种草图不再用 AI 重新生成,而是从 product 已生成的三合一主图(每颜色一张)中按 count 随机选取:
# - count <= 颜色数:随机取 count 个不同颜色(优先保证每色主图都有一张
# - count > 颜色数:每色一张 + 从全部主图中随机补足(可重复)
# 选取的种草图压缩上传 OSS(货号计数与 oss_upload 共用续接)URL 写入模板「详情图文」列
seed_shot:
enabled: true
count: 1 # 每个产品生成几张种草图(传入数量即可)
size: "1536×2048" # 种草图尺寸(统一读取此配置,不再硬编码
count: 1 # 每个产品选取几张种草图(从三合一主图中随机取,传入数量即可)
size: "1536x2048" # 种草图生成尺寸(3:4,与合成图一致
# —— 第四阶段 product:热点 → SPU/颜色选品 → 底图 → 三图合成(图1模特+图2设计稿+图3底图)→ 模板 ——
# 数据关系:SPU.code=款号,SKU.code="款号-颜色编码"(如 DG004-BL01),
@@ -177,4 +213,5 @@ product:
background: "transparent" # 设计稿透明背景(product 后端生图时也传 background=transparent
template_dir: "templates" # template_router.py 所在目录(项目内自包含)
template_path: "templates/商品上传模版.xlsx" # 商品上传模板(可改为自由上传)
concurrency: 5 # Pinterest 模式 pipeline 总并发(设计生成→三合一→种草图→标题 同一管道串行,总并发=此值)
+82 -23
View File
@@ -1,32 +1,91 @@
# 澳大利亚专属数据源配置
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- summer
- beach
- surf
- vintage
- outback
- coastal
- cat
- dog
- cute animals
- paw prints
- moon and stars
- cozy vibes
- summer
- beach
- surf
- vintage
- outback
- coastal
- cat
- dog
- cute animals
- paw prints
- moon and stars
- cozy vibes
- kangaroo
- koala
- aussie slang
- vegemite
- barbecue
- reef coral
- bush walk
- wattle
- cricket
- footy
- sundowner
- boomerang
- farm life
- seagull
- lamington
- pavlova
- op shop retro
- uluru
- sydney opera house
- sydney harbour bridge
- bondi beach
- great barrier reef
- wombat
- platypus
- echidna
- dingo
- emu
- kookaburra
- cockatoo
- fairy penguin
- sea turtle
- whale shark
- saltwater crocodile
- meat pie
- sausage roll
- fairy bread
- anzac biscuit
- damper
- billy tea
- akubra hat
- afl
- rugby league
- surf lifesaving
- beach cricket
- snorkelling
- sailing
- eucalyptus
- gum tree
- bottlebrush
- waratah
- kangaroo paw
- frangipani
- southern cross
related:
enabled: true
seed_keywords:
- kawaii
- vintage poster
- funny mug
- beach art
- retro travel
- floral
timeframe: "today 3-m"
- kawaii
- vintage poster
- funny mug
- beach art
- retro travel
- floral
- aussie wildlife
- outback art
- retro australia
- surf retro
- coastal art
- australian food
- native plants
- beach retro
- sydney art
- reef art
timeframe: today 3-m
+95
View File
@@ -0,0 +1,95 @@
# 巴西专属数据源配置(configs/countries/BR.yaml
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- tropical
- amazon rainforest
- samba
- carnival
- rio de janeiro
- copacabana
- beach sunset
- surf
- football fan
- jiu jitsu
- capoeira
- parrot
- toucan
- macaw
- jaguar
- sloth
- capybara
- pineapple
- coconut palm
- acai bowl
- caipirinha
- street art
- graffiti
- bossa nova
- forro
- tropical flowers
- hibiscus
- palm trees
- samba dancer
- carnival mask
- confetti
- favela art
- amazon river
- jungle wildlife
- hummingbird
- sunset beach
- brazilian coffee
- brigadeiro
- ipanema
- sugarloaf mountain
- christ the redeemer
- iguaçu falls
- pantanal
- pink river dolphin
- anaconda
- piranha
- blue morpho butterfly
- poison dart frog
- caiman
- pão de queijo
- feijoada
- churrasco
- coxinha
- pastel
- tapioca
- acarajé
- moqueca
- maracujá
- passion fruit
- mango tree
- banana leaf
- monstera
- orchids
- festa junina
- sertanejo
- funk carioca
- pandeiro
- berimbau
related:
enabled: true
seed_keywords:
- tropical vintage
- brazilian street art
- samba pattern
- rio retro
- amazon wildlife
- beach vibes
- brazilian food
- carnival colors
- jungle leaves
- sunset palm
- brazilian wildlife
- rio de janeiro art
- brazilian music
- tropical leaves
- festa junina
- brazilian retro
timeframe: today 3-m
+95
View File
@@ -0,0 +1,95 @@
# 加拿大专属数据源配置(configs/countries/CA.yaml
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- maple leaf
- maple syrup
- moose
- beaver
- polar bear
- northern lights
- aurora borealis
- rocky mountains
- banff
- lake louise
- pine forest
- canoe
- kayak
- camping
- hiking
- snowboarding
- skiing
- hockey
- ice skating
- winter
- snowflake
- log cabin
- poutine
- butter tart
- canadian wildlife
- loon
- whale
- orca
- salmon
- french canada
- quebec
- old quebec
- montreal
- toronto skyline
- cn tower
- vancouver
- pacific coast
- lobster
- fishing
- cottage
- lake life
- fall colors
- autumn leaves
- hockey stick
- ice fishing
- snowmobile
- lumberjack
- plaid
- flannel
- mountie
- snowy owl
- bald eagle
- puffin
- beluga
- narwhal
- caribou
- muskox
- arctic fox
- niagara falls
- jasper
- moraine lake
- whistler
- tofino
- vancouver island
- st lawrence river
- sugar shack
- maple taffy
- curling
related:
enabled: true
seed_keywords:
- canadian wildlife
- northern lights
- maple leaf
- rocky mountains
- cottage country
- winter sports
- canadian retro
- french canada
- autumn leaves
- lake life
- canadian birds
- winter wonderland
- canadian food
- mountain lakes
- east coast art
- maple syrup art
timeframe: today 3-m
+95
View File
@@ -0,0 +1,95 @@
# 德国专属数据源配置(configs/countries/DE.yaml
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- lederhosen
- bavarian
- alpine
- black forest
- cuckoo clock
- pretzel
- german beer
- bratwurst
- sauerkraut
- berlin street art
- bauhaus
- industrial minimal
- german typography
- gothic
- medieval castle
- neuschwanstein
- viking
- nordic
- forest hiking
- mountain lake
- cycling
- football fan
- christmas market
- stollen
- dirndl
- edelweiss
- techno music
- berlin wall
- east berlin retro
- trabi car
- ampelmann
- german shepherd
- schnauzer
- wild boar
- red fox
- autumn forest
- river rhine
- harbor lighthouse
- stork
- bavarian alps
- zugspitze
- beer garden
- weisswurst
- currywurst
- schnitzel
- spätzle
- apfelstrudel
- black forest cake
- marzipan
- lebkuchen
- glühwein
- nutcracker
- brandenburg gate
- fernsehturm
- cologne cathedral
- hamburg harbor
- heidelberg castle
- romantic road
- dachshund
- great dane
- deer stag
- lynx
- wolf
- black eagle
- fraktur
- german expressionism
- krautrock
- oompah band
related:
enabled: true
seed_keywords:
- bavarian pattern
- alpine vintage
- german humor
- berlin retro
- retro gdr
- nordic minimal
- german food
- mountain hiking
- medieval knight
- christmas market
- german wildlife
- bavarian alps
- berlin art
- german castle
- autobahn retro
- beer garden
timeframe: today 3-m
+95
View File
@@ -0,0 +1,95 @@
# 西班牙专属数据源配置(configs/countries/ES.yaml
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- flamenco
- flamenco dress
- andalusia
- seville
- azulejo
- spanish tile
- gaudi
- barcelona
- sagrada familia
- tapas
- paella
- jamon
- olive
- olive tree
- bull
- castanets
- spanish guitar
- siesta
- fiesta
- tomato festival
- carnival
- valencia
- mediterranean
- costa brava
- ibiza
- flamenco dancer
- mantilla
- hand fan
- moorish
- alhambra
- gothic
- renaissance
- sangria
- churros
- siesta cat
- mediterranean coast
- spanish villa
- orange tree
- bullring
- sevillanas
- granada
- cordoba
- ronda
- white villages
- park guell
- casa batllo
- las ramblas
- tortilla espanola
- patatas bravas
- croquetas
- gazpacho
- salmorejo
- pulpo
- calamares
- manchego
- chorizo
- empanada
- turron
- polvorones
- iberian lynx
- spanish ibex
- flamingo
- imperial eagle
- griffon vulture
- sunflower fields
- almond blossom
- olive grove
- vineyard
related:
enabled: true
seed_keywords:
- spanish tile pattern
- flamenco art
- mediterranean vibes
- andalusian pattern
- spanish food
- gaudi style
- costa del sol
- spanish retro
- olive branch
- fiesta colors
- spanish wildlife
- mediterranean coast art
- spanish architecture
- tapas art
- iberian nature
- spanish vintage
timeframe: today 3-m
+82 -23
View File
@@ -1,32 +1,91 @@
# 英国专属数据源配置
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- british humor
- punk
- vintage
- cottagecore
- retro
- gothic
- cat
- dog
- cute animals
- paw prints
- moon and stars
- cozy vibes
- british humor
- punk
- vintage
- cottagecore
- retro
- gothic
- cat
- dog
- cute animals
- paw prints
- moon and stars
- cozy vibes
- heritage
- london skyline
- britpop
- mod style
- tea time
- pub sign
- coastal britain
- canal narrowboat
- classic british cars
- seaside pier
- english garden
- countryside walk
- tartan plaid
- victorian pattern
- fish and chips
- rainy day humor
- morris dancing
- big ben
- tower bridge
- red double decker bus
- london taxi
- queen's guard
- buckingham palace
- stonehenge
- scottish highlands
- loch ness
- edinburgh castle
- welsh dragon
- afternoon tea
- scones
- full english breakfast
- sunday roast
- yorkshire pudding
- bangers and mash
- shepherd's pie
- thatched cottage
- country pub
- rose garden
- lavender field
- corgi
- bulldog
- robin
- red squirrel
- hedgehog
- badger
- white cliffs of dover
- lake district
- cotswolds
- cornwall coast
- bonfire night
- fireworks
- christmas pudding
- red telephone box
related:
enabled: true
seed_keywords:
- kawaii
- vintage uk
- funny names
- skull head
- england retro
- retro shirt
timeframe: "today 3-m"
- kawaii
- vintage uk
- funny names
- skull head
- england retro
- retro shirt
- british wildlife
- london retro
- union jack pattern
- english garden art
- seaside retro
- pub sign art
- royal heritage
- countryside art
- britpop retro
- tea time art
timeframe: today 3-m
+95
View File
@@ -0,0 +1,95 @@
# 意大利专属数据源配置(configs/countries/IT.yaml
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- italian renaissance
- rome
- colosseum
- venice
- gondola
- canals
- tuscany
- tuscan hills
- cypress
- sunflower
- pizza
- pasta
- spaghetti
- espresso
- italian coffee
- gelato
- tiramisu
- limoncello
- amalfi coast
- lemon
- lemon tree
- vesuvius
- pompeii
- la dolce vita
- italian sports car
- opera
- venetian mask
- carnival of venice
- italian mosaic
- roman mosaic
- gladiator
- roman soldier
- laurel wreath
- olive branch
- mediterranean
- italian riviera
- portofino
- sicily
- trulli
- leaning tower
- florence
- italian typography
- vintage italy
- retro italian
- pantheon
- trevi fountain
- spanish steps
- roman forum
- aqueduct
- centurion
- st mark's square
- rialto bridge
- murano glass
- burano
- chianti
- san gimignano
- siena
- val d'orcia
- lasagna
- ravioli
- tortellini
- risotto
- carbonara
- pesto
- mozzarella
- burrata
- prosciutto
- panettone
related:
enabled: true
seed_keywords:
- italian vintage
- venetian mask
- tuscan countryside
- italian food
- roman empire
- mediterranean coast
- renaissance art
- espresso culture
- italian retro
- amalfi coast
- italian wildlife
- italian architecture
- dolce vita art
- italian wine
- mediterranean art
- italian design
timeframe: today 3-m
+83 -23
View File
@@ -1,32 +1,92 @@
# 日本专属数据源配置
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- kawaii
- anime
- japanese aesthetic
- kanji
- vaporwave
- gyaru
- cat
- dog
- cute animals
- paw prints
- moon and stars
- cozy vibes
- kawaii
- anime
- japanese aesthetic
- kanji
- vaporwave
- gyaru
- cat
- dog
- cute animals
- paw prints
- moon and stars
- cozy vibes
- shiba inu
- sakura
- ukiyo e
- torii gate
- maneki neko
- daruma
- koi fish
- bonsai
- origami
- ramen
- sushi
- matcha
- zen minimal
- japanese calligraphy
- yokai
- festival matsuri
- tanuki
- onsen
- mount fuji
- bullet train
- japanese garden
- bamboo forest
- momiji
- kimono
- yukata
- samurai
- ninja
- geisha
- kabuki
- sumo
- karate
- tempura
- okonomiyaki
- takoyaki
- udon
- mochi
- taiyaki
- green tea
- wagashi
- akita
- red-crowned crane
- kitsune
- kappa
- sumi-e
- manga
- chibi
- harajuku
- pagoda
- kinkakuji
- himeji castle
- tokyo skyline
- shibuya crossing
- hanami
- fireworks hanabi
related:
enabled: true
seed_keywords:
- kawaii sticker
- vintage poster
- cute cat
- anime tee
- minimalist art
- floral
timeframe: "today 3-m"
- kawaii sticker
- vintage poster
- cute cat
- anime tee
- minimalist art
- floral
- japanese retro
- ukiyo e art
- japanese food
- zen art
- sakura art
- japanese wildlife
- torii gate art
- manga art
- japanese pattern
- retro japan
timeframe: today 3-m
+83 -25
View File
@@ -1,34 +1,92 @@
# 墨西哥专属数据源配置
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- day of the dead
- calavera
- sugar skull
- loteria
- aztec pattern
- lucha libre
- mariachi
- mexican folk art
- chicano
- cactus
- day of the dead
- calavera
- sugar skull
- loteria
- aztec pattern
- lucha libre
- mariachi
- mexican folk art
- chicano
- cactus
- alebrije
- papel picado
- talavera
- agave
- fiesta
- sombrero
- folk embroidery
- huarache
- quetzal
- maracas
- charro
- mexican flowers
- colorful birds
- mercado
- catrina
- marigold
- cempasuchil
- ofrenda
- pan de muerto
- aztec calendar
- mayan pyramid
- chichen itza
- teotihuacan
- quetzalcoatl
- jaguar
- feathered serpent
- luchador
- wrestling mask
- serape
- poncho
- rebozo
- taco
- burrito
- enchilada
- quesadilla
- tamale
- pozole
- mole
- elote
- churro
- concha
- horchata
- nopal
- saguaro
- prickly pear
- pitaya
- avocado
- guacamole
- otomi pattern
- huichol art
- axolotl
- xoloitzcuintli
- monarch butterfly
- iguana
- hummingbird
- sea turtle
related:
enabled: true
seed_keywords:
- catrina
- dia de los muertos
- mexican food
- taco
- avocado
- sombrero
- aguila mexicana
- aztec calendar
- alebrijes
- lowrider
timeframe: "today 3-m"
- catrina
- dia de los muertos
- mexican food
- taco
- avocado
- sombrero
- aguila mexicana
- aztec calendar
- alebrijes
- lowrider
- mexican wildlife
- mexican art
- day of the dead art
- mexican retro
- aztec art
- mexican nature
timeframe: today 3-m
+95
View File
@@ -0,0 +1,95 @@
# 波兰专属数据源配置(configs/countries/PL.yaml
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- highland folklore
- podhale
- goral
- folk embroidery
- wycinanki
- paper cutout
- amber
- european bison
- white eagle
- forest
- lake
- mazury
- baltic sea
- seagull
- pierogi
- oscypek
- tatra mountains
- mountain hiking
- medieval castle
- knight
- slavic mythology
- wawel dragon
- krakow old town
- retro poland
- polish poster
- typography
- mushroom
- wildflowers
- cornflower
- folk pattern
- embroidery pattern
- christmas eve
- gingerbread
- stork
- wolf
- elk
- river vistula
- old town square
- amber jewelry
- folk dance
- zakopane
- highland hut
- sheep
- bryndza
- krakowiak
- polonaise
- mazurka
- boleslawiec pottery
- sea glass
- wisent
- moose
- brown bear
- lynx
- wild boar
- hare
- beaver
- swan
- crane
- kingfisher
- bigos
- żurek
- gołąbki
- kotlet schabowy
- sernik
- makowiec
- paczki
- toruń gingerbread
- kielbasa
related:
enabled: true
seed_keywords:
- polish folk art
- highland pattern
- slavic retro
- amber jewelry
- tatra mountains
- polish food
- folk embroidery
- medieval knight
- baltic coast
- forest wildlife
- polish wildlife
- slavic mythology art
- zakopane style
- baltic amber
- polish retro
- folk pattern art
timeframe: today 3-m
+96
View File
@@ -0,0 +1,96 @@
# 沙特阿拉伯专属数据源配置(configs/countries/SA.yaml
# 保守市场:避免宗教符号/人物形象/酒精/猪/国旗国徽/王室;主打自然、几何、文化氛围。
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- desert
- sand dunes
- camel
- arabian horse
- falcon
- arabic calligraphy
- geometric pattern
- palm tree
- date palm
- oasis
- oud
- arabic coffee
- dates
- bedouin tent
- starry desert night
- red sea
- coral reef
- scuba diving
- riyadh skyline
- futuristic city
- desert fox
- arabian oryx
- gazelle
- falconry
- incense
- henna pattern
- arabic lantern
- arabian nights
- mosaic
- desert rose
- sand art
- dune buggy
- desert sunset
- camel caravan
- star map
- astronomy
- constellation
- desert wildflowers
- alula
- hegra
- edge of the world
- diriyah
- jeddah corniche
- neom
- arabesque
- islamic geometry
- zellige
- mashrabiya
- horseshoe arch
- gahwa
- cardamom
- saffron
- rose water
- mint tea
- kunafa
- baklava
- luqaimat
- kabsa
- shawarma
- falafel
- hummus
- bakhoor
- amber
- jasmine
- flying carpet
- magic lamp
- spice market
- sand cat
related:
enabled: true
seed_keywords:
- arabic geometric
- desert sunset
- camel silhouette
- arabian horse
- falcon art
- henna pattern
- arabic lantern
- oasis palm
- red sea coral
- starry desert
- saudi wildlife
- arabic coffee
- desert art
- red sea life
- arabian nights art
- traditional pattern
timeframe: today 3-m
+83 -26
View File
@@ -1,35 +1,92 @@
# 美国专属数据源配置(覆盖全局默认)
# 种子词已换成短而热门、且贴近 POD 的词,related_queries 才能返回数据。
trending:
enabled: true
limit: 40
style:
enabled: true
seeds:
- vintage
- retro
- funny
- aesthetic
- cottagecore
- grunge
- streetwear
- punk
- cat
- dog
- cute animals
- paw prints
- moon and stars
- cozy vibes
- vintage
- retro
- funny
- aesthetic
- cottagecore
- grunge
- streetwear
- punk
- cat
- dog
- cute animals
- paw prints
- moon and stars
- cozy vibes
- western cowboy
- coastal cowgirl
- y2k
- retro gaming
- psychedelic
- tie dye
- 90s nostalgia
- minimalist typography
- hand drawn doodle
- botanical line art
- mountain adventure
- camping outdoors
- space astronomy
- astrology zodiac
- surf beach
- art deco
- national parks
- vintage racing
- skater culture
- boho
- bald eagle
- american bison
- grizzly bear
- raccoon
- blue jay
- route 66
- grand canyon
- yellowstone
- new york skyline
- las vegas neon
- cowboy boots
- rodeo
- sheriff star
- wild west saloon
- covered wagon
- baseball
- basketball
- american football
- hot dog
- burger
- apple pie
- retro diner
- neon sign
- road trip
- camper van
- muscle car
- rock and roll
- jazz blues
- country music
- vinyl record
- thanksgiving turkey
- pumpkin patch
related:
enabled: true
seed_keywords:
- kawaii
- vintage poster
- funny mug
- anime tee
- retro band tee
- skull art
timeframe: "today 3-m"
- kawaii
- vintage poster
- funny mug
- anime tee
- retro band tee
- skull art
- american retro
- national park art
- western art
- vintage travel
- retro sports
- diner sign
- american wildlife
- stars and stripes
- road trip art
- coastal retro
timeframe: today 3-m
+74 -55
View File
@@ -1,56 +1,75 @@
# 模特特征库 —— 可自定义添加(一行一条,种草图提示词 [模特特征] 随机取用
# 示例:
# - "20岁清新少女,素颜通透感"
# - "25岁都市职场女性,干练气质"
# 模特特征库 —— 跨境电商基础款服装展示专用(已剔除外部穿搭与夸张妆造干扰
# 占位符:[模特特征] 随机取用
# 注意:所有特征仅描述长相、肤质、气质,不含外套或多余服装。
# 按性别分组:female=女模 / male=男模。
# 商品类目(模版「类目」表头值)含「男」→ 固定从 male 随机;含「女」→ 固定从 female 随机;都不含 → 全部随机。
model_features:
- "20岁欧美甜心,金发碧眼,阳光加州感"
- "25岁法国左岸文青,法式刘海,慵懒红唇"
- "28岁意大利名媛,复古波浪卷,精致上扬眼线"
- "22岁纽约下城区酷女孩,挑染发色,厌世烟熏妆"
- "30岁北欧极简风女,冷白皮,无瑕光泽肌"
- "24岁拉美热情系女生,小麦色肌肤,野生挑眉"
- "26岁法国时尚博主,法式码头上衣,碎发自然感"
- "29岁英伦中性风女模,深色短寸,骨感清冷"
- "21岁俄罗斯芭蕾少女,深邃眼窝,通透纯欲妆"
- "25岁巴西超模脸,高颧骨,健康古铜色肌肤"
- "33岁美式大女主气场,利落大波浪,深色红唇"
- "22岁Y2K千禧辣妹,银色眼影,浅色唇彩"
- "28岁美式复古Pin-up女孩, Victory卷发,饱满红唇"
- "24岁欧美高级中性模,凌乱短发,苍白质肌肤"
- "20岁加州冲浪系男孩,阳光金发,麦色健康肌"
- "25岁英伦雅痞型男,复古油头,短胡茬,熟男气质"
- "28岁意大利型男,深邃五官,意式凌乱卷发"
- "22岁纽约街头滑板男孩,脏辫,宽松街头风"
- "30岁华尔街商务精英,背头,沉稳内敛气质"
- "26岁日系盐系清冷男模,单眼皮,清瘦骨感"
- "24岁欧美健身教练型男,肌肉线条分明,小麦色肌肤"
- "29岁柏林暗黑系青年,苍白皮肤,银色配饰,冷感打底"
- "21岁英伦贵族少爷,金丝眼镜,白皙皮肤,忧郁气质"
- "27型美式机车硬汉,粗犷轮廓,络腮胡,硬挺气质"
- "23岁东欧赛博朋克风骇客,机械感配饰,冷感眼妆"
- "32岁法式儒雅大叔,微卷发,眼镜,温润如玉气质"
- "25岁欧美高冷男模,银白发色,苍白冷白皮"
- "22岁俄裔冷酷超模,高颧骨,锋利眼神"
- "26岁拉美混血风男模,深邃眼窝,健康小麦色"
- "28岁纽约高街潮流主理人,oversize穿搭,厌世脸"
- "20岁荷兰清新少女,雀斑,通透素颜"
- "28岁北欧美人鱼风,长发及腰,冷感通透妆"
- "24岁巴黎左岸文艺女青年,条纹衫气质,伪素颜"
- "29岁米兰奢华贵妇,戴墨镜,精致法式美甲"
- "21岁加州 Coachella 音乐节女孩,波西米亚编发,晒伤妆"
- "27岁东欧废土风流浪者,做旧皮革质感,沧桑眼神"
- "23岁巴西里约热内卢狂欢女孩,羽毛头饰,高饱和妆容"
- "31岁哥本哈根极简风设计师,利落短发,黑白灰穿搭"
- "25岁美式复古绅士,圆框眼镜,马甲三件套"
- "22岁迈阿密热辣女孩,大波浪,高光立体修容妆"
- "26岁巴黎先锋艺术系青年,高领毛衣,单边耳坠"
- "32岁意式慵懒波西米亚女性,大波浪,流苏配饰"
- "25岁柏林冷酷电子乐DJ,全黑穿搭,荧光眼线"
- "20岁美式青春啦啦队队长,马尾,元气通透妆"
- "28岁伦敦复古古着店主理人,复古丝绒材质,红棕唇"
- "24岁北欧极简主义建筑系学生,眼镜,素雅气质"
- "29岁好莱坞黄金时代复古女星,手推波浪卷,红唇"
- "21岁加拿大户外徒步青年,冲锋衣,健康小麦色"
- "33岁法式波尔多酒庄主理人,优雅气质,微醺红唇"
- "26岁纽约苏荷区独立摄影师,工装背带裤,随性素颜"
- "30岁北欧性冷淡风艺术家,银色短发,疏离眼神"
female:
# ========== 女模 - 亚洲/清新/通勤类(适合基础款、纯色T恤) ==========
- "22岁亚洲清新女学生,通透伪素颜,黑直发,清瘦骨感"
- "25岁日韩系通勤女模,元气通透底妆,棕色微卷发,亲切感"
- "27岁亚洲极简风女,冷白皮,无瑕光泽肌,利落黑色短发"
- "29岁亚洲轻熟女模,骨相美,微雾感底妆,气质温婉"
# ========== 女模 - 欧美/阳光/甜心类(适合印花T恤、度假风) ==========
- "20岁欧美甜心女模,金发碧眼,阳光加州感,健康小麦色肌肤"
- "23岁法式慵懒女模,法式刘海,微卷棕发,通透红唇"
- "27岁欧美自然系女模,淡雀斑,大地色系淡妆,健康好气色" # 新增
- "21岁迈阿密热辣女孩,金棕色大波浪,高光立体修容,健康古铜色肌肤"
- "24岁北美学院风女模,高马尾,通透元气妆,白皙肌肤"
- "34岁北美宝妈系女模,自然淡妆,栗色长发,亲切温暖的微笑" # 新增
# ========== 女模 - 欧美/街头/个性类(适合街头风、美式复古印花) ==========
- "22岁纽约下城区酷女孩,挑染发色,清冷厌世感,苍白质肌肤"
- "28岁欧美高级中性模,凌乱短发,冷白皮,骨感清冷"
- "26岁拉美混血风女模,深邃眼窝,野生挑眉,健康小麦色肌肤"
- "25岁Y2K千禧辣妹,银色挑染发,清透裸妆,微胖立体感"
# ========== 女模 - 极简/性冷淡/高街类(适合纯色基础款、卫衣) ==========
- "30岁北欧极简风女模,冷白皮,无瑕哑光肌,银色利落短发"
- "29岁纽约高街潮流女模,冷感通透妆,深棕色直发,疏离眼神"
- "31岁哥本哈根极简风设计师女模,利落黑色短发,黑白灰冷感气质"
- "28岁法式先锋艺术系女模,单边耳坠,冷感素颜,深金色发"
# ========== 女模 - 多元族裔类(适合多站点覆盖:北美/欧洲站必备) ========== # 新增分组
- "26岁非裔自然卷女模,健康深色肌肤,光泽感底妆,明快笑容"
- "29岁非裔都市丽人女模,利落编发,精致底妆,自信干练气场"
- "24岁印度裔女模,浓密黑长发,深邃大眼,暖调蜜糖色肌肤"
- "27岁拉丁裔阳光女模,栗色卷发,蜜色肌肤,热情爽朗笑容"
- "32岁中东裔优雅女模,微卷黑发,轮廓深邃,端庄知性气质"
- "28岁大码自信女模,健康微胖体型,自然光泽肌,开朗感染力笑容" # 大码:覆盖plus size市场
male:
# ========== 男模 - 亚洲/盐系/清新类(适合基础款、日韩系) ==========
- "23岁日系盐系男模,单眼皮,清瘦骨感,柔软黑发"
- "25岁亚洲清冷系男模,冷白皮,碎发自热感,下颌线清晰"
- "28岁亚洲轻熟男模,干净利落的短发,健康肤色,稳重气质"
- "21岁亚洲阳光男大,通透底妆,微卷黑发,清爽笑容"
# ========== 男模 - 欧美/街头/运动类(适合美式复古、街头印花) ==========
- "20岁加州冲浪系男模,阳光金发,麦色健康肌,清爽笑容"
- "24岁欧美健身教练型男,肌肉线条分明,小麦色肌肤,硬朗骨相"
- "22岁纽约街头滑板男模,脏辫,清冷厌世感,苍白肌肤"
- "27岁美式机车硬汉男模,粗犷髂廓,络腮胡,硬挺气质"
- "35岁北美成熟奶爸系男模,浅胡茬,栗色短发,温暖亲切笑容" # 新增
# ========== 男模 - 欧美/商务/雅痞类(适合重磅纯色T恤、卫衣) ==========
- "25岁英伦雅痞型男,复古油头,短胡茬,熟男气质"
- "30岁华尔街商务精英男模,背头,沉稳内敛气质,干净皮肤"
- "28岁意大利型男,深邃五官,意式凌乱卷发,健康肌肤"
- "32岁法式儒雅大叔,微卷发,金丝眼镜,温润如玉气质"
# ========== 男模 - 极简/暗黑/高街类(适合纯色基础款、暗黑风) ==========
- "25岁欧美高冷男模,银白发色,苍白冷白皮,锋利眼神"
- "29岁柏林暗黑系青年,苍白皮肤,冷感眼神,黑色直发"
- "26岁东欧赛博风男模,高颧骨,清冷骨相,浅色唇"
- "33岁北欧性冷淡风男艺术家,银色短发,疏离眼神,极简气质"
# ========== 男模 - 多元族裔类(适合多站点覆盖:北美/欧洲站必备) ========== # 新增分组
- "27岁非裔阳光型男模,健康深色肌肤,利落寸头,爽朗笑容"
- "31岁非裔商务型男模,修剪整齐的短须,挺拔身姿,可靠稳重气场"
- "26岁拉丁裔热情男模,微卷黑发,蜜色肌肤,明亮笑容"
- "29岁印度裔斯文男模,黑短发,浓眉,温和儒雅气质"
- "30岁中东裔深邃男模,黑色微卷发,轮廓立体,沉稳内敛"
- "33岁大码健硕男模,魁梧厚实体型,健康肤色,豪爽亲和笑容" # 大码:覆盖plus size市场
+82
View File
@@ -0,0 +1,82 @@
# Pinterest 参考模式种子词(面向视觉灵感,非热点关键词)
# 约束:避开品牌/角色/名人/宗教/国旗/酒精等侵权与敏感项
seeds:
- australian wildlife
- surf culture
- outback landscape
- great barrier reef
- sydney harbour
- koala
- kangaroo
- beach lifestyle
- tropical rainforest
- coastal australia
- aussie retro
- australian birds
- uluru sunset
- australian bush
- sydney opera house
- australian beach
- coral reef
- australian flora
- eucalyptus
- australian summer
- surfboard retro
- australian outback road
- kangaroo silhouette
- australian coast
- bondi beach
- australian desert
- native australian plants
- australian wildlife art
- beach sunset
- australian retro poster
- great ocean road
- australian mountains
- tropical fish
- australian birds art
- surf retro
- australian landscape
- coastal walk
- australian animals
- beach house retro
- australian minimal
- australian emu
- australian cockatoo
- kookaburra
- platypus
- wombat
- tasmanian devil
- australian crocodile
- australian whale
- australian dolphin
- australian sea turtle
- australian reef fish
- australian jellyfish
- australian seahorse
- australian octopus
- australian coral
- australian mangrove
- australian rainforest
- australian waterfall
- australian canyon
- australian outback stars
- australian wildflower
- australian wattle
- australian gum tree
- australian fern
- australian surfboard
- australian boomerang
- australian retro car
- australian retro train
# —— 节日主题(适合印花,避开宗教人物/国旗/酒精/猪等敏感项)——
- australia day fireworks
- easter bilby
- summer christmas
- beach santa
- new year sydney fireworks
- anzac poppy
- spring racing carnival
- surf lifesaving
- autumn leaves
- winter wildlife
+82
View File
@@ -0,0 +1,82 @@
# Pinterest 参考模式种子词(面向视觉灵感,非热点关键词)
# 约束:避开品牌/角色/名人/宗教/国旗/酒精等侵权与敏感项
seeds:
- brazilian tropical
- amazon rainforest
- brazilian street art
- carnival colors
- tropical birds
- brazilian flora
- favela art
- samba culture
- brazilian beach
- jaguar
- toucan
- brazilian retro
- tropical leaves
- brazilian wildlife
- brazilian coast
- rio landscape
- brazilian patterns
- tropical sunset
- brazilian birds
- brazilian art
- amazon wildlife
- brazilian minimal
- tropical flowers
- brazilian street style
- brazilian retro poster
- brazilian nature
- brazilian beach sunset
- brazilian architecture
- tropical fish
- brazilian forest
- brazilian folk art
- brazilian textiles
- brazilian mountains
- brazilian wildlife art
- tropical retro
- brazilian coast retro
- brazilian floral
- brazilian landscape
- brazilian summer
- brazilian retro design
- brazilian macaw
- brazilian hummingbird
- brazilian butterfly
- brazilian monkey
- brazilian capybara
- brazilian sloth
- brazilian dolphin
- brazilian sea turtle
- brazilian reef fish
- brazilian coral
- brazilian waterfall
- brazilian river
- brazilian surf
- brazilian football retro
- brazilian carnival retro
- brazilian samba retro
- brazilian music retro
- brazilian guitar
- brazilian percussion
- brazilian dance
- brazilian capoeira
- brazilian street market
- brazilian fruit
- brazilian mango
- brazilian pineapple
- brazilian coconut
- brazilian palm
- brazilian coffee
# —— 节日主题(适合印花,避开宗教人物/国旗/酒精/猪等敏感项)——
- carnival parade
- carnival feathers
- june festival
- tropical christmas
- new year beach
- easter eggs
- halloween pumpkin
- children's day
- samba festival
- autumn harvest
+82
View File
@@ -0,0 +1,82 @@
# Pinterest 参考模式种子词(面向视觉灵感,非热点关键词)
# 约束:避开品牌/角色/名人/宗教/国旗/酒精等侵权与敏感项
seeds:
- canadian wilderness
- northern lights
- canadian wildlife
- moose
- polar bear
- mountain lakes
- cottage country
- canadian retro
- hockey culture
- coastal canada
- canadian maple
- rocky mountains
- canadian forest
- canadian birds
- loon
- canadian canoe
- banff landscape
- canadian winter
- snowboarding retro
- canadian fishing
- maple forest
- canadian coast
- canadian summer
- canadian wildlife art
- niagara falls
- canadian prairie
- canadian retro poster
- canadian mountains
- canadian lake
- canadian minimal
- canadian autumn
- canadian wildlife illustration
- canadian cabin
- canadian trail
- canadian beach
- canadian skyline
- canadian retro travel
- canadian nature
- canadian wildlife retro
- canadian outdoor
- canadian beaver
- canadian goose
- canadian owl
- canadian eagle
- canadian black bear
- canadian wolf
- canadian fox
- canadian deer
- canadian elk
- canadian caribou
- canadian salmon
- canadian lobster
- canadian whale
- canadian puffin
- canadian heron
- canadian maple syrup
- canadian curling
- canadian skiing
- canadian ice skating
- canadian winter retro
- canadian waterfall
- canadian glacier
- canadian lighthouse
- canadian log cabin
- canadian barn
- canadian wheat
- canadian wildflower
- canadian pine
# —— 节日主题(适合印花,避开宗教人物/国旗/酒精/猪等敏感项)——
- canada day fireworks
- thanksgiving harvest
- maple sugar shack
- winter carnival
- easter eggs
- halloween pumpkin
- christmas snow
- new year fireworks
- autumn leaves
- spring blossom
+82
View File
@@ -0,0 +1,82 @@
# Pinterest 参考模式种子词(面向视觉灵感,非热点关键词)
# 约束:避开品牌/角色/名人/宗教/国旗/酒精等侵权与敏感项
seeds:
- german folk art
- bavarian alpine
- black forest
- berlin street art
- cuckoo clock
- lederhosen
- german castle
- autobahn retro
- nordic minimalism
- german typography
- berlin wall art
- german mountains
- bavarian patterns
- german wildlife
- german retro poster
- german forest
- german architecture
- german countryside
- german birds
- german retro travel
- german minimal
- german coast
- german lakes
- german folk patterns
- german street style
- german nature
- german retro car
- german castle silhouette
- german winter
- german autumn
- german summer
- german floral
- german landscape
- german retro design
- german wildlife art
- german mountains retro
- german folk embroidery
- german minimal design
- german coastal
- german retro typography
- german owl
- german fox
- german deer
- german hare
- german rabbit
- german squirrel
- german hedgehog
- german badger
- german stork
- german robin
- german swan
- german heron
- german kingfisher
- german woodpecker
- german forest animals
- german alpine flowers
- german edelweiss
- german cornflower
- german poppy
- german sunflower
- german lavender
- german rose
- german tulip
- german wildflowers
- german meadow
- german apple orchard
- german pumpkin
- german strawberry
# —— 节日主题(适合印花,避开宗教人物/国旗/酒精/猪等敏感项)——
- easter eggs
- christmas market
- advent calendar
- lantern parade
- carnival costume
- maypole
- autumn harvest
- new year fireworks
- halloween pumpkin
- spring blossom
+82
View File
@@ -0,0 +1,82 @@
# Pinterest 参考模式种子词(面向视觉灵感,非热点关键词)
# 约束:避开品牌/角色/名人/宗教/国旗/酒精等侵权与敏感项
seeds:
- spanish tiles
- flamenco
- andalusian architecture
- spanish retro
- mediterranean coast
- spanish ceramics
- paella
- spanish guitar
- olive groves
- spanish countryside
- spanish floral
- spanish retro poster
- spanish wildlife
- spanish mountains
- spanish coast
- spanish minimal
- spanish architecture
- spanish street style
- spanish nature
- spanish retro design
- spanish birds
- spanish summer
- spanish landscape
- spanish folk art
- spanish pottery
- spanish retro travel
- spanish garden
- spanish tiles patterns
- spanish coastal
- spanish wildlife art
- spanish traditional patterns
- spanish retro typography
- spanish flowers
- spanish beach
- spanish countryside retro
- spanish folk patterns
- spanish minimal design
- spanish retro poster travel
- spanish mountains retro
- spanish art
- spanish horse
- spanish donkey
- spanish goat
- spanish sheep
- spanish cow
- spanish castanets
- spanish fan
- spanish mantilla
- spanish shawl
- spanish lace
- spanish embroidery
- spanish mosaic
- spanish fountain
- spanish plaza
- spanish courtyard
- spanish balcony
- spanish arch
- spanish tower
- spanish castle
- spanish lighthouse
- spanish harbor
- spanish cove
- spanish orange
- spanish lemon
- spanish pomegranate
- spanish watermelon
- spanish churros
- spanish octopus
# —— 节日主题(适合印花,避开宗教人物/国旗/酒精/猪等敏感项)——
- la tomatina
- spanish fiesta
- fallas festival
- flamenco festival
- new year grapes
- summer festival
- halloween pumpkin
- valentine hearts
- autumn harvest
- spring blossom
+82
View File
@@ -0,0 +1,82 @@
# Pinterest 参考模式种子词(面向视觉灵感,非热点关键词)
# 约束:避开品牌/角色/名人/宗教/国旗/酒精等侵权与敏感项
seeds:
- london street style
- british punk
- victorian botanical
- english countryside
- london skyline
- mod fashion
- britpop aesthetic
- royal guard
- tea culture
- coastal britain
- rock music retro
- london underground
- british seaside
- punk rock
- union jack vintage
- british wildlife
- scottish highlands
- welsh coast
- british retro poster
- london fashion week street
- english garden
- british pub sign
- london bridge
- british weather
- vintage british travel
- oxford academia
- british rock band retro
- london graffiti
- british countryside walk
- coastal cliffs
- british birds
- english heritage
- british floral
- london night
- british football retro
- cricket vintage
- british seaside pier
- london architecture
- english tea party
- british minimal
- london double decker
- british seaside retro
- english country cottage
- british canal boats
- london telephone box
- british bulldog
- english rose
- british coastal cliffs
- london night skyline
- british punk retro
- english garden flowers
- london parks
- british retro car
- mini cooper retro
- british music festival
- english fox
- british garden birds
- scottish thistle
- welsh dragon
- british village green
- london architecture retro
- british retro typography
- british floral pattern
- british retro poster art
- english oak tree
- british beach hut
- british street market
- british retro train
# —— 节日主题(适合印花,避开宗教人物/国旗/酒精/猪等敏感项)——
- bonfire night fireworks
- christmas crackers
- easter eggs
- summer bank holiday
- london new year fireworks
- halloween pumpkin
- valentine hearts
- autumn harvest
- spring blossom
- winter snow scene
+82
View File
@@ -0,0 +1,82 @@
# Pinterest 参考模式种子词(面向视觉灵感,非热点关键词)
# 约束:避开品牌/角色/名人/宗教/国旗/酒精等侵权与敏感项
seeds:
- italian renaissance
- tuscan landscape
- venetian mask
- italian retro
- mediterranean style
- roman architecture
- italian ceramics
- amalfi coast
- pasta
- italian espresso
- dolomites
- sicilian patterns
- italian countryside
- italian floral
- italian retro poster
- italian wildlife
- italian coast
- italian minimal
- italian architecture
- italian street style
- italian nature
- italian retro design
- italian birds
- italian summer
- italian landscape
- italian folk art
- italian pottery
- italian retro travel
- italian garden
- italian tiles patterns
- italian coastal
- italian wildlife art
- italian traditional patterns
- italian retro typography
- italian flowers
- italian beach
- italian countryside retro
- italian folk patterns
- italian minimal design
- italian art
- italian wolf
- italian fox
- italian deer
- italian hare
- italian rabbit
- italian squirrel
- italian hedgehog
- italian owl
- italian falcon
- italian swallow
- italian peacock
- italian swan
- italian flamingo
- italian sea turtle
- italian octopus
- italian seahorse
- italian coral
- italian shell
- italian gondola
- italian sailboat
- italian lemon
- italian fig
- italian pomegranate
- italian tomato
- italian basil
- italian gelato
- italian cannoli
- italian focaccia
# —— 节日主题(适合印花,避开宗教人物/国旗/酒精/猪等敏感项)——
- carnevale mask
- ferragosto summer
- new year fireworks
- easter eggs
- summer festival
- autumn harvest
- valentine hearts
- halloween pumpkin
- spring blossom
- winter snow
+82
View File
@@ -0,0 +1,82 @@
# Pinterest 参考模式种子词(面向视觉灵感,非热点关键词)
# 约束:避开品牌/角色/名人/宗教/国旗/酒精等侵权与敏感项
seeds:
- 和柄モチーフ
- 浮世絵デザイン
- レトロポップ
- ミニマルラインアート
- 花柄イラスト
- 猫イラスト
- 富士山グラフィック
- 渋谷ストリートスタイル
- 京都和風
- 桜モチーフ
- 波紋デザイン
- 神社鳥居
- 星座イラスト
- かわいい動物
- 昭和レトロ
- 大正ロマン
- 千鳥格子
- 金魚
- 提灯
- 和菓子
- 招き猫
- だるま
- 風鈴
- 浴衣柄
- 歌舞伎モチーフ
- 水墨画
- 折り紙
- 提灯祭り
- 紅葉
-
-
- 鯉のぼり
-
- 雪景色
- 夏祭り
- 縁日
- 雷門
- 五重塔
- 和太鼓
- 風神雷神
- 花火大会
- 和傘
- 柴犬
- 秋田犬
- うさぎ
-
-
-
-
- 蜻蛉
-
- カブトムシ
- フクロウ
-
-
-
- 椿
-
- 紫陽花
- 朝顔
- 向日葵
- 銀杏
- 雪の結晶
- 七夕
- お月見
- 温泉
- 天守閣
- 忍者
# —— 节日主题(适合印花,避开宗教人物/国旗/酒精/猪等敏感项)——
- お正月デザイン
- ひな祭り
- クリスマス
- ハロウィン
- 雪だるま
- 節分
- バレンタイン
- お花見
- こどもの日
- 大晦日
+82
View File
@@ -0,0 +1,82 @@
# Pinterest 参考模式种子词(面向视觉灵感,非热点关键词)
# 约束:避开品牌/角色/名人/宗教/国旗/酒精等侵权与敏感项
seeds:
- mexican folk art
- talavera patterns
- cacti desert
- aztec patterns
- mexican food
- sombrero
- papel picado
- otomi patterns
- mexican retro
- colorful mexican tiles
- mexican embroidery
- marigold flowers
- mexican birds
- desert sunset
- mexican pottery
- lucha libre retro
- mexican architecture
- tropical mexico
- mexican beach
- mayan patterns
- mexican textiles
- cactus illustration
- mexican skull art
- fiesta colors
- mexican landscape
- mexican flowers
- serape blanket
- mexican market
- colonial mexico
- mexican retro poster
- agave plant
- mexican street art
- chiapas textiles
- mexican wildlife
- oaxaca patterns
- mexican sunset
- mexican folk patterns
- tropical birds
- mexican handcraft
- mexican minimal
- mexican monarch butterfly
- mexican hummingbird
- mexican coyote
- mexican wolf
- mexican fox
- mexican deer
- mexican armadillo
- mexican iguana
- mexican sea turtle
- mexican dolphin
- mexican whale
- mexican starfish
- mexican seahorse
- mexican octopus
- mexican aloe
- mexican yucca
- mexican avocado
- mexican chili
- mexican corn
- mexican tortilla
- mexican tamale
- mexican taco
- mexican guacamole
- mexican vanilla
- mexican piñata
- mexican maracas
- mexican huipil
- mexican rebozo
# —— 节日主题(适合印花,避开宗教人物/国旗/酒精/猪等敏感项)——
- dia de los muertos
- cinco de mayo
- independence fiesta
- christmas posada
- new year fireworks
- easter eggs
- valentine hearts
- mother's day flowers
- summer fiesta
- autumn harvest
+82
View File
@@ -0,0 +1,82 @@
# Pinterest 参考模式种子词(面向视觉灵感,非热点关键词)
# 约束:避开品牌/角色/名人/宗教/国旗/酒精等侵权与敏感项
seeds:
- polish folk art
- polish pottery
- bialowieza forest
- polish mountains
- wawel castle
- slavic patterns
- amber
- polish retro
- vistula river
- polish embroidery
- polish folk patterns
- polish wildlife
- polish countryside
- polish architecture
- polish retro poster
- polish birds
- polish nature
- polish coast
- polish lakes
- polish minimal
- slavic embroidery
- polish folk flowers
- polish retro design
- polish winter
- polish autumn
- polish summer
- polish landscape
- polish folk art patterns
- polish mountains retro
- polish wildlife art
- polish folk costume
- polish retro travel
- polish forest
- polish coastal
- polish folk pottery
- polish minimal design
- polish retro typography
- polish folk birds
- polish countryside retro
- polish traditional patterns
- polish owl
- polish fox
- polish deer
- polish hare
- polish rabbit
- polish squirrel
- polish hedgehog
- polish badger
- polish stork
- polish crane
- polish swan
- polish kingfisher
- polish woodpecker
- polish bison
- polish wolf
- polish lynx
- polish forest animals
- polish wildflowers
- polish cornflower
- polish poppy
- polish sunflower
- polish meadow
- polish apple orchard
- polish strawberry
- polish mushroom
- polish pierogi
- polish gingerbread
- polish honey
# —— 节日主题(适合印花,避开宗教人物/国旗/酒精/猪等敏感项)——
- easter eggs
- christmas market
- midsummer wreaths
- harvest festival
- valentine hearts
- halloween pumpkin
- new year fireworks
- autumn leaves
- winter snow
- spring blossom
+80
View File
@@ -0,0 +1,80 @@
# Pinterest 参考模式种子词(面向视觉灵感,非热点关键词)
# 约束:避开品牌/角色/名人/宗教/国旗/酒精等侵权与敏感项
seeds:
- arabic calligraphy
- desert dunes
- saudi architecture
- middle eastern patterns
- camel
- oasis
- arabic geometric patterns
- traditional arabic design
- desert night sky
- palm oasis
- arabic floral patterns
- desert sunset
- saudi retro
- arabian horses
- desert wildlife
- arabic tiles
- saudi coast
- red sea
- arabic lantern
- desert retro poster
- saudi minimal
- arabic typography
- desert landscape
- saudi mountains
- arabic birds
- desert stars
- saudi nature
- arabic architecture
- desert flowers
- saudi wildlife
- arabic patterns retro
- saudi beach
- desert retro
- arabic minimal design
- saudi folk art
- desert caravan
- arabic pottery
- saudi retro poster
- desert oasis illustration
- arabic geometric art
- arabian falcon
- arabian oryx
- arabian gazelle
- arabian wolf
- arabian fox
- arabian hare
- arabian goat
- arabian sheep
- arabian hoopoe
- arabian dove
- arabian peacock
- arabian flamingo
- arabian sea turtle
- arabian dolphin
- arabian whale
- arabian coral
- arabian starfish
- arabian seahorse
- arabian octopus
- arabian desert rose
- arabian jasmine
- arabian date palm
- arabian olive
- arabian pomegranate
- arabian mint
- arabian coffee
- arabian dates
- arabian carpet
# —— 节日主题(适合印花,避开宗教人物/国旗/酒精/猪等敏感项)——
- desert festival
- camel racing
- date harvest
- arabian nights
- oasis festival
- red sea festival
- saudi coffee culture
- winter desert
+83
View File
@@ -0,0 +1,83 @@
# Pinterest 参考模式种子词(面向视觉灵感,非热点关键词)
# 用途:LLM 据此生成 Pinterest 搜索词 → 爬取图片 → 分析 → 生成 T 恤设计
# 约束:避开品牌/角色/名人/宗教/国旗/酒精等侵权与敏感项
seeds:
- vintage 70s retro
- desert southwest
- coastal beach vibes
- botanical illustration
- retro surf culture
- mountain landscape
- western cowboy
- minimalist line art
- american diner retro
- national park
- road trip
- skate culture
- floral watercolor
- celestial night sky
- mid-century modern
- boho festival
- grunge aesthetic
- cottagecore
- y2k fashion
- streetwear graphic
- retro arcade
- vintage travel poster
- abstract geometric
- hand drawn doodle
- retro sunset
- palm tree summer
- wild west
- space exploration
- ocean waves
- forest wildlife
- retro typography
- pop art
- art deco
- psychedelic
- vintage motorcycle
- retro camper van
- american classic car
- baseball retro
- basketball street
- hiking adventure
- bald eagle illustration
- route 66 road trip
- new york skyline
- golden gate bridge
- grand canyon sunset
- yellowstone wildlife
- rocky mountain peaks
- appalachian trail
- jazz age retro
- blues music retro
- rock and roll retro
- country music retro
- rodeo retro
- barn quilt patterns
- farmhouse retro
- american diner neon
- drive-in movie retro
- vintage soda pop
- american football retro
- skateboard deck art
- graffiti street art
- desert cactus
- retro roller skate
- american retro circus
- liberty bell retro
- space shuttle retro
- vintage pinball
- bowling retro
# —— 节日主题(适合印花,避开宗教人物/国旗/酒精/猪等敏感项)——
- 4th of july fireworks
- thanksgiving turkey
- autumn pumpkin harvest
- christmas snowman
- winter reindeer
- valentine hearts
- easter bunny
- halloween pumpkin
- new year fireworks
- st patrick shamrock
+68 -76
View File
@@ -1,4 +1,4 @@
# 种草图提示词模板库 —— 跨境电商详情页专用版(正面印花完整展示版)
# 种草图提示词模板库 —— 跨境电商详情页专用版(稳定出图+零遮挡强约束+得体姿态+全亮调场景版)
# 占位符:[商品名称]、[材质]、[模特特征]、[服装风格]
# 摄影参数说明:35mm/50mm镜头控制自然透视,f/1.4-f/2.8控制景深虚化,8k强化面料细节,3:4符合电商标准长图比例。
@@ -8,175 +8,167 @@ seed_shot_templates:
# ==========================================
- name: "纯白背景正面全展示"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在纯白无缝背景纸前,身体正对镜头微侧15度,双手自然下垂,眼神直视镜头,整体呈现[服装风格]的调性,完整展示衣服正面的印花图案与[材质]面料的垂坠感。采用电商标准的高亮柔光,左右各一盏柔光箱消除杂乱阴影,光线均匀分布。画面比例为3:4。商业白底图摄影,50mm镜头,f/2.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂或单手插兜,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在纯白无缝背景纸前,身体正对镜头微侧15度,眼神直视镜头,整体呈现[服装风格]的调性,完整展示衣服正面的印花图案与[材质]面料的垂坠感。采用电商标准的高亮柔光,左右各一盏柔光箱消除杂乱阴影,光线均匀分布。画面比例为3:4。商业白底图摄影,50mm镜头,f/2.8光圈,8k分辨率。
- name: "高级浅灰背景全展示"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在高级浅灰背景纸前,身体正对镜头,双手插兜或自然下垂,姿态略微随性,整体呈现[服装风格]的调性,完整展示衣服正面印花与[材质]的挺括度。采用影棚标准柔光与边缘光结合,背景为干净的低饱和灰色。画面比例为3:4。商业白底摄影,50mm镜头,f/2.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂或单手插兜,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在高级浅灰背景纸前,身体正对镜头,姿态略微随性,整体呈现[服装风格]的调性,完整展示衣服正面印花与[材质]的挺括度。采用影棚标准柔光与边缘光结合。画面比例为3:4。商业白底摄影,50mm镜头,f/2.8光圈,8k分辨率。
- name: "纯白背景双手展示下摆"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中近景半身构图,模特站在纯白背景纸前,双手捏住衣服下摆两侧向下轻拉展平,确保正面印花完整无遮挡,眼神直视镜头,整体呈现[服装风格]的调性,画面聚焦展示衣服正面印花图案与下摆的缝线工艺。采用影棚高显色柔光箱,突出印花色彩与[材质]的紧密编织纹理。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.0光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手背在身后或自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中近景半身构图,模特站在纯白背景纸前,眼神直视镜头,整体呈现[服装风格]的调性,画面聚焦展示衣服正面印花图案与下摆的缝线工艺。采用影棚高显色柔光箱,突出印花色彩与[材质]的紧密编织纹理。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.0光圈,8k分辨率。
- name: "低饱和克莱因蓝背景棚拍"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特在低饱和克莱因蓝的无缝背景纸前摆出具有张力的站姿,身体正对镜头,双手自然下垂,整体呈现[服装风格]的调性,突出衣服正面印花图案的视觉冲击力与剪裁,展示[材质]的独特纹理。光线采用双灯硬光与柔光箱结合,形成干净分明的明暗对比。画面比例为3:4。极简主义商业摄影,85mm镜头,f/2.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特在低饱和克莱因蓝的无缝背景纸前摆出具有张力的站姿,身体正对镜头,整体呈现[服装风格]的调性,突出衣服正面印花图案的视觉冲击力与剪裁,展示[材质]的独特纹理。光线采用双灯硬光与柔光箱结合,形成干净分明的明暗对比。画面比例为3:4。极简主义商业摄影,85mm镜头,f/2.8光圈,8k分辨率。
- name: "纯白背景微动态走动展示"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在纯白无缝背景纸前,呈现正对镜头的动态走动状态,单手插兜,整体呈现[服装风格]的调性,展示衣服正面印花在动态下的视觉效果与[材质]面料的动态垂坠感。采用影棚高亮柔光,光比干净分明。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂或单手插兜,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。全身构图,模特站在纯白无缝背景纸前,呈现正对镜头的动态走动状态,整体呈现[服装风格]的调性,展示衣服正面印花在动态下的视觉效果与[材质]面料的动态垂坠感。采用影棚高亮柔光,光比干净分明。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.8光圈,8k分辨率。
# ==========================================
# 二、 面料与印花特写区(打消购买顾虑)
# ==========================================
- name: "纯白背景领口细节特写"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中近景构图,模特站在纯白背景纸前,双手自然下垂不遮挡印花,整体呈现[服装风格]的调性,画面聚焦展示衣服的领口、袖口等工艺细节与[材质]面料的紧密编织纹理。采用影棚标准高显色柔光箱,光线均匀且突出材质的高密度纹理与亲肤特性。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.0光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中近景构图,模特站在纯白背景纸前,整体呈现[服装风格]的调性,画面聚焦展示衣服的领口、袖口等工艺细节与[材质]面料的紧密编织纹理。采用影棚标准高显色柔光箱,光线均匀且突出材质的高密度纹理与亲肤特性。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.0光圈,8k分辨率。
- name: "逆光面料透气质感展示"
- name: "明亮室内逆光面料透气质感展示"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特在黄昏时分的空旷天台逆光站立,发丝被风吹起,双手插兜,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服在逆光强光下展现出的[材质]面料透光性与柔软质感。光线为日落黄金时刻逆光,边缘形成强烈的轮廓光发丝发亮。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂或单手插兜,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。中景半身构图,模特在阳光明媚的玻璃幕墙大堂内逆光站立,发丝被自然光照亮,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服在明亮逆光下展现出的[材质]面料透光性与柔软质感。光线为正午明亮的自然逆光,边缘形成强烈的轮廓光。画面比例为3:4。清透氧气感摄影,50mm镜头,f/1.8光圈,8k分辨率。
- name: "双手拉扯领口弹性展示"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中近景构图,模特站在纯色背景前,双手拉扯衣服领口向下或向两侧拉伸,展示衣服的弹力与防变形属性,整体呈现[服装风格]的调性,凸显[材质]面料的回弹性与结实度。采用高亮柔光,突出面料拉伸时的纹理张力。画面比例为3:4。商业电商摄影,50mm镜头,f/2.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手捏住领口两侧向外轻拉展示弹力,绝对不可将手放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中近景构图,模特站在纯色背景前,凸显[材质]面料的回弹性与结实度。采用高亮柔光,突出面料拉伸时的纹理张力。画面比例为3:4。商业电商摄影,50mm镜头,f/2.8光圈,8k分辨率。
- name: "低头凝视正面印花特写"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特站在纯白背景纸前,微微低头凝视衣服胸前的印花图案,双手自然下垂,整体呈现[服装风格]的调性,画面以斜俯视角度聚焦展示正面印花的色彩细节与[材质]面料的质感。采用影棚顶部柔光与正面补光,突出印花图案的清晰度。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.0光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净简洁,不可产生与服装颜色冲突的杂色。中景半身构图,模特站在纯白背景纸前,微微低头凝视衣服胸前的印花图案,整体呈现[服装风格]的调性,画面以斜俯视角度聚焦展示正面印花的色彩细节与[材质]面料的质感。采用影棚顶部柔光与正面补光,突出印花图案的清晰度。画面比例为3:4。电商白底图摄影,50mm镜头,f/2.0光圈,8k分辨率。
# ==========================================
# 三、 居家生活场景区(营造松弛感与舒适度)
# ==========================================
- name: "居家沙发慵懒场景"
- name: "居家沙发坐姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中远景全身构图,模特慵懒地靠在现代极简风格的客厅布艺沙发上,身体正对镜头微侧,姿态松弛,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的舒适度。室内采用柔和的漫反射自然光,背景为高度虚化的居家环境。画面比例为3:4。柯达Portra 400胶片质感,色彩柔和,35mm镜头,f/2.0光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的坐姿,双手自然放在腿上或沙发扶手上,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。中远景全身构图,模特得体地坐在明亮现代极简风格的客厅布艺沙发上,身体正对镜头微侧,姿态松弛,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的舒适度。室内采用柔和的高调漫反射自然光,背景为高度虚化的明亮居家环境。画面比例为3:4。柯达Portra 400胶片质感,色彩柔和明亮35mm镜头,f/2.0光圈,8k分辨率。
- name: "居家落地窗自然光展示"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特站在高层公寓的落地窗前,单手轻触玻璃,身体正前方对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]亲肤舒适属性。采用日落前的柔和逆光,形成强烈的轮廓光发丝发亮。背景为大虚化的城市楼宇剪影与暖色光晕。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。中景半身构图,模特站在高层公寓明亮的落地窗前,身体正前方对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]亲肤舒适属性。采用日间明亮的柔和逆光,画面通透。背景为大虚化的明亮城市楼宇与蓝天。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8光圈,8k分辨率。
- name: "周末清晨床头场景"
- name: "周末清晨床头坐姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景构图,模特坐在柔软的双人床上伸懒腰,旁边有凌乱的白色枕头,展现周末清晨的松弛感,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的亲肤无拘束感。室内采用清晨柔和的侧向自然光,背景为高度虚化的卧室家具。画面比例为3:4。日系胶片质感,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的坐姿,双手自然放在腿上,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。中景构图,模特得体地坐在床边,展现周末清晨的松弛感,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的亲肤无拘束感。室内采用清晨明亮的高调自然光,背景为高度虚化的卧室家具。画面比例为3:4。日系胶片质感,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。
- name: "居家厨房烹饪场景"
- name: "居家厨房场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中远景全身构图,模特站在现代开放式厨房的中岛台前切水果,身体正对镜头微侧,姿态放松自然,整体呈现[服装风格]的调性,展示衣服正面印花在居家生活中的百搭属性与[材质]面料的舒适耐穿度。室内采用明亮的漫反射自然光与暖色室内灯,背景为高度虚化的厨房台面与绿植。画面比例为3:4。清透氧气感色彩,索尼A7R4画质,50mm镜头,f/1.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂或单手操作厨具,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。中远景全身构图,模特站在现代开放式厨房的中岛台前,身体正对镜头微侧,姿态放松自然,整体呈现[服装风格]的调性,展示衣服正面印花在居家生活中的百搭属性与[材质]面料的舒适耐穿度。室内采用明亮的漫反射自然光与暖色室内灯,背景为高度虚化的厨房台面与绿植。画面比例为3:4。清透氧气感色彩,索尼A7R4画质,50mm镜头,f/1.8光圈,8k分辨率。
- name: "周末居家阅读场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特盘腿坐在卧室的羊毛地毯上,身体正对镜头微侧,双手捧着一本书但不遮挡胸口印花,整体呈现[服装风格]的调性,展示衣服正面印花图案与[材质]面料的柔软亲肤感。室内采用柔和的窗光侧逆光,背景为高度虚化的卧室床铺与暖色氛围灯。画面比例为3:4。日系胶片质感,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的坐姿,双手必须捧书放在腿上,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。中景半身构图,模特盘腿坐在卧室的羊毛地毯上,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花图案与[材质]面料的柔软亲肤感。室内采用柔和的窗光侧逆光,背景为高度虚化的卧室床铺与暖色氛围灯。画面比例为3:4。日系胶片质感,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。
# ==========================================
# 四、 户外休闲/运动场景区(展现百搭与透气)
# ==========================================
- name: "阳光草坪户外实拍"
- name: "阳光草坪户外站姿"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身动态抓拍构图,模特单手插兜,行走在阳光斑驳的城市林荫道上,身体正对镜头微侧,微微低头微笑,呈现不经意的随性状态,整体展现[服装风格]的氛围,凸显[材质]在自然行动中的透气与百搭。午后阳光透过树叶洒下丁达尔光斑与树影,背景为高度虚化的过往行人与都市街景。画面比例为3:4。徕卡Q2摄影质感,高对比度色彩,35mm镜头,f/1.7大光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂或单手插兜,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特站在阳光充足的城市林荫道上,身体正对镜头微侧,微微低头微笑,整体展现[服装风格]的氛围,凸显[材质]在自然行动中的透气与百搭。午后阳光透过树叶洒下明亮的光斑,背景为高度虚化的过往行人与都市街景。画面比例为3:4。徕卡Q2摄影质感,高对比度明亮色彩,35mm镜头,f/1.7大光圈,8k分辨率。
- name: "都市街头OOTD穿搭展示"
- name: "都市街头OOTD站姿展示"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在现代商业街区或美术馆外墙前,单手拿着外带咖啡杯放在胸前不遮挡印花,身体正对镜头微靠在墙上,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的抗皱性。采用午后天光与建筑反射光,画面明亮通透,背景为高度虚化的都市街景与阳光光斑。画面比例为3:4。清透氧气感色彩,索尼A7R4画质,50mm镜头,f/1.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂或单手拿咖啡杯放在腰侧,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特站在阳光明媚的现代商业街区外墙前,身体正对镜头微靠在墙上,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的抗皱性。采用午后天光与建筑反射光,画面明亮通透,背景为高度虚化的都市街景与阳光光斑。画面比例为3:4。清透氧气感色彩,索尼A7R4画质,50mm镜头,f/1.8光圈,8k分辨率。
- name: "天台蓝天白云清透场景"
- name: "天台蓝天白云站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在无遮挡的空旷天台上,背景是大面积的蓝天白云,模特双手自然下垂或交叉抱胸但不遮挡印花,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的透气感。正午明亮的顺光,无死角的展现服装颜色,背景为高饱和的纯蓝天空。画面比例为3:4。徕卡Q2摄影质感,35mm镜头,f/2.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特站在无遮挡的空旷天台上,背景是大面积的蓝天白云,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的透气感。正午明亮的顺光,无死角的展现服装颜色。画面比例为3:4。徕卡Q2摄影质感,35mm镜头,f/2.8光圈,8k分辨率。
- name: "自然公园休闲外景"
- name: "自然公园站姿外景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在阳光充足的公园草坪前,微风吹拂发丝,微微仰头感受自然,身体正对镜头微侧,双手自然下垂,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的透气性与轻盈感。光线为明亮的顺光搭配自然反光,画面明亮通透,背景为大面积虚化的鲜绿植被与光斑。画面比例为3:4。清透氧气感色彩,索尼A7R4画质,85mm镜头,f/1.8光圈,清新高调摄影,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特站在阳光充足的公园草坪前,微风吹拂发丝,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的透气性与轻盈感。光线为明亮的顺光搭配自然反光,画面明亮通透,背景为大面积虚化的鲜绿植被与光斑。画面比例为3:4。清透氧气感色彩,索尼A7R4画质,85mm镜头,f/1.8光圈,清新高调摄影,8k分辨率。
- name: "街头滑板运动场景"
- name: "街头滑板站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身动态抓拍构图,模特单脚踩滑板停在滑板公园的U型池边缘,身体正对镜头,微风吹拂发丝,双手自然下垂,呈现不经意的随性状态,整体展现[服装风格]的氛围,展示衣服正面印花与[材质]的运动属性。午后强烈的阳光形成侧逆光,背景为高度虚化的水泥滑板池与涂鸦墙。画面比例为3:4。徕卡Q2摄影质感,35mm镜头,f/1.7光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,单脚踩滑板上,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特站在阳光明媚的滑板公园边缘,身体正对镜头,微风吹拂发丝,呈现不经意的随性状态,整体展现[服装风格]的氛围,展示衣服正面印花与[材质]的运动属性。明亮的阳光形成侧逆光,背景为高度虚化的彩色滑板场地与涂鸦墙。画面比例为3:4。徕卡Q2摄影质感,35mm镜头,f/1.7光圈,8k分辨率。
- name: "阳光林荫道骑行场景"
- name: "林荫道骑行停靠场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身动态抓拍构图,模特骑着一辆复古自行车停在两旁长满梧桐树的林荫小道上,单脚点地,转头看向镜头微笑,身体正对镜头,双手握把不遮挡印花,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的透气性。午后阳光透过树叶洒下丁达尔光斑,背景为高度虚化的树干与光斑。画面比例为3:4。日系胶片质感,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,单脚点地双手握把,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特骑着一辆复古自行车停在两旁长满梧桐树的林荫小道上,转头看向镜头微笑,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的透气性。明亮阳光透过树叶洒下光斑,背景为高度虚化的树干与明亮光斑。画面比例为3:4。日系胶片质感,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。
- name: "海边漫步度假场景"
- name: "海边沙滩站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身动态抓拍构图,模特在细软的沙滩上,海风吹起衣摆,双手自然张开,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的轻盈与夏日属性。光线为正午强烈的顺光,画面明亮高调,背景为高度虚化的蔚蓝海水、白沙滩与远处海平线。画面比例为3:4。索尼A7R4画质,35mm镜头,f/2.0光圈,高饱和度清透色彩,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤,脚上穿着休闲鞋。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特在细软的沙滩上,海风吹起衣摆,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的轻盈与夏日属性。光线为正午强烈的顺光,画面明亮高调,背景为高度虚化的蔚蓝海水、白沙滩与远处海平线。画面比例为3:4。索尼A7R4画质,35mm镜头,f/2.0光圈,高饱和度清透色彩,8k分辨率。
- name: "露营帐篷森系户外场景"
- name: "露营帐篷坐姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特坐在森林空地的露营椅上,旁边有燃烧的篝火和搭好的金字塔帐篷,双手端着搪瓷杯放在腿上不遮挡印花,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的保暖性。采用黄昏暖色篝火光与天光交织,背景为高度虚化的茂密松林与烟雾。画面比例为3:4。复古胶片质感,35mm镜头,f/1.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的坐姿,双手端着搪瓷杯放在腿上,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特坐在森林空地的露营椅上,旁边有搭好的白色金字塔帐篷,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的户外属性。采用正午明亮的自然光,背景为高度虚化的茂密松林与光斑。画面比例为3:4。复古胶片质感,35mm镜头,f/1.8光圈,8k分辨率。
- name: "海风度假场景展示"
- name: "浅水沙滩站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特赤脚走在浅水沙滩,海风吹起衣摆,双手自然张开,笑容明朗,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的轻盈与飘逸感。光线为正午到下午的明亮阳光,海面反光形成自然补光,背景为高度虚化的蔚蓝大海、白沙滩与天空。画面比例为3:4。夏日清透色彩,高饱和度,35mm镜头,f/2.0光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤,脚上穿着休闲鞋。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特在浅水沙滩,海风吹起衣摆,笑容明朗,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的轻盈与飘逸感。光线为正午到下午的明亮阳光,海面反光形成自然补光,背景为高度虚化的蔚蓝大海、白沙滩与天空。画面比例为3:4。夏日清透色彩,高饱和度,35mm镜头,f/2.0光圈,8k分辨率。
- name: "热带绿植温室场景"
- name: "热带绿植温室站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在长满大型龟背竹与天堂鸟的植物园温室中,手指轻轻触碰绿叶,笑容明朗,身体正对镜头,双手自然下垂,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的轻盈与透气感。光线为穿透植物叶片的柔和自然光,形成斑驳的树影打在衣服上,背景为高度虚化的茂密绿植与光斑。画面比例为3:4。富士Provia 400X色彩预设,35mm镜头,f/1.4大光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特站在长满大型龟背竹与天堂鸟的植物园温室中,笑容明朗,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的轻盈与透气感。光线为穿透玻璃顶的明亮自然光,形成明亮的光斑,背景为高度虚化的茂密绿植。画面比例为3:4。富士Provia 400X色彩预设,35mm镜头,f/1.4大光圈,8k分辨率。
- name: "阴天极简冷淡风外景"
- name: "现代美术馆纯白站姿外景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特背靠在粗犷的混凝土墙面或现代美术馆外墙前,眼神冷,身体正对镜头微侧,双手自然下垂,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]的街头属性。采用阴天柔和的漫反射自然冷光,背景为低饱和的莫兰迪灰调与几何影,画面干净清。画面比例为3:4。极简主义商业摄影,55mm镜头,f/2.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特背靠在明亮的现代美术馆纯白外墙前,眼神冷,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]的极简高级感。采用明亮的顺光漫反射,背景为低饱和的明亮白调与几何影,画面干净清。画面比例为3:4。极简主义商业摄影,55mm镜头,f/2.8光圈,8k分辨率。
- name: "山顶自然风光征服场景"
- name: "山顶站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在山顶的岩石上,双手叉腰但不遮挡印花,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花图案与[材质]面料在户外的耐穿与透气属性。采用傍晚日落前的逆光与山顶漫反射光,背景为高度虚化的连绵山脉与云。画面比例为3:4。电影级情绪摄影,35mm镜头,f/2.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特站在山顶的岩石上,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花图案与[材质]面料在户外的耐穿与透气属性。采用正午明亮的顺光,画面通透,背景为高度虚化的连绵山脉与蓝天白云。画面比例为3:4。电影级情绪摄影,35mm镜头,f/2.8光圈,8k分辨率。
# ==========================================
# 五、 工作/通勤场景区(展现日常实用度)
# ==========================================
- name: "办公场景商务休闲展示"
- name: "办公场景坐姿展示"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特坐在极简办公桌前,单手托腮或敲击键盘,身体正对镜头微侧,展现干练气质,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的抗皱与挺括感。室内采用明亮的现代白光照明,背景为高度虚化的电脑屏幕与办公桌绿植,画面通透干净。画面比例为3:4。商业电商摄影,50mm镜头,f/2.0光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的坐姿,双手放在桌上或键盘上不遮挡胸口,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。中景半身构图,模特坐在明亮的极简办公桌前,身体正对镜头微侧,展现干练气质,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的抗皱与挺括感。室内采用明亮的高调白光照明,背景为高度虚化的电脑屏幕与办公桌绿植,画面通透干净。画面比例为3:4。商业电商摄影,50mm镜头,f/2.0光圈,8k分辨率。
- name: "咖啡馆周末休闲场景"
- name: "咖啡馆坐姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特坐在极简风格咖啡馆的窗边座位上,单手端着陶瓷咖啡杯放在嘴边不遮挡印花,身体正对镜头微侧,姿态慵懒松弛,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的柔软垂坠感。晨间自然光从大窗户斜射进来形成柔和侧逆光,背景为高度虚化的木质室内装潢、绿植与朦胧的咖啡蒸汽。画面比例为3:4。日系胶片质感,富士Provia 400X色彩预设,35mm镜头,f/1.8大光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的坐姿,单手端着陶瓷咖啡杯放在嘴边不遮挡印花,另一只手自然放在桌上,绝对不可双手交叉抱胸。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。中景半身构图,模特坐在明亮风格咖啡馆的窗边座位上,身体正对镜头微侧,姿态慵懒松弛,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的柔软垂坠感。明亮的自然光从大窗户斜射进来,画面通透,背景为高度虚化的木质室内装潢、绿植与朦胧的咖啡蒸汽。画面比例为3:4。日系胶片质感,富士Provia 400X色彩预设,35mm镜头,f/1.8大光圈,8k分辨率。
- name: "书店翻阅书籍场景"
- name: "书店站姿翻阅场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特站在高大木质书架前翻阅一本精装书,眼神专注,身体正对镜头微侧,双手捧书放在腰间不遮挡胸口印花,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的挺括与质感。书店采用暖色调的钨丝灯点光源,背景为高度虚化的书脊与暖色光斑。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8大光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手捧书放在腰间不遮挡胸口,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。中景半身构图,模特站在明亮的高大木质书架前翻阅一本精装书,眼神专注,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的挺括与质感。书店采用明亮的射灯与自然光交织,背景为高度虚化的书脊与明亮光斑。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8大光圈,8k分辨率。
- name: "复古家具店探店场景"
- name: "复古家具店站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在摆满上世纪老物件的中古家具店内,手指轻抚一把复古单椅,眼神安静,身体正对镜头微侧,双手自然下垂,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的质感。店内采用暖色调的钨丝灯漫反射,背景为高度虚化的胡桃木柜子与老式台灯。画面比例为3:4。富士Provia 400X色彩预设,35mm镜头,f/1.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特站在摆满上世纪老物件的中古家具店内,眼神安静,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的质感。店内采用明亮的自然光漫反射,背景为高度虚化的胡桃木柜子与明亮光斑。画面比例为3:4。富士Provia 400X色彩预设,35mm镜头,f/1.8光圈,8k分辨率。
- name: "艺术画廊看展高级场景"
- name: "艺术画廊站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在灯光柔和的现代艺术画廊内,侧身凝视一幅巨大的抽象画后转过头来正对镜头,双手自然下垂,气质疏离高级,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]的高级调性。画廊专业的顶光灯打出柔和的漫反射,背景为高度虚化的洁白墙面与画框。画面比例为3:4。索尼A7R4画质,35mm镜头,f/1.8大光圈,清冷调高级感,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特站在灯光柔和明亮的现代艺术画廊内,侧身凝视一幅巨大的抽象画后转过头来正对镜头,气质疏离高级,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]的高级调性。画廊专业的顶光灯打出柔和的漫反射,背景为高度虚化的洁白墙面与画框。画面比例为3:4。索尼A7R4画质,35mm镜头,f/1.8大光圈,清冷调高级感,8k分辨率。
- name: "超市货架色彩碰撞场景"
- name: "超市货架站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特推着购物车或站在摆满色彩鲜艳饮料的超市货架前,身体正对镜头,双手推车不遮挡印花,姿态俏皮个性,整体呈现[服装风格]的调性,展示衣服正面印花图案与背景色彩的碰撞感及[材质]的日常实穿度。货架顶部的冷光源打亮环境,背景为高度虚化的彩色商品与灯轨。画面比例为3:4。赛博潮流摄影,35mm镜头,f/1.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手推车不遮挡印花,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特推着购物车或站在摆满色彩鲜艳饮料的超市货架前,身体正对镜头,姿态俏皮个性,整体呈现[服装风格]的调性,展示衣服正面印花图案与背景色彩的碰撞感及[材质]的日常实穿度。货架顶部的明亮冷光源打亮环境,背景为高度虚化的彩色商品与灯轨。画面比例为3:4。赛博潮流摄影,35mm镜头,f/1.8光圈,8k分辨率。
# ==========================================
# 六、 情绪氛围与夜景场景区(提升品牌调性)
# 六、 情绪氛围与高亮特色场景区(提升品牌调性)
# ==========================================
- name: "工业风工作室背景展示"
- name: "明亮工业风咖啡馆站姿展示"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特站在工业风loft工作室的水泥墙前,单手插兜不遮挡印花,眼神清冷,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的硬挺与廓形。采用顶部的冷色聚光灯与微弱的暖色环境光对比,背景为高度虚化的昏暗通道与反光地面。画面比例为3:4。赛博潮流电商摄影,55mm镜头,f/2.0光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂或单手插兜,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特站在明亮工业风咖啡馆的纯白水泥墙前,眼神清冷,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的硬挺与廓形。采用正午明亮的自然光与室内暖光交织,背景为高度虚化的明亮通道与绿植。画面比例为3:4。赛博潮流电商摄影,55mm镜头,f/2.0光圈,8k分辨率。
- name: "录音棚音乐人场景"
- name: "录音棚站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景构图,模特戴着监听耳机站在专业麦克风前调音,眼神专注,身体正对镜头微侧,双手调音不遮挡胸口印花,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的挺括廓形。采用录音棚特有的暖色聚光灯与整体冷色调对比,背景为高度虚化的吸音棉墙面与调音台。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手调音不遮挡胸口,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。中景构图,模特戴着监听耳机站在专业麦克风前调音,眼神专注,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的挺括廓形。采用录音棚明亮的暖色聚光灯与整体白光对比,背景为高度虚化的吸音棉墙面与调音台。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.8光圈,8k分辨率。
- name: "微醺暖光清吧场景"
- name: "暖光清吧坐姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特坐在氛围感清吧的吧台前,单手把玩着威士忌酒杯放在吧台上不遮挡印花,眼神微醺迷离,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]在暖光下的质感。采用暖黄色点光源与背景微弱的光对比,背景为高度虚化的酒瓶阵列与杯光交错。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.4大光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的坐姿,双手把玩酒杯放在吧台上不遮挡印花,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。中景半身构图,模特坐在氛围感清吧的吧台前,眼神微醺迷离,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]在暖光下的质感。采用明亮的暖黄色点光源与背景微弱的光对比,背景为高度虚化的酒瓶阵列与杯光交错。画面比例为3:4。电影级情绪摄影,50mm镜头,f/1.4大光圈,8k分辨率。
- name: "夜晚霓虹街头场景"
- name: "日落黄昏街头站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特夜晚倚靠在城市天桥栏杆旁,眼神清冷,身体正对镜头微侧,双手插兜不遮挡印花,整体呈现[服装风格]的调性,展示衣服正面印花在夜色下的视觉效果与[材质]的质感与垂感。采用强烈的边缘光与城市霓虹灯的彩色反光(青蓝与橘红对比),背景为高度虚化的车流光轨与霓虹灯牌。画面比例为3:4。赛博朋克潮流摄影,35mm镜头,f/1.4大光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手插兜不遮挡印花,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特倚靠在城市明亮的天桥栏杆旁,眼神清冷,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花在黄昏下的视觉效果与[材质]的质感与垂感。采用日落前明亮的黄金时刻光线与边缘光,背景为高度虚化的明亮车流与城市剪影。画面比例为3:4。赛博朋克潮流摄影,35mm镜头,f/1.4大光圈,8k分辨率。
- name: "复古旱冰场霓虹场景"
- name: "旱冰场站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特穿着旱冰鞋在复古旱冰场滑行,姿态灵动,身体正对镜头微侧,双手自然摆动不遮挡印花,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的随性与飘逸。霓虹紫粉色调与射灯打在模特身上,背景为高度虚化的霓虹灯带与溜冰场护栏。画面比例为3:4。复古胶片质感,35mm镜头,f/1.4大光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特穿着旱冰鞋在复古旱冰场中央,姿态从容,身体正对镜头微侧,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的随性与飘逸。明亮的紫粉色调与射灯打在模特身上,背景为高度虚化的霓虹灯带与溜冰场护栏。画面比例为3:4。复古胶片质感,35mm镜头,f/1.4大光圈,8k分辨率。
- name: "地下车库工业风场景"
- name: "明亮的现代地下车库站姿场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特背靠在粗犷的地下车库水泥柱上,眼神冷酷,身体转回正对镜头,双手自然下垂,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的耐穿属性。采用顶部的冷色聚光灯与微弱的暖色环境光对比,背景为高度虚化的昏暗车库通道与反光地面。画面比例为3:4。赛博朋克潮流摄影,55mm镜头,f/2.0光圈,8k分辨率。
- name: "美式复古街道场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。全身构图,模特走在有复古拱门和石板路的欧式街道上,手里拿着一束鲜花放在胸前不遮挡印花,身体正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的垂感。清晨柔和的漫反射自然光,画面充满复古氛围,背景为高度虚化的古典建筑与梧桐树。画面比例为3:4。柯达Portra 400胶片质感,色彩柔和低饱和,50mm镜头,f/2.0光圈,8k分辨率。
- name: "长途自驾车窗场景"
prompt: |
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其穿在一位[模特特征]的身上。中景半身构图,模特坐在汽车副驾驶位上,单手将手肘搭在车窗上,看着镜头,微风吹拂发丝,身体正对镜头微侧,另一只手自然放在腿上不遮挡印花,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的随性质感。光线为穿透车窗的柔和侧逆光,背景为高度虚化的公路与掠过的树影。画面比例为3:4。电影级情绪摄影,柯达Portra 400色彩预设,40mm镜头,f/2.0光圈,8k分辨率。
【最高优先级约束】请严格保留参考图1中模特所穿衣服的完整外观,包括其原有的颜色、印花图案、版型款式、材质纹理与缝线细节,绝对禁止对衣服本身进行任何形式的修改、重新设计、变色或改变图案。仅提取这件[商品名称],将其作为单件上衣穿在一位[模特特征]的身上,模特仅单穿这一件衣服,绝对禁止在外面叠加任何外套、夹克或衬衫。模特下半身穿着与整体风格搭配的长裤、短裤或牛仔裤。【负面约束】禁止改变衣服颜色,禁止遮挡材质纹理,禁止遮挡或破坏印花图案完整性,禁止双手交叉抱胸,禁止手部遮挡胸口,禁止裸露下半身,禁止赤脚。【动作硬约束】模特必须保持规范的站姿,双手自然下垂,绝对不可放在胸口或腰间交叉。【稳定性约束】背景必须保持干净明亮,不可产生昏暗杂色。全身构图,模特背靠在明亮的现代地下车库环氧地坪和纯白水泥柱上,眼神冷酷,身体转回正对镜头,整体呈现[服装风格]的调性,展示衣服正面印花与[材质]面料的耐穿属性。采用顶部的明亮白光聚光灯照明,画面清透无暗角,背景为高度虚化的明亮车库通道与反光地面。画面比例为3:4。赛博朋克潮流摄影,55mm镜头,f/2.0光圈,8k分辨率。
+19
View File
@@ -0,0 +1,19 @@
# 2026-08-25 工作日志
## 全量同步 13 国(追加模式,保留现有数据)
- 目标:按"之前的流程"同步所有国家。PG plates 表共 17 个(plate 1=目录不计),实际国家 13 个:
US(2,3,4,5)、MX(6)、JP(7)、KR(8)、SA(9)、BR(10)、GB(11)、CA(12)、PL(13)、ES(14)、DE(15)、AU(16)、IT(17)。
- 关键风险:旧 `__main__``clear_first=True`(先 DELETE 两表),全量重跑会清空当前库、冲掉手动修改(JP/GB 尺码、JPTM001 图片+价格)。用户选择"追加9国·保留现有"。
- 改动 sync_from_pg.py
1. 新增 `SIZE_SYSTEM` 映射:JP/KR=("亚洲尺码","亚洲尺码亚洲常规"),其余默认 ("尺码","欧美尺码常规")SKU 循环里 `sgroup, stype = SIZE_SYSTEM.get(country, default)` 替换原写死的 `尺码/欧美尺码常规`
2. `__main__` 改为 13 国全部 `clear_first=False`(追加)。已存在的 SPU code / SKU 组合自动跳过,不覆盖手动编辑。
- 结果:SPU 93→143+50),SKU 2025→2875+850)。13 国全到齐。
- 校验:US/MX/JP/GB 数量与重跑前一致(1400/123/244/258);JP=亚洲尺码、GB=欧美尺码、JPTM001-BL01(cdnfe图+price=42) 均保留;KR=亚洲尺码;新国 SPU code 与旧国零重复。
- 备份:`spu_sku.db.bak_pre_fullsync`(重跑前含手动修改的整库)。
- SA 的 PG categories 4 条但只同步 3 个 SPU1 条 code 为空被脚本 `c.code IS NOT NULL AND c.code<>''` 过滤,属正常)。
## 尺码体系约定(最终)
- 亚洲市场(JP/KR)→ size_group=亚洲尺码 / size_type=亚洲尺码亚洲常规
- 欧美及其它市场(US/MX/GB/CA/PL/ES/DE/AU/BR/IT/SA)→ size_group=欧美尺码 / size_type=欧美尺码常规
- 用户 8/25 明确:除 JP/KR 外其余 11 国 size_group 一律"欧美尺码"(含 GB 之前手动改的也符合)。执行 UPDATEWHERE country NOT IN ('JP','KR')),影响 2579 行,size_type 不动。备份 spu_sku.db.bak_sizegroup。
- 注:现在 size_group 仅两种值(亚洲尺码/欧美尺码),口径已统一;sync_from_pg.py 中 SIZE_SYSTEM 默认仍是"尺码",与库内现状不一致,若以后重跑追加新国家需注意让默认对齐"欧美尺码"。
BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+23 -6
View File
@@ -41,6 +41,13 @@ import json
PG = dict(host="localhost", port=5432, user="postgres", password="inkreach", dbname="inkreach")
SQLITE = r"C:\Users\Admin\Desktop\test模版\design_agent\pod_trend_agent\db\spu_sku.db"
# 尺码体系按国家区分:亚洲市场(JP/KR)用亚洲尺码,其余默认 欧美尺码/欧美尺码常规
# (库内约定:除 JP/KR 外所有国家 size_group 一律"欧美尺码",与下方默认一致)
SIZE_SYSTEM = {
"JP": ("亚洲尺码", "亚洲尺码亚洲常规"),
"KR": ("亚洲尺码", "亚洲尺码亚洲常规"),
}
def clean(v):
if v is None:
@@ -466,9 +473,8 @@ def sync(plate_ids, country, clear_first=True):
img5 = urls[4] if len(urls) > 4 else None
price = price_by_code.get(code)
# 按用户要求:size_group 固定为"尺码"size_type 固定为"欧美尺码常规"
sgroup = "尺码"
stype = "欧美尺码常规"
# 尺码体系按国家区分:亚洲市场(JP/KR)=亚洲尺码,其余默认 欧美尺码/欧美尺码常规
sgroup, stype = SIZE_SYSTEM.get(country, ("欧美尺码", "欧美尺码常规"))
for col in color_list:
raw_code = col["code"]
@@ -529,9 +535,20 @@ def sync(plate_ids, country, clear_first=True):
if __name__ == "__main__":
# 顺序执行:先全量同步美国(重置整库),再依次追加其他国家(保留已有数据)
sync((2, 3, 4, 5), "US", clear_first=True)
# 追加模式(clear_first=False):保留现有 US/MX/JP/GB 及手动修改,仅补齐其余 9 国
# 任何国家若已存在会被跳过(SPU code / SKU 组合去重),不会覆盖手动编辑
sync((2, 3, 4, 5), "US", clear_first=False)
sync((6,), "MX", clear_first=False)
sync((7,), "JP", clear_first=False)
sync((11,), "GB", clear_first=False)
print("\n✅ 同步完成:SPU/SKU 已包含 US + MX + JP + GB 数据")
# 新增国家
sync((8,), "KR", clear_first=False)
sync((9,), "SA", clear_first=False)
sync((10,), "BR", clear_first=False)
sync((12,), "CA", clear_first=False)
sync((13,), "PL", clear_first=False)
sync((14,), "ES", clear_first=False)
sync((15,), "DE", clear_first=False)
sync((16,), "AU", clear_first=False)
sync((17,), "IT", clear_first=False)
print("\n✅ 同步完成:13 国数据已包含(US/MX/JP/GB 保留,KR/SA/BR/CA/PL/ES/DE/AU/IT 已追加)")
+125
View File
@@ -58,6 +58,83 @@ def build_graph():
return builder.compile()
def _pinterest_route(state: Dict[str, Any]) -> str:
"""图池路由:简报达标 → done;图池还有未消费图片 → analyze(继续分析,不搜索);
图池不足 → search(新一轮搜索);轮次耗尽 → done。"""
target = int(state.get("pinterest_target") or 0)
if target <= 0:
target = 1
briefs = state.get("briefs") or []
rounds = int(state.get("pinterest_rounds") or 0)
terms = state.get("pinterest_search_terms") or []
pcfg = (state.get("config") or {}).get("pinterest") or {}
max_rounds = int(pcfg.get("max_search_rounds") or 0)
if max_rounds <= 0:
max_rounds = max(target * 2, 5)
if len(briefs) >= target:
print(f"[pinterest_route] 简报已达目标 {len(briefs)}/{target},结束")
return "done"
# 图池还有未消费图片 → 继续分析(不搜索)
try:
from graph.pinterest import load_image_pool, load_used_images, pool_unused_images
pool = load_image_pool(str(state.get("output_dir") or ""), state.get("country") or "")
used = load_used_images(str(state.get("output_dir") or ""), state.get("country") or "")
unused = pool_unused_images(pool, used)
except Exception: # noqa: BLE001
unused = []
if unused:
print(f"[pinterest_route] 图池还有 {len(unused)} 张未消费图片,继续分析(简报 {len(briefs)}/{target}")
return "analyze"
# 图池不足 → 搜索
if rounds >= max_rounds:
print(f"[pinterest_route] 已达最大轮次 {max_rounds},简报 {len(briefs)}/{target},按现有结果继续")
return "done"
if not terms and rounds > 0:
print(f"[pinterest_route] 无可用搜索词,停止搜索(简报 {len(briefs)}/{target}")
return "done"
print(f"[pinterest_route] 图池不足,新一轮搜索(第 {rounds} 轮,简报 {len(briefs)}/{target}")
return "search"
def build_pinterest_graph():
"""Pinterest 参考模式图(按需搜索循环 + 简报池并发生成):
pinterest_init(建简报池)→ pinterest_search → pinterest_scrape → pinterest_analyze
→ [pinterest_route] 简报不足 → 回到 pinterest_search;达标 → pinterest_finalize
(排空简报池、后台并发生成 设计→三合一→OSS→种草图)→ template_export
"""
from graph.nodes import (
pinterest_analyze_node,
pinterest_scrape_node,
pinterest_search_node,
)
from graph.nodes.pinterest_finalize_node import pinterest_finalize_node
from graph.nodes.pinterest_init_node import pinterest_init_node
builder = StateGraph(AgentState)
builder.add_node("pinterest_init", pinterest_init_node)
builder.add_node("pinterest_search", pinterest_search_node)
builder.add_node("pinterest_scrape", pinterest_scrape_node)
builder.add_node("pinterest_analyze", pinterest_analyze_node)
builder.add_node("pinterest_finalize", pinterest_finalize_node)
builder.add_node("template_export", template_export_node)
builder.add_edge("__start__", "pinterest_init")
builder.add_edge("pinterest_init", "pinterest_search")
builder.add_edge("pinterest_search", "pinterest_scrape")
builder.add_edge("pinterest_scrape", "pinterest_analyze")
builder.add_conditional_edges("pinterest_analyze", _pinterest_route, {
"analyze": "pinterest_analyze", # 图池还有未消费图片 → 继续分析(不搜索)
"search": "pinterest_search", # 图池不足 → 新一轮搜索
"done": "pinterest_finalize", # 简报达标/轮次耗尽 → 收尾(排空简报池)
})
builder.add_edge("pinterest_finalize", "template_export")
builder.add_edge("template_export", END)
return builder.compile()
def run_country(
country: str,
global_config: Dict[str, Any],
@@ -109,3 +186,51 @@ def run_country(
result = compiled.invoke(state)
return result
def run_pinterest_ref(
country: str,
global_config: Dict[str, Any],
project_root: Path,
output_root: Optional[Path] = None,
task_timestamp: Optional[str] = None,
) -> Dict[str, Any]:
"""Pinterest 参考模式入口:独立于 Google Trends 的完整流程。
种子词 → LLM 搜索词(json_schema + 动态注入防重复)→ 爬图 → LLM 分析图片
→ 设计简报 → 设计稿 → 产品图 → 上传 → 种草图 → 模板导出。
参数语义与 run_country 一致(project_root=数据根,output_root=产物根)。
"""
compiled = build_pinterest_graph()
cc = build_country_config(global_config, country, project_root)
prompts_dir = project_root / "prompts" / country
cache_dir = (output_root or project_root) / "output" / country
ts = task_timestamp or time.strftime("%Y%m%d_%H%M%S")
_base = ts
_i = 1
while (cache_dir / ts).exists(): # 时间戳文件夹唯一(同秒多任务防冲突/覆盖)
ts = f"{_base}_{_i}"
_i += 1
output_dir = cache_dir / ts
state: Dict[str, Any] = {
"country": country,
"config": global_config,
"country_config": cc,
"prompts_dir": str(prompts_dir),
"cache_dir": str(cache_dir),
"output_dir": str(output_dir),
"briefs": [],
"composite": [],
"designs": [],
"errors": [],
"stats": {},
"task_timestamp": ts,
"oss_seq": 0,
# 按需搜索目标:简报数 = spu_tasks 数量(每款一个设计);无任务时回退 spu_count/1
"pinterest_target": len((global_config.get("product") or {}).get("spu_tasks") or [])
or int((global_config.get("product") or {}).get("spu_count") or 0) or 1,
"pinterest_rounds": 0,
"pinterest_attempted": [],
}
return compiled.invoke(state)
+1 -1
View File
@@ -19,7 +19,7 @@ class ImageBackend(ABC):
def print(self, prompt: str, base_image: str, out_path: str, negative: str = "",
extra_images: Optional[Sequence[str]] = None, size: str = "") -> str:
"""返回生成的成品图路径。实现内部应处理调用失败/超时并抛异常由调用方兜底。
size: 显式尺寸覆盖(如 "1504x2000");留空则用后端配置的 size。"""
size: 显式尺寸覆盖(如 "1536x2048");留空则用后端配置的 size。"""
raise NotImplementedError
def generate(self, prompt: str, out_path: str, negative: str = "", size: str = "") -> str:
+3 -2
View File
@@ -20,7 +20,7 @@ class MockImageBackend(ImageBackend):
self._cfg = cfg or {}
def print(self, prompt: str, base_image: str, out_path: str, negative: str = "",
extra_images=None, size: str = "") -> str:
extra_images=None, size: str = "", seed: int = None) -> str:
size_px = (1024, 1024)
try:
with Image.open(base_image) as im:
@@ -45,7 +45,8 @@ class MockImageBackend(ImageBackend):
img.save(out_path)
return out_path
def generate(self, prompt: str, out_path: str, negative: str = "", size: str = "") -> str:
def generate(self, prompt: str, out_path: str, negative: str = "", size: str = "",
seed: int = None) -> str:
"""纯文生图(mock):白底 + 文字标注,模拟纯印花设计稿。"""
size_px = (1024, 1024)
if size:
+10 -3
View File
@@ -137,13 +137,14 @@ class OpenAIImageBackend(ImageBackend):
return str(self._cfg.get("base_url") or "https://api.openai.com/v1").rstrip("/")
def print(self, prompt: str, base_image: str, out_path: str, negative: str = "",
extra_images=None, size: str = "") -> str:
extra_images=None, size: str = "", seed: Optional[int] = None) -> str:
"""img2img 编辑:参考图 base_image+ 可选 extra_images 多参考图)按 prompt 生成新图。
- 平铺服装图:base_image=平铺衣服底图(图3)extra_images=[印花设计稿(图2)]
- 三图模特合成:base_image=模特图(图1)extra_images=[印花设计稿(图2), 平铺底图(图3)]
提交顺序即图1→图2→图3,与提示词中的图片角色一一对应。
size: 显式尺寸覆盖(如 "1504x2000");留空用配置 size(默认 1024x1024)。
size: 显式尺寸覆盖(如 "1536x2048");留空用配置 size(默认 1024x1024)。
seed: 随机种子(None=不传,网关随机;固定值=可复现,网关支持才生效)。
"""
cfg = self._cfg
api_key = cfg.get("api_key", "")
@@ -172,6 +173,8 @@ class OpenAIImageBackend(ImageBackend):
"model": model,
"execution_mode": "sync", # 强制同步(ai-media 等网关默认重负载转异步任务,不稳定)
}
if seed is not None:
data["seed"] = seed
# 提交重试:异步路径不稳定 → 失败重试同步提交(最多 3 次);
# 内容政策拦截(content_policy_violation)多为网关误判 → 等待后重试
last_err: Optional[str] = None
@@ -195,9 +198,11 @@ class OpenAIImageBackend(ImageBackend):
print(f"[img] 第 {attempt + 1} 次提交异步失败,重试同步提交: {e}")
raise RuntimeError(f"图像合成多次提交均失败: {last_err}")
def generate(self, prompt: str, out_path: str, negative: str = "", size: str = "") -> str:
def generate(self, prompt: str, out_path: str, negative: str = "", size: str = "",
seed: Optional[int] = None) -> str:
"""纯文生图:生成白底纯印花设计稿(standalone pure print design)。
size: 显式尺寸覆盖(印花设计统一 1024x1024);留空用配置 size。
seed: 随机种子(None=不传,网关随机;固定值=可复现,网关支持才生效)。
background: 配置 compose.background="transparent" 时传 background 参数 → 透明背景 PNG
gpt-image-1/2 等模型支持;网关不支持该参数时会被忽略或由网关兜底)。"""
cfg = self._cfg
@@ -217,6 +222,8 @@ class OpenAIImageBackend(ImageBackend):
"response_format": "b64_json",
"execution_mode": "sync", # 强制同步(ai-media 等网关默认重负载转异步任务,不稳定)
}
if seed is not None:
data["seed"] = seed
bg = str(cfg.get("background") or "").strip()
if bg:
data["background"] = bg # 如 "transparent"(透明背景 PNG
+51
View File
@@ -135,9 +135,60 @@ class MockBackend:
related += history[:6]
related += trending[4:8]
max_seeds = int(context.get("max_seeds") or 0)
max_style = int(context.get("max_style_seeds", 10) or 10)
max_related = int(context.get("max_related_seeds", 10) or 10)
if max_seeds > 0:
# 不再按类型分:总量均分到 style/related
max_style = max_related = (max_seeds + 1) // 2
return {
"style_seeds": _dedup_limit(style, max_style),
"related_seeds": _dedup_limit(related, max_related),
}
def generate_pinterest_terms(self, context: Dict[str, Any]) -> Dict[str, Any]:
"""规则生成 Pinterest 搜索词(零 API 成本):从种子词池随机取 + 两两组合增加多样性。"""
import random
seeds = [str(s).strip() for s in (context.get("seeds") or []) if str(s).strip()]
used = {str(u).strip().lower() for u in (context.get("used_terms") or [])}
count = int(context.get("count", 10))
pool = [s for s in seeds if s.lower() not in used]
random.shuffle(pool)
terms = pool[:count]
# 不足时用「种子词 + 风格词」组合补足(视觉导向,避免与已用重复)
style_tail = ["t-shirt design", "graphic tee", "print art", "vintage tee", "flat design"]
i = 0
while len(terms) < count and pool:
combo = f"{pool[i % len(pool)]} {style_tail[(i // len(pool)) % len(style_tail)]}"
if combo.lower() not in used and combo not in terms:
terms.append(combo)
i += 1
# 自动追加 " t-shirt design":让 Pinterest 返回真正的 T 恤印花图(更适合作印花设计参考)
terms = [f"{t} t-shirt design" if "t-shirt design" not in t.lower() else t for t in terms]
return {"search_terms": terms}
def analyze_pinterest_images(self, image_paths, term="", country="", on_400=None):
"""规则生成设计简报(零 API 成本):按搜索词启发式推导风格/配色/构图。"""
from ..classify import classify, prompt_suggestion
cat = classify(term)
art_style, palette = derive_style_palette(term, country, category=cat)
motif = prompt_suggestion(term, cat).split(" --no ")[0].split(",")[0].strip()
composition = derive_composition(term, cat)
negative = ("no real people, no likeness of any person, no copyrighted characters, "
"no brand logos, no trademarks, no celebrity, no readable text unless safe")
n = max(1, len(image_paths or []))
paths = list(image_paths or [])
return [{
"topic": term,
"concept": f"(启发式兜底)围绕「{term}」做原创{art_style}风格印花",
"motif": motif,
"art_style": art_style,
"color_palette": palette,
"composition": composition,
"negative_prompt": negative,
"image_prompt": (f"{motif}, {art_style}, {palette}, {composition}, "
f"original {art_style} t-shirt print design"),
# 生图参考:每条简报对应其来源爬取图(mock 按图逐张产出简报,顺序一一对应)
"ref_images": [str(paths[i])] if i < len(paths) else [],
"source": "pinterest",
} for i in range(n)]
+366 -12
View File
@@ -15,9 +15,7 @@ from typing import Any, Dict, List
import requests
# 模型调用一律直连:用户常开 VPN(系统代理),LLM 网关多为国内/自建,走代理会被拦截或变慢。
# 环境变量级 NO_PROXY 双保险(requests/urllib3 均读取),Google 采集(pytrends)不受影响
os.environ.setdefault("NO_PROXY", "*")
os.environ.setdefault("no_proxy", "*")
# 仅请求级 proxies=NO_PROXY 直连,不设置进程级 NO_PROXY 环境变量(避免影响 Google Trends 等外部采集)
from .base import LLMBackend
from graph.paths import runtime_root
@@ -107,6 +105,7 @@ Rules:
# 模板字典按编号存放;TITLE_TEMPLATE_ROUTE 按国家路由到模板编号。
# 模板 1:英语市场(US/GB/AU/MX)→ en_title + cn_title
# 模板 2:日本市场(JP)→ en_title + cn_title + ja_title
# 模板 3:西班牙市场(ES)→ es_title + cn_title
TITLE_TEMPLATES: Dict[str, str] = {
"1": '''# Role
你是一位资深的跨境服装运营专家,精通英语电商的SEO标题逻辑。你的任务是通过分析服装图片,生成高权重的英语-中文商品标题。
@@ -151,15 +150,36 @@ TITLE_TEMPLATES: Dict[str, str] = {
- **Output**: 必须严格返回 JSON 格式,不要包含 Markdown 代码块标记,格式如下:
{"en_title": "Title in English", "cn_title": "中文标题", "ja_title": "日本語タイトル"}''',
"3": '''# Role
你是一位资深的跨境服装运营专家,精通西班牙语电商(Amazon ES, MercadoLibre)的SEO标题逻辑。你的任务是通过分析服装图片,生成高权重的西班牙语-中文商品标题。
# Task
请深度分析图片中的服装特征(品类、风格、材质、剪裁、细节、受众),生成符合西语电商搜索逻辑的中西文标题。
# 当前时间(标题须贴合当下,季节/年份词以此为准)
- **Current time**: {year}-{month}{season}),标题中的年份/季节等时效词必须使用以上时间。
# Analysis Focus (视觉分析重点)
- 品类识别:准确判断西班牙语核心词(如 Vestido, Blusa, Sudadera)和中文核心词(如 连衣裙, 卫衣)。
- 风格定位:判断风格流派(如 Boho, Vintage, Minimalista / 法式, 复古, 极简)。
- 设计细节:提取领型、袖型、裙长等(如 Escote en V, Manga abullonada / V领, 阔袖)。
- 适用场景:推断穿着场景(如 Playa, Oficina, Fiesta / 度假, 通勤, 约会)。
# Constraints (生成规则)
- Spanish Title: 遵循 Amazon ES/MercadoLibre 风格,核心词前置,包含材质、风格、场景等长尾词,符合西语搜索习惯。
- Chinese Title: 遵循淘宝/1688风格,关键词权重递减,包含年份/季节+风格+核心词+卖点+人群。
- Output: 必须严格返回 JSON 格式,不要包含 Markdown 代码块标记,格式如下:
{"es_title": "Título en español", "cn_title": "中文标题"}''',
}
# 国家 → 标题模板编号(JP 路由到模板 2,其余默认模板 1;后续可按国家新增模板 3...
# 国家 → 标题模板编号(JP 路由到模板 2,ES 路由到模板 3其余默认模板 1;后续可按国家新增模板)
TITLE_TEMPLATE_ROUTE: Dict[str, str] = {
"US": "1",
"GB": "1",
"JP": "2",
"AU": "1",
"MX": "1",
"ES": "3",
}
@@ -233,6 +253,143 @@ def build_user_prompt(country, topics, aesthetic_hint):
)
# —— Pinterest 参考模式:搜索词生成(json_schema 结构化 + 动态注入已用词防重复)——
PINTEREST_TERM_SYSTEM_PROMPT = """You are a Pinterest search-term generator for print-on-demand (POD) SHORT-SLEEVE T-SHIRT print design.
You turn seed words into diverse, visual, Pinterest-friendly search terms that will be used to scrape inspiration images
that are DIRECTLY usable as reference for a t-shirt print design.
RULES:
- Generate EXACTLY the requested number of search terms (usually 1 per call).
- Every term MUST be a "t-shirt design" style query: think of it as if the user typed "<concept> t-shirt design" on
Pinterest, so the scraped images are actual t-shirt graphics / flat print artworks, NOT lifestyle photos, scenery,
architecture, food plates, or anything that cannot become a clean chest print.
- Terms MUST be suitable for a SHORT-SLEEVE T-SHIRT PRINT: a flat, graphic, print-ready concept (illustration, mascot,
emblem, pattern, typography, slogan) that works as a chest print between about 15x18 cm and 26x32 cm.
- Prefer a clear central subject with a strong silhouette and balanced composition that reads well as a standalone print.
- AVOID terms that lead to full-scene photos, landscapes, architecture, food plates, or anything that cannot become a clean t-shirt print.
- Terms must be VISUAL / AESTHETIC concepts (style, motif, scene, color) suitable as T-shirt print inspiration.
- Terms must be DIVERSE and NON-OVERLAPPING: never repeat a concept, never give near-synonyms of each other.
- DO NOT repeat or closely paraphrase ANY of the "already used terms" provided in the user message.
- Use the country's local language where natural (e.g. Japanese for JP, Spanish for ES/MX), else English.
- Each term is 2-4 words, concise, no punctuation.
- COPYRIGHT-SAFE: no brands, no logos, no characters, no celebrities, no real persons, no franchises.
- AVOID: politics, religion, hate, violence, sexual content, alcohol, national flags.
Return JSON with the field "search_terms" (array of strings)."""
PINTEREST_TERM_SCHEMA = {
"name": "pinterest_search_terms",
"schema": {
"type": "object",
"properties": {
"search_terms": {
"type": "array",
"items": {"type": "string"},
"description": "Diverse, non-overlapping Pinterest search terms for short-sleeve t-shirt print design inspiration",
}
},
"required": ["search_terms"],
"additionalProperties": False,
},
}
def build_pinterest_term_user_prompt(context: Dict[str, Any]) -> str:
"""动态注入:种子词(灵感)+ 已用搜索词(禁止重复)+ 数量要求(按需每次 1 个)。"""
seeds = context.get("seeds", []) or []
used = context.get("used_terms", []) or []
count = int(context.get("count", 1))
lines = [
f"Country: {context.get('country', '')}",
f"Seed words (inspiration, may combine or extend): {', '.join(seeds)}",
"",
f"Already used terms — DO NOT repeat or paraphrase ANY of these: "
f"{', '.join(used) if used else '(none yet)'}",
"",
f"Generate {count} new, diverse, non-overlapping Pinterest search term(s) "
f"that are suitable for a SHORT-SLEEVE T-SHIRT PRINT design "
f"(flat, graphic, print-ready motif that works as a chest print). "
f"Each term should read like \"<concept> t-shirt design\" so Pinterest returns "
f"actual t-shirt graphics / flat print artwork as reference.",
]
return "\n".join(lines)
# —— Pinterest 参考模式:图片分析 → 原创设计简报(多模态)——
# image_prompt 由 LLM 直接输出完整的英文生图提示词(多模态对图片的描述拼接),
# 不再走「四要素 + 固定模板」装配;尺寸/白底等统一约束段由 prompt_node 自动追加。
PINTEREST_ANALYZE_SYSTEM_PROMPT = """You are a POD (print-on-demand) T-shirt design analyst.
You receive Pinterest reference images for one search term. For each image, extract the VISUAL CONCEPT
(style, mood, motif, color palette, composition) that makes it appealing, then produce an ORIGINAL
T-shirt print design brief that captures that VIBE WITHOUT copying the image.
RULES:
- NEVER copy the image, never reproduce the exact artwork, characters, logos, or any text from it.
- Extract only the abstract style/mood/motif concept as inspiration.
- Produce an original, flat, print-ready design brief (no garment, no model, no background scene).
- COPYRIGHT-SAFE: no brands, no logos, no characters, no celebrities, no real persons, no franchises.
- AVOID: politics, religion, hate, violence, sexual content, alcohol, national flags.
- motif: English, concrete central subject of the print (e.g. "a smiling cat with a fish", "geometric mountain layers").
- art_style: English visual technique (e.g. "clean flat vector", "retro screen print").
- color_palette: English colors (e.g. "sunset orange, cream, dusty blue").
- composition: English layout (e.g. "centered emblem with balanced negative space").
- concept: Chinese, one sentence describing the design idea.
- negative_prompt: what to avoid (real people, likeness, characters, logos, text).
- image_prompt: a COMPLETE, fluent English text-to-image prompt for generating the ORIGINAL flat print
design artwork (the print itself, NOT a garment photo). Describe the motif, art style, colors, layout
and mood in natural English, as a standalone print. Do NOT include garment / shirt / model / mannequin /
background-scene / watermark words. Do NOT mention any size or white-background suffix — a fixed
"small centered print on pure white" suffix will be appended automatically by the system.
Return JSON with the field "designs" (array of objects with keys:
motif, art_style, color_palette, composition, concept, negative_prompt, image_prompt)."""
PINTEREST_ANALYZE_SCHEMA = {
"name": "pinterest_design_briefs",
"schema": {
"type": "object",
"properties": {
"designs": {
"type": "array",
"items": {
"type": "object",
"properties": {
"image_index": {"type": "integer"},
"motif": {"type": "string"},
"art_style": {"type": "string"},
"color_palette": {"type": "string"},
"composition": {"type": "string"},
"concept": {"type": "string"},
"negative_prompt": {"type": "string"},
"image_prompt": {"type": "string"},
},
"required": ["image_index", "motif", "art_style", "color_palette",
"composition", "concept", "negative_prompt", "image_prompt"],
"additionalProperties": False,
},
}
},
"required": ["designs"],
"additionalProperties": False,
},
}
def build_pinterest_analyze_user_prompt(term: str, country: str, image_count: int) -> str:
return (
f"Country: {country}\n"
f"Pinterest search term: {term}\n"
f"Reference images attached: {image_count} images.\n\n"
f"Analyze the attached images and produce {image_count} ORIGINAL design briefs "
f"(one per image), each capturing the visual vibe as an original T-shirt print design. "
f"Do NOT copy the images.\n"
f"For EACH brief you MUST set image_index to the 0-based position of the input image "
f"it was derived from (first image = 0, second = 1, ...). Every image_index from 0 to "
f"{max(image_count - 1, 0)} must appear exactly once — this links each brief to its "
f"source image so the design is generated from the SAME image that was analyzed."
)
def call_openai_compatible(cfg, messages, timeout=90):
base_url = str(cfg.get("base_url", "https://api.openai.com/v1")).rstrip("/")
api_key = cfg.get("api_key", "")
@@ -251,6 +408,41 @@ def call_openai_compatible(cfg, messages, timeout=90):
return data["choices"][0]["message"]["content"]
def call_openai_compatible_structured(cfg, messages, json_schema, timeout=120):
"""调用 LLM 并返回结构化 JSON 文本。
优先 json_schemastrict 结构化输出);部分兼容厂商不支持 json_schema 时
自动回退 json_object(仍要求 JSON)。最终解析交给 _extract_json 兜底。
"""
base_url = str(cfg.get("base_url", "https://api.openai.com/v1")).rstrip("/")
api_key = cfg.get("api_key", "")
model = cfg.get("model", "gpt-4o-mini")
url = f"{base_url}/chat/completions"
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
payload = {
"model": model,
"messages": messages,
"temperature": float(cfg.get("temperature", 0.6)),
"response_format": {
"type": "json_schema",
"json_schema": {
"name": json_schema.get("name", "structured_output"),
"strict": True,
"schema": json_schema.get("schema", json_schema),
},
},
}
try:
resp = requests.post(url, json=payload, headers=headers, timeout=timeout, proxies=NO_PROXY)
resp.raise_for_status()
return resp.json()["choices"][0]["message"]["content"]
except Exception: # noqa: BLE001 兼容厂商不支持 json_schema → 回退 json_object
payload["response_format"] = {"type": "json_object"}
resp = requests.post(url, json=payload, headers=headers, timeout=timeout, proxies=NO_PROXY)
resp.raise_for_status()
return resp.json()["choices"][0]["message"]["content"]
def _retry(func, max_attempts=4, base_delay=4):
last = None
for attempt in range(max_attempts):
@@ -272,9 +464,31 @@ def _extract_json(text):
try:
return json.loads(text)
except json.JSONDecodeError:
m = re.search(r"\{.*\}", text, re.S)
if m:
return json.loads(m.group(0))
# 找第一个 { 到与之平衡的 },逐字符跳过字符串内的花括号,避免贪婪匹配截断 JSON
start = text.find("{")
if start == -1:
raise
depth = 0
in_str = False
esc = False
for i in range(start, len(text)):
ch = text[i]
if in_str:
if esc:
esc = False
elif ch == "\\":
esc = True
elif ch == '"':
in_str = False
else:
if ch == '"':
in_str = True
elif ch == "{":
depth += 1
elif ch == "}":
depth -= 1
if depth == 0:
return json.loads(text[start:i + 1])
raise
@@ -345,15 +559,154 @@ class OpenAICompatBackend(LLMBackend):
_cache_set(cache_key, out)
return out
def generate_title(self, image_path: str, system_prompt: str = "", country: str = "",
fallback_text: str = "") -> Dict[str, Any]:
"""多模态标题生成;图片输入不被模型支持(如 qwen 纯文本模型 400)时,
自动降级为纯文本生成(fallback_text 为商品描述/热点主题)。"""
def generate_pinterest_terms(self, context: Dict[str, Any]) -> Dict[str, Any]:
"""生成 Pinterest 搜索词(json_schema 结构化 + 动态注入已用词防重复)。
context 字段:country, seeds, used_terms, count。
返回 {"search_terms": [str]};失败抛异常由节点兜底(回退种子词)。
"""
cfg = self._cfg
# 防御性上限:已用词最多注入 100 个,防 token 超限(节点层已截断,这里双保险)
ctx = dict(context or {})
used = [str(u) for u in (ctx.get("used_terms") or []) if str(u)]
max_used = int((cfg or {}).get("max_used_terms_in_prompt", 100) or 100)
if max_used > 0:
ctx["used_terms"] = used[-max_used:]
messages = [
{"role": "system", "content": PINTEREST_TERM_SYSTEM_PROMPT},
{"role": "user", "content": build_pinterest_term_user_prompt(ctx)},
]
raw = _retry(lambda: call_openai_compatible_structured(cfg, messages, PINTEREST_TERM_SCHEMA, timeout=120))
parsed = _extract_json(raw)
terms = [str(x).strip() for x in (parsed.get("search_terms", []) or []) if str(x).strip()]
# 自动追加 " t-shirt design":让 Pinterest 返回真正的 T 恤印花图(更适合作印花设计参考)
terms = [f"{t} t-shirt design" if "t-shirt design" not in t.lower() else t for t in terms]
return {"search_terms": terms}
def analyze_pinterest_images(self, image_paths: List[str], term: str, country: str = "",
on_400=None) -> List[Dict[str, Any]]:
"""多模态分析 Pinterest 图片 → 原创设计简报列表。
图片输入不被模型支持(纯文本模型 400)时自动降级为纯文本分析(仅用搜索词)。
失败返回 [],由节点兜底(回退 mock 规则简报)。
on_400: 每次 HTTP 400(且含「内容/图片」)时回调(供调用方累计放弃计数)。
"""
cfg = self._cfg
api_key = cfg.get("api_key", "")
if not api_key:
print("[pinterest_analyze] 未配置 LLM api_key,跳过图片分析")
return []
base_url = str(cfg.get("base_url") or "https://api.openai.com/v1").rstrip("/")
model = cfg.get("model", "gpt-4o-mini")
url = f"{base_url}/chat/completions"
headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"}
# 图片 → base64 data URI(多模态输入)
data_uris: List[str] = []
for p in image_paths:
try:
import base64 as b64
mime = "image/png"
if Path(p).suffix.lower() in (".jpg", ".jpeg"):
mime = "image/jpeg"
data_uris.append(f"data:{mime};base64,{b64.b64encode(Path(p).read_bytes()).decode()}")
except Exception as e: # noqa: BLE001
print(f"[pinterest_analyze] 图片读取失败 {p}: {e}")
def _notify_400(exc) -> None:
if on_400 is None:
return
try:
from graph.pinterest import is_400_content_image
if is_400_content_image(exc):
on_400()
except Exception: # noqa: BLE001
pass
def _call(use_images: bool) -> str:
user_content: List[Any] = [
{"type": "text", "text": build_pinterest_analyze_user_prompt(term, country, len(data_uris))},
]
if use_images:
user_content += [{"type": "image_url", "image_url": {"url": u}} for u in data_uris]
payload = {
"model": model,
"messages": [
{"role": "system", "content": PINTEREST_ANALYZE_SYSTEM_PROMPT},
{"role": "user", "content": user_content},
],
"temperature": 0.5,
"response_format": {
"type": "json_schema",
"json_schema": {
"name": PINTEREST_ANALYZE_SCHEMA["name"],
"strict": True,
"schema": PINTEREST_ANALYZE_SCHEMA["schema"],
},
},
}
try:
resp = requests.post(url, json=payload, headers=headers, timeout=180, proxies=NO_PROXY)
resp.raise_for_status()
return str(resp.json()["choices"][0]["message"].get("content") or "")
except Exception as e: # noqa: BLE001 兼容厂商不支持 json_schema
_notify_400(e)
payload["response_format"] = {"type": "json_object"}
resp = requests.post(url, json=payload, headers=headers, timeout=180, proxies=NO_PROXY)
resp.raise_for_status()
return str(resp.json()["choices"][0]["message"].get("content") or "")
raw = ""
if data_uris:
try:
raw = _call(use_images=True)
except Exception as e: # noqa: BLE001 纯文本模型不支持图片 → 降级纯文本
print(f"[pinterest_analyze] 图片输入失败,降级纯文本分析: {e}")
raw = ""
if not raw:
try:
raw = _call(use_images=False)
except Exception as e: # noqa: BLE001
print(f"[pinterest_analyze] 分析失败: {e}")
return []
try:
parsed = _extract_json(raw)
except Exception as e: # noqa: BLE001
print(f"[pinterest_analyze] 解析失败: {e}")
return []
designs = []
# 兼容 LLM 返回裸数组([...])或 {designs: [...]} 两种结构
if isinstance(parsed, dict):
designs_raw = parsed.get("designs") or []
elif isinstance(parsed, list):
designs_raw = parsed
else:
designs_raw = []
for i, d in enumerate(designs_raw):
if not isinstance(d, dict):
continue
designs.append({
"topic": term,
"concept": str(d.get("concept", "")).strip(),
"motif": str(d.get("motif", "")).strip(),
"art_style": str(d.get("art_style", "")).strip(),
"color_palette": str(d.get("color_palette", "")).strip(),
"composition": str(d.get("composition", "")).strip(),
"negative_prompt": str(d.get("negative_prompt", "")).strip(),
"image_prompt": str(d.get("image_prompt", "")).strip(),
# 生图参考:每条简报对应其来源爬取图(LLM 按图逐张产出简报,顺序一一对应)
"ref_images": [str(image_paths[i])] if i < len(image_paths) else [],
"source": "pinterest",
})
return designs
def generate_title(self, image_path: str, system_prompt: str = "", country: str = "") -> Dict[str, Any]:
"""多模态:分析服装图片,生成商品标题(按国家路由模板)。
系统提示词:显式传入优先;否则按 country 经 TITLE_TEMPLATE_ROUTE 路由到对应模板。
模板 1US/GB/AU/MX)返回 {"en_title","cn_title"}
模板 2(JP)额外返回 {"ja_title"}
模板 2(JP)额外返回 {"ja_title"}
模板 3ES)返回 {"es_title","cn_title"}。
无 key/调用失败返回 {}(调用方兜底不中断)。
"""
cfg = self._cfg
@@ -406,6 +759,7 @@ class OpenAICompatBackend(LLMBackend):
"en_title": str(parsed.get("en_title", "")).strip(),
"cn_title": str(parsed.get("cn_title", "")).strip(),
"ja_title": str(parsed.get("ja_title", "")).strip(),
"es_title": str(parsed.get("es_title", "")).strip(),
}
except Exception as e: # noqa: BLE001
print(f"[titles] 标题生成失败: {e}")
+6
View File
@@ -3,6 +3,9 @@ from .compose_node import compose_node
from .fetch_node import fetch_node
from .filter_node import filter_node
from .oss_upload_node import oss_upload_node
from .pinterest_analyze_node import pinterest_analyze_node
from .pinterest_scrape_node import pinterest_scrape_node
from .pinterest_search_node import pinterest_search_node
from .product_node import product_node
from .prompt_node import prompt_node
from .score_node import score_node
@@ -23,4 +26,7 @@ __all__ = [
"oss_upload_node",
"seed_shot_node",
"template_export_node",
"pinterest_search_node",
"pinterest_scrape_node",
"pinterest_analyze_node",
]
+109 -33
View File
@@ -10,13 +10,25 @@
import json
import time
from pathlib import Path
from typing import Any, Dict, List
from typing import Any, Dict, List, Optional
from graph.validate import with_fallback
RISK_LABEL = {"safe": "✅ 安全", "review": "⚠️ 待复核", "blocked": "⛔ 拦截"}
def _notify_400(on_400, exc) -> None:
"""HTTP 400(且含「内容/图片」)时触发 on_400 回调(供调用方累计放弃计数)。"""
if on_400 is None:
return
try:
from graph.pinterest import is_400_content_image
if is_400_content_image(exc):
on_400()
except Exception: # noqa: BLE001
pass
def _build_briefs_md(briefs: List[Dict[str, Any]], generated_at: str) -> str:
lines = [
"# POD 印花设计简报(LLM 合规筛选 + 生图提示词)",
@@ -96,6 +108,88 @@ def _build_report_md(state: Dict[str, Any]) -> str:
return "\n".join(lines)
def generate_design(ib, brief: Dict[str, Any], design_dir: Path, out_stem: str,
errors: List[Dict[str, Any]] = None,
seed: Optional[int] = None,
on_400=None,
size: str = "1024x1024") -> Optional[str]:
"""生成单张纯印花设计稿(图2)。返回设计稿路径;失败 / 全局 MD5 重复返回 None。
out_stem: 输出文件名主干(不含扩展名),最终文件 = {out_stem}_design.png。
货号模式传 img_code(如 DG000)→ designs/DG000_design.png
旧 compose 模式传 {country}_{idx:02d}(如 JP_01)→ designs/JP_01_design.png。
Pinterest 参考模式:简报带 ref_images(爬取图)→ 用 ib.print() 图生图,
把爬取图 + 多模态分析简报(已封装进 image_prompt)一起发给生图模型;
无参考图或图生图失败 → 回退 ib.generate() 纯文生图。
seed: 随机种子(None=不传,网关随机;固定值=可复现,网关支持才生效)。
on_400: 每次 HTTP 400(且含「内容/图片」)时回调(供调用方累计放弃计数)。
"""
try:
from graph.style_rules import sanitize_image_prompt, ensure_rebrand_hint
img_prompt = sanitize_image_prompt(brief.get("image_prompt", ""))
img_prompt = ensure_rebrand_hint(brief, img_prompt) # review → 原创化魔改引导
out_path = str(design_dir / f"{out_stem}_design.png")
ref_images = [str(p) for p in (brief.get("ref_images") or []) if str(p)]
if ref_images and hasattr(ib, "print"):
try:
# 图生图:以爬取图为参考,按分析简报生成原创设计(不复制原图)
ref_prompt = img_prompt + (
" Create an ORIGINAL, non-copying flat print design inspired ONLY by "
"the reference image's style and mood. Do NOT reproduce the reference "
"image, its characters, logos, or any text.")
out_path = ib.print(
ref_prompt, ref_images[0], out_path,
brief.get("composite_negative", ""),
extra_images=ref_images[1:] or None,
size=size, seed=seed) # 设计稿尺寸按 config compose.design_size
except Exception as e: # noqa: BLE001
print(f"[compose] 图生图(参考图)失败,回退文生图 {brief.get('topic','')}: {e}")
_notify_400(on_400, e)
out_path = ib.generate(
img_prompt, str(design_dir / f"{out_stem}_design.png"),
brief.get("composite_negative", ""), size=size, seed=seed)
else:
out_path = ib.generate(
img_prompt, str(design_dir / f"{out_stem}_design.png"),
brief.get("composite_negative", ""), size=size, seed=seed)
# 全局 MD5 去重:生成了设计后,把 MD5 加入全局过滤(对所有国家生效);
# 已存在的重复设计 → 跳过(不用于产品),避免跨国家重复使用同一设计
from graph.pinterest import design_md5_ok
if not design_md5_ok(out_path):
print(f"[compose] 设计稿 MD5 全局重复,跳过(不用于产品): {out_path}")
return None
return out_path
except Exception as e: # noqa: BLE001
_notify_400(on_400, e)
if errors is not None:
errors.append({"node": "compose", "type": type(e).__name__,
"message": f"设计稿生成失败 {brief.get('topic','')}: {e}", "trace": ""})
print(f"[compose] 设计稿生成失败 {brief.get('topic', '')}: {e}")
return None
def write_compose_reports(state: Dict[str, Any], briefs: List[Dict[str, Any]]) -> None:
"""写 compose 阶段简报报告(design_briefs / composite_prompts / report.md)。
Pinterest 并发生成模式下 compose_node 不再整体执行,由收尾节点调用本函数补写报告。
"""
output_dir = Path(state["output_dir"])
output_dir.mkdir(parents=True, exist_ok=True)
cache_dir = Path(state.get("cache_dir") or output_dir)
generated_at = time.strftime("%Y-%m-%dT%H:%M:%S")
(cache_dir / "design_briefs.json").write_text(
json.dumps({"generated_at": generated_at, "total": len(briefs), "design_briefs": briefs},
ensure_ascii=False, indent=2), encoding="utf-8")
(cache_dir / "design_briefs.md").write_text(
_build_briefs_md(briefs, generated_at), encoding="utf-8")
(cache_dir / "composite_prompts.json").write_text(
json.dumps({"generated_at": generated_at, "total": len(briefs), "composite_prompts": briefs},
ensure_ascii=False, indent=2), encoding="utf-8")
(cache_dir / "composite_prompts.md").write_text(
_build_composite_md(briefs), encoding="utf-8")
(output_dir / "report.md").write_text(_build_report_md(state), encoding="utf-8")
@with_fallback("compose")
def compose_node(state: Dict[str, Any]) -> Dict[str, Any]:
briefs: List[Dict[str, Any]] = state.get("briefs") or []
@@ -105,26 +199,8 @@ def compose_node(state: Dict[str, Any]) -> Dict[str, Any]:
config = state["config"]
country = state.get("country", "")
generated_at = time.strftime("%Y-%m-%dT%H:%M:%S")
# 1) design_briefs.json(缓存 → 根目录,不进时间戳任务文件夹)
(cache_dir / "design_briefs.json").write_text(
json.dumps({"generated_at": generated_at, "total": len(briefs), "design_briefs": briefs},
ensure_ascii=False, indent=2), encoding="utf-8")
# 2) design_briefs.md
(cache_dir / "design_briefs.md").write_text(
_build_briefs_md(briefs, generated_at), encoding="utf-8")
# 3) composite_prompts.json / .md
(cache_dir / "composite_prompts.json").write_text(
json.dumps({"generated_at": generated_at, "total": len(briefs), "composite_prompts": briefs},
ensure_ascii=False, indent=2), encoding="utf-8")
(cache_dir / "composite_prompts.md").write_text(
_build_composite_md(briefs), encoding="utf-8")
# 4) report.md(本次任务报告 → 产物目录)
(output_dir / "report.md").write_text(_build_report_md(state), encoding="utf-8")
# 1-4) 简报报告(design_briefs / composite_prompts / report.md
write_compose_reports(state, briefs)
# 5) 生成纯印花设计稿(图2):前 N 个 safe 简报用 image_prompt 文生图
designs: List[Dict[str, Any]] = []
@@ -153,22 +229,20 @@ def compose_node(state: Dict[str, Any]) -> Dict[str, Any]:
design_dir = output_dir / "designs"
design_dir.mkdir(exist_ok=True)
from graph.style_rules import sanitize_image_prompt, ensure_rebrand_hint
from concurrent.futures import ThreadPoolExecutor, as_completed
# 随机种子:config compose.seed >0 时固定(可复现,网关支持才生效);0/留空=每次随机
_seed = int(compose_cfg.get("seed") or 0)
_seed = _seed if _seed > 0 else None
def _gen_one(i: int, b: Dict[str, Any]):
"""单张设计稿生成(并发线程内调用,每设计一线程)。"""
try:
img_prompt = sanitize_image_prompt(b.get("image_prompt", ""))
img_prompt = ensure_rebrand_hint(b, img_prompt) # review → 原创化魔改引导
out_path = ib.generate(
img_prompt,
str(design_dir / f"{country}_{i:02d}_design.png"),
b.get("composite_negative", ""),
size="1024x1024") # 印花设计统一 1024x1024
return i, b, out_path, None
except Exception as e: # noqa: BLE001
return i, b, None, e
out_path = generate_design(ib, b, design_dir, f"{country}_{i:02d}",
state.get("errors"), seed=_seed,
size=compose_cfg.get("design_size", "1024x1024"))
if out_path is None:
return i, b, None, None
return i, b, out_path, None
targets = [(i, b) for i, b in enumerate(safe_briefs[:design_count], 1)]
# 并发生成:每张设计一个线程(并行调图像网关),数量多时不串行等待
@@ -183,6 +257,8 @@ def compose_node(state: Dict[str, Any]) -> Dict[str, Any]:
state.setdefault("errors", []).append({
"node": "compose", "type": type(err).__name__,
"message": f"设计稿生成失败 {b.get('topic','')}: {err}", "trace": ""})
elif out_path is None:
print(f"[compose] 设计稿跳过(MD5 全局去重): {b.get('topic', '')}")
else:
b["design_path"] = out_path
designs.append({"topic": b.get("topic", ""), "path": out_path, "design_path": out_path})
+30 -20
View File
@@ -2,6 +2,10 @@
按 config.sources 启用各可插拔数据源,汇总统一格式行。
单源失败不影响其它源(内部逐个 try),整体再套 with_fallback 兜底。
缓存策略(用户要求:成功采集就不用缓存):
1. 先用种子词走数据源抓取(Google Trends 等),成功即用新数据;
2. 抓取失败/无结果才回退 output/<国>/collected_keywords.json 旧缓存,保证流水线不中断。
"""
from typing import Any, Dict, List
@@ -18,26 +22,7 @@ def fetch_node(state: Dict[str, Any]) -> Dict[str, Any]:
rows: List[Dict[str, Any]] = []
errors = list(state.get("errors") or [])
# 采集缓存优先:采集(fetch_keywords)成功后写入 output/<国>/collected_keywords.json
# 这里直接用(跳过 Google 重抓),避免重复撞限流;无缓存才走数据源抓取
use_collected = (config.get("fetch") or {}).get("use_collected", True)
if use_collected:
try:
import json as _json
from pathlib import Path as _Path
p = _Path(state.get("cache_dir") or state.get("output_dir", "")) / "collected_keywords.json"
if p.exists():
data = _json.loads(p.read_text(encoding="utf-8"))
cached_rows = data.get("keywords") or []
if cached_rows:
rows = [dict(r) for r in cached_rows] # 已过滤去重的关键词
print(f"[fetch] 使用采集缓存 {len(rows)} 条({country},跳过 Google 抓取)")
stats = dict(state.get("stats") or {})
stats["fetch"] = {"raw_rows": len(rows), "sources": ["collected_cache"], "errors": 0}
return {"raw_rows": rows, "errors": errors, "stats": stats}
except Exception as e: # noqa: BLE001
print(f"[fetch] 读取采集缓存失败(回退数据源): {e}")
# 1) 先尝试数据源抓取(用种子词),成功即用新数据
for name in enabled:
try:
src = get_source(name)
@@ -49,6 +34,31 @@ def fetch_node(state: Dict[str, Any]) -> Dict[str, Any]:
})
print(f"[fetch] 数据源 {name} 失败(跳过): {e}")
if rows:
rows = validate_rows(rows, "fetch")
stats = dict(state.get("stats") or {})
stats["fetch"] = {"raw_rows": len(rows), "sources": enabled, "errors": len(errors)}
return {"raw_rows": rows, "errors": errors, "stats": stats}
# 2) 抓取失败/无结果 → 回退采集缓存(filter 上次写入的 collected_keywords.json
use_collected = (config.get("fetch") or {}).get("use_collected", True)
if use_collected:
try:
import json as _json
from pathlib import Path as _Path
p = _Path(state.get("cache_dir") or state.get("output_dir", "")) / "collected_keywords.json"
if p.exists():
data = _json.loads(p.read_text(encoding="utf-8"))
cached_rows = data.get("keywords") or []
if cached_rows:
rows = [dict(r) for r in cached_rows] # 已过滤去重的关键词
print(f"[fetch] 数据源抓取失败,回退采集缓存 {len(rows)} 条({country}")
stats = dict(state.get("stats") or {})
stats["fetch"] = {"raw_rows": len(rows), "sources": ["collected_cache"], "errors": len(errors)}
return {"raw_rows": rows, "errors": errors, "stats": stats}
except Exception as e: # noqa: BLE001
print(f"[fetch] 读取采集缓存失败(回退数据源): {e}")
rows = validate_rows(rows, "fetch")
stats = dict(state.get("stats") or {})
stats["fetch"] = {"raw_rows": len(rows), "sources": enabled, "errors": len(errors)}
+25
View File
@@ -64,4 +64,29 @@ def filter_node(state: Dict[str, Any]) -> Dict[str, Any]:
kept = validate_rows(kept, "filter")
stats = dict(state.get("stats") or {})
stats["filter"] = {"kept": len(kept), "dropped": dropped_total}
# 把过滤后的热点写入 collected_keywords.json(前台显示完整热点池用):
# 完整流水线(run_country)也会写,保证运行后前台能看到所有未用热点,
# 而不是只显示简报(design_briefs 仅含本次限量生成的热点)。
if kept:
try:
import json as _json
from pathlib import Path as _Path
p = _Path(state.get("cache_dir") or state.get("output_dir", "")) / "collected_keywords.json"
p.parent.mkdir(parents=True, exist_ok=True)
kws = [{"topic": r.get("topic", ""), "source": r.get("source", ""),
"kind": r.get("kind", ""), "raw_score": r.get("raw_score")} for r in kept]
p.write_text(_json.dumps({"country": country,
"collected_at": _datetime_now(),
"keywords": kws}, ensure_ascii=False, indent=2),
encoding="utf-8")
print(f"[filter] 已写入采集缓存 {len(kws)} 条(collected_keywords.json")
except Exception as e: # noqa: BLE001
print(f"[filter] 写入采集缓存失败: {e}")
return {"filtered_rows": kept, "stats": stats}
def _datetime_now() -> str:
import time
return time.strftime("%Y-%m-%dT%H:%M:%S")
+322
View File
@@ -0,0 +1,322 @@
"""Pinterest 参考模式节点 3/3:从图池取图 → 多并发 LLM 分析 → 原创设计简报(pinterest_analyze)。
图池机制:
- 从持久化图池(image_pool.json)取「未消费」图片(md5 不在 used_images.json)。
- 大图先压缩(内存占用过大 → 缩放/重编码)再送 LLM。
- 多并发分析(每批 analyze_per_term 张,并发 analyze_concurrency 线程)。
- 每张被分析的图片 md5 一律拉黑(used_images.json)——合适→产出简报→生成设计(设计 md5 全局拉黑见 compose);
不合适→图片 md5 已拉黑→下一轮自动取下一张,不重复分析。
- 图池无未消费图片时返回空,由路由触发新一轮搜索。
兜底链:LLM 多模态 → 纯文本降级(后端内部)→ mock 规则简报 → 空列表(下游跳过)。
带 with_fallback:任何异常都不中断。
"""
import concurrent.futures
import re
from pathlib import Path
from typing import Any, Dict, List
from graph.llms import get_backend
from graph.nodes.prompt_node import prompt_node
from graph.pinterest import (
compress_image,
load_image_pool,
load_used_images,
pool_unused_images,
save_used_images,
)
from graph.validate import with_fallback
# 明显不适合 T 恤印花的简报主体(启发式过滤;真实判定交给 LLM 搜索词引导)
_BRIEF_UNSUITABLE = re.compile(
r"\b(landscape|panorama|scenery|cityscape|street scene|interior|room decor|"
r"food photography|meal|dinner plate|recipe|makeup|nails|manicure|"
r"weather forecast|map|directions|photorealistic scene|realistic portrait)\b",
re.IGNORECASE,
)
def _brief_suitable(b: Dict[str, Any]) -> bool:
"""简报是否适合做 T 恤印花:非侵权(blocked 拦截)+ 有主体 + 非明显非印花概念。"""
if str(b.get("risk_level") or "").strip().lower() == "blocked":
return False
motif = str(b.get("motif") or "").strip()
if not motif:
return False
if _BRIEF_UNSUITABLE.search(motif):
return False
return True
def _enrich_briefs(raw_briefs: List[Dict[str, Any]], country: str,
existing_topics: List[str] = None) -> List[Dict[str, Any]]:
"""富化原始简报 → screened 格式(唯一 topic / safe / 分类 / 分数),供 prompt_node 装配。
同一搜索词的多张图会产出多条简报,topic 相同 → 追加序号保证唯一
product_node 按 topic 绑定简报,重复 topic 会互相覆盖)。
existing_topics: 已累计简报的 topic 列表;用它初始化计数实现跨轮次去重——
直接搜固定词时每轮 LLM 都返回相同 topic,若每轮从 #1 重新计数,
30 个产品会因 topic 重复只用到前几个唯一设计(其余全复制)。
"""
from graph.classify import classify
import re as _re
seen_topics: Dict[str, int] = {}
# 已累计简报按「基础词」计数(去掉 #N 后缀),保证跨轮次序号连续递增
for t in existing_topics or []:
key = _re.sub(r"\s+#\d+$", "", str(t).strip().lower())
if key:
seen_topics[key] = seen_topics.get(key, 0) + 1
out: List[Dict[str, Any]] = []
for i, b in enumerate(raw_briefs):
if not isinstance(b, dict):
continue
term = str(b.get("topic") or "").strip() or f"pinterest {i + 1}"
base = term
n = seen_topics.get(base.lower(), 0)
seen_topics[base.lower()] = n + 1
topic = base if n == 0 else f"{base} #{n + 1}"
motif = str(b.get("motif") or "").strip() or term
if not motif:
continue
out.append({
"country": country,
"topic": topic,
"risk_level": str(b.get("risk_level") or "safe").strip().lower() or "safe",
"safe_for_print": bool(b.get("safe_for_print", True)),
"suitable_for_print": bool(b.get("suitable_for_print", True)),
"design_category": classify(term),
"concept": str(b.get("concept") or "").strip() or f"围绕「{term}」的原创印花设计",
"motif": motif,
"art_style": str(b.get("art_style") or "").strip(),
"color_palette": str(b.get("color_palette") or "").strip(),
"composition": str(b.get("composition") or "").strip(),
"negative_prompt": str(b.get("negative_prompt") or "").strip(),
"image_prompt": str(b.get("image_prompt") or "").strip(),
"ref_images": [str(p) for p in (b.get("ref_images") or []) if str(p)],
"source_md5": str(b.get("source_md5") or "").strip().lower(),
"slogan": "",
"score": 1.0,
"confidence": 1.0,
"source": "pinterest",
})
return out
@with_fallback("pinterest_analyze")
def pinterest_analyze_node(state: Dict[str, Any]) -> Dict[str, Any]:
country = state["country"]
config = state["config"]
output_dir = state["output_dir"]
errors = list(state.get("errors") or [])
pcfg = config.get("pinterest") or {}
analyze_per_term = int(pcfg.get("analyze_per_term", 1))
concurrency = int(pcfg.get("analyze_concurrency", 3))
max_designs = int(pcfg.get("max_designs", 10))
n_ref = max(1, int(pcfg.get("ref_images_per_design", 1)))
provider = str(pcfg.get("provider") or "openai").strip().lower()
# 按需分析:只取补齐到目标所需的图片数(batch_size 为上限,不超额分析),并按 md5 去重,
# 保证同一图片内容(md5)不会同时被多条简报使用
target = int(state.get("pinterest_target") or 0)
existing = state.get("briefs") or []
remaining = max(0, target - len(existing))
batch_size = int(pcfg.get("analyze_batch", 0))
if batch_size <= 0:
# 自动:一次分析补齐到「目标所需」或「每词简报上限」的较小值(每张图→1条简报),
# 让 pipeline 队列一次有足够任务,时刻保持并发生成(避免每轮只推 6 条导致线程空转)
batch_size = min(remaining, max_designs)
need = min(batch_size, remaining) if remaining > 0 else 0
# 1) 图池取未消费图片(md5 不在 used_images);无 → 返回空,路由触发搜索
pool = load_image_pool(output_dir, country)
used = load_used_images(output_dir, country)
unused = pool_unused_images(pool, used)
if not unused:
print("[pinterest_analyze] 图池无未消费图片,跳过分析(路由将触发新一轮搜索)")
return {"pinterest_briefs": [], "briefs": state.get("briefs") or [],
"errors": errors}
if need <= 0:
print("[pinterest_analyze] 简报已达标,无需分析")
return {"pinterest_briefs": [], "briefs": state.get("briefs") or [],
"errors": errors}
seen_md5: set = set()
batch: List[Dict[str, Any]] = []
for img in unused:
m = str(img.get("md5") or "").strip().lower()
if m and m in seen_md5:
continue # 同一图片内容(md5)不重复分析
seen_md5.add(m)
batch.append(img)
if len(batch) >= need:
break
print(f"[pinterest_analyze] 图池取 {len(batch)} 张未消费图片分析(按需 {need}"
f"池剩余未消费 {len(unused) - len(batch)} 张,已消费 {len(used)} 张)")
def _assign_refs(res: List[Dict[str, Any]], chunk: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
"""按简报的 image_index(LLM 返回)匹配它实际分析的图,写入 source_md5 + ref_images。
全局 id 校验:简报必须带 image_index(对应输入第几张图,0-based);
无 image_indexmock 兜底)→ 回退按顺序;无效/越界/重复 → 丢弃该简报(避免错位)。
这样 analyze_per_term 可 >1 一次分析多张图提速,简报仍严格对应各自的图。
"""
chunk_paths = [img["path"] for img in chunk]
chunk_md5s = [str(img.get("md5") or "").strip().lower() for img in chunk]
used_idx: set = set()
out: List[Dict[str, Any]] = []
for i, b in enumerate(res):
if not isinstance(b, dict):
continue
try:
idx = int(b.get("image_index"))
except (TypeError, ValueError):
idx = i # 无 image_index → 回退按顺序
if idx < 0 or idx >= len(chunk_paths) or idx in used_idx:
print(f"[pinterest_analyze] 简报 image_index={idx} 无效/重复,丢弃(避免图-简报错位)")
continue
used_idx.add(idx)
refs: List[str] = []
for k in range(n_ref):
src = chunk_paths[(idx + k) % len(chunk_paths)]
if src not in refs:
refs.append(src)
b["ref_images"] = refs
b["source_md5"] = chunk_md5s[idx] if idx < len(chunk_md5s) else ""
out.append(b)
return out
# 2) LLM 后端(openai → 真多模态;mock → 规则兜底)
llm = None
if provider != "static":
try:
llm = get_backend(provider)
if hasattr(llm, "bind_config"):
llm.bind_config(config.get("llm_screen") or {})
if provider not in ("mock",) and not getattr(llm, "has_key", False):
print(f"[pinterest_analyze] {provider} 未配置 API key,降级 mock")
llm = get_backend("mock")
except Exception as e: # noqa: BLE001
print(f"[pinterest_analyze] LLM 初始化失败: {e}")
llm = None
# 3) 大图先压缩(内存占用过大 → 缩放/重编码),再按批分组
compressed_map: Dict[str, str] = {}
for img in batch:
compressed_map[img["path"]] = compress_image(img["path"])
chunks: List[List[Dict[str, Any]]] = [
batch[i:i + analyze_per_term] for i in range(0, len(batch), analyze_per_term)
]
# 4) 多并发分析(每线程分析一个 chunk;LLM 后端只读 self._cfg,线程安全)
raw_briefs: List[Dict[str, Any]] = []
def _analyze_chunk(chunk: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
term = str(chunk[0].get("term") or "")
paths = [compressed_map.get(img["path"], img["path"]) for img in chunk]
if llm is not None and hasattr(llm, "analyze_pinterest_images"):
try:
def _on_400():
pipe = state.get("pinterest_pipeline")
if pipe is not None and hasattr(pipe, "record_400"):
if pipe.record_400():
pipe._abort_current_term()
res = llm.analyze_pinterest_images(paths, term, country, on_400=_on_400) or []
# 把每条简报的来源图路径回填为原始图(压缩图仅用于分析,参考图用原图)
return _assign_refs(res, chunk)
except Exception as e: # noqa: BLE001
errors.append({"node": "pinterest_analyze", "type": type(e).__name__,
"message": f"term[{term}] batch@{len(chunk)}: {e}", "trace": ""})
print(f"[pinterest_analyze] 「{term}」分析失败: {e}")
return []
return []
workers = max(1, min(concurrency, len(chunks)))
if len(chunks) > 1:
print(f"[pinterest_analyze] 并发分析 {len(chunks)} 批({workers} 线程,每批 {analyze_per_term} 张)…")
with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as _ex:
_futs = [_ex.submit(_analyze_chunk, c) for c in chunks]
for _f in concurrent.futures.as_completed(_futs):
raw_briefs.extend(_f.result())
# 5) 兜底:LLM 无结果 → mock 规则简报(零 API 成本,保证有设计可生成)
if not raw_briefs:
try:
mock = get_backend("mock")
for chunk in chunks:
term = str(chunk[0].get("term") or "")
paths = [compressed_map.get(img["path"], img["path"]) for img in chunk]
res = mock.analyze_pinterest_images(paths, term, country) or []
_assign_refs(res, chunk)
raw_briefs.extend(res)
print(f"[pinterest_analyze] 兜底:mock 规则简报 {len(raw_briefs)}")
except Exception as e: # noqa: BLE001
print(f"[pinterest_analyze] mock 兜底失败: {e}")
# 6) 本批所有图片 md5 一律拉黑(已消费,不再复用)——合适/不合适都拉黑
for img in batch:
if img.get("md5"):
used.add(str(img["md5"]).lower())
save_used_images(output_dir, country, used)
# 7) 简报过滤:只留适合印花的(有主体 + 非明显非印花概念)
kept: List[Dict[str, Any]] = []
for b in raw_briefs:
if isinstance(b, dict) and _brief_suitable(b):
kept.append(b)
if len(kept) < len(raw_briefs):
print(f"[pinterest_analyze] 简报过滤:{len(raw_briefs)}{len(kept)} 条适合印花")
# 8) 上限 + 去重(同 motif+style 指纹只留一条)
kept = kept[:max_designs]
seen: set = set()
uniq: List[Dict[str, Any]] = []
for b in kept:
fp = f"{str(b.get('motif', '')).strip().lower()}|{str(b.get('art_style', '')).strip().lower()}"
if fp in seen:
continue
seen.add(fp)
uniq.append(b)
kept = uniq
# 9) 富化 → screened → prompt_node 装配提示词 → 标准 briefs(追加到累计,按需截断到目标数)
existing_topics = [str(b.get("topic", "")).strip() for b in (state.get("briefs") or [])]
screened = _enrich_briefs(kept, country, existing_topics)
new_briefs: List[Dict[str, Any]] = []
if screened:
r = prompt_node({**state, "screened": screened})
new_briefs = r.get("briefs") or []
old_count = len(state.get("briefs") or [])
accumulated = list(state.get("briefs") or [])
accumulated.extend(new_briefs)
target = int(state.get("pinterest_target") or 0)
if target > 0 and len(accumulated) > target:
accumulated = accumulated[:target]
print(f"[pinterest_analyze] 简报已达目标 {target} 条,截断多余部分")
# 推送实际新增且保留的简报到并发生成流水线(简报池):边分析边生成设计/三合一/种草图
pushed = accumulated[old_count:]
pipe = state.get("pinterest_pipeline")
if pipe is not None and pushed:
if getattr(pipe, "is_400_aborted", lambda: False)():
print("[pinterest_analyze] 当前种子词 400 超限已放弃,本轮简报不推送")
pushed = []
else:
try:
pipe.add_briefs(pushed)
except Exception as e: # noqa: BLE001
print(f"[pinterest_analyze] 简报入池失败: {e}")
stats = dict(state.get("stats") or {})
stats["pinterest_analyze"] = {
"provider": provider,
"images_analyzed": len(batch),
"pool_unused": len(unused),
"used_images": len(used),
"briefs": len(new_briefs),
"accumulated": len(accumulated),
}
print(f"[pinterest_analyze] 本轮分析 {len(batch)} 张图 → 简报 {len(new_briefs)} 条,"
f"累计 {len(accumulated)} 条({country}")
return {"pinterest_briefs": kept, "briefs": accumulated, "stats": stats, "errors": errors}
+47
View File
@@ -0,0 +1,47 @@
"""Pinterest 并发生成流水线节点 3/3:收尾(pinterest_finalize)。
分析循环结束后:排空简报池、等待后台全部产品完成(设计→三合一→OSS→种草图),
合并产品到 state,补写 compose 简报报告与 products.json,再交给 template_export。
"""
from pathlib import Path
from typing import Any, Dict
from graph.validate import with_fallback
@with_fallback("pinterest_finalize")
def pinterest_finalize_node(state: Dict[str, Any]) -> Dict[str, Any]:
pipe = state.get("pinterest_pipeline")
products: list = []
perr: list = []
if pipe is not None:
products, perr = pipe.finish()
# 合并后台产出的产品(与已存在的合并,避免覆盖)
state_products = list(state.get("product") or [])
state_products.extend(products)
# 补写 compose 简报报告(design_briefs / composite_prompts / report.md
try:
from graph.nodes.compose_node import write_compose_reports
write_compose_reports(state, state.get("briefs") or [])
except Exception as e: # noqa: BLE001
print(f"[pinterest_finalize] 简报报告写入失败: {e}")
# 写 products.jsonproduct 节点原职责)
try:
from graph.nodes.product_node import _write_products
prod_dir = Path(state["output_dir"]) / "product"
prod_dir.mkdir(parents=True, exist_ok=True)
_write_products(prod_dir, state_products)
except Exception as e: # noqa: BLE001
print(f"[pinterest_finalize] products.json 写入失败: {e}")
stats = dict(state.get("stats") or {})
stats["pinterest_pipeline"] = {"products": len(products), "errors": len(perr)}
errors = list(state.get("errors") or []) + perr
oss_seq = getattr(pipe, "oss_seq", state.get("oss_seq", 0)) if pipe is not None \
else state.get("oss_seq", 0)
print(f"[pinterest_finalize] 收尾完成:合并 {len(state_products)} 个产品,"
f"后台错误 {len(perr)}oss_seq={oss_seq}")
return {"product": state_products, "oss_seq": oss_seq, "errors": errors, "stats": stats}
+15
View File
@@ -0,0 +1,15 @@
"""Pinterest 并发生成流水线节点 0/3:初始化简报池(pinterest_init)。
创建 PinterestPipeline(简报池 + 后台并发生成线程),存 state["pinterest_pipeline"]
供 pinterest_analyze 推送简报、pinterest_finalize 收尾。
"""
from typing import Any, Dict
from graph.validate import with_fallback
@with_fallback("pinterest_init")
def pinterest_init_node(state: Dict[str, Any]) -> Dict[str, Any]:
from graph.pinterest_pipeline import PinterestPipeline
pipe = PinterestPipeline(state)
return {"pinterest_pipeline": pipe}
+157
View File
@@ -0,0 +1,157 @@
"""Pinterest 参考模式节点 2/3:爬取图片(pinterest_scrape)。
对 pinterest_search 生成的搜索词(按需:每次 1 个),调 pinterest_scraper.scraper.scrape_pinterest
Playwright 启动本地 Chrome)搜索 Pinterest 并下载图片到 output/pinterest_ref/<国家>/<搜索词>/。
- 单个搜索词失败(未登录/网络/无结果)跳过,不中断整批。
- 只有用了才标记已用:爬取成功(真正用掉该搜索词)→ 持久化已用词;
爬取失败 → 记入本轮 attempted(不持久化),避免同轮重复生成。
- 已爬取过且图片数达标的搜索词跳过(断点续爬,避免重复开 Chrome)。
"""
import concurrent.futures
from pathlib import Path
from typing import Any, Dict, List
from graph.pinterest import (
image_md5,
load_image_pool,
load_used_images,
load_used_terms,
merge_used,
save_image_pool,
save_used_terms,
)
from graph.validate import with_fallback
def _term_dir(output_dir: str, country: str, term: str) -> Path:
safe = "".join(ch for ch in term if ch.isalnum() or ch in "-_ ").strip() or "term"
return Path(output_dir) / "pinterest_ref" / country / safe
def _already_scraped(term_dir: Path) -> bool:
"""该搜索词已爬取过(目录里已有 ≥1 张图)→ 跳过,避免重复开 Chrome。"""
if not term_dir.exists():
return False
return any(p.is_file() and p.suffix.lower() in (".jpg", ".jpeg", ".png", ".webp")
for p in term_dir.iterdir())
@with_fallback("pinterest_scrape")
def pinterest_scrape_node(state: Dict[str, Any]) -> Dict[str, Any]:
terms: List[str] = state.get("pinterest_search_terms") or []
if not terms:
print("[pinterest_scrape] 无搜索词,跳过爬取")
return {"pinterest_images": {}, "errors": state.get("errors") or []}
country = state["country"]
config = state["config"]
output_dir = state["output_dir"]
errors = list(state.get("errors") or [])
pcfg = config.get("pinterest") or {}
images_per_term = int(pcfg.get("images_per_term", 40))
concurrency = int(pcfg.get("scrape_concurrency", 2))
headless = bool(pcfg.get("headless", False))
proxy = pcfg.get("proxy") or None
search_mode = str(pcfg.get("search_mode") or "direct").strip().lower()
# 所有搜索词共享同一个 .chrome_session 登录态目录,Chrome 对同一 user-data-dir 是单例,
# 并发启动会互相抢占导致 "browser has been closed",必须串行爬取。
if concurrency > 1:
print(f"[pinterest_scrape] 共享登录态目录不支持并发,scrape_concurrency 强制为 1(原 {concurrency}")
concurrency = 1
# 一次性探测并校验代理(Pinterest 需代理才能访问;代理失效时给出明确警告,避免逐词静默失败)
if proxy is None:
try:
from pinterest_scraper.pinterest_image_capture import detect_proxy, get_system_proxy, _validate_proxy
proxy = detect_proxy() or get_system_proxy()
except Exception: # noqa: BLE001
proxy = None
if not proxy:
print("[pinterest_scrape] 警告:未检测到代理,将直连下载。国内网络通常无法访问 "
"i.pinimg.com,请先开启代理/VPNClash/v2ray 等)再运行,否则图片下载会全部失败")
elif not _validate_proxy(proxy):
print(f"[pinterest_scrape] 警告:代理 {proxy} 无法连通外网,请检查代理/VPN 是否正常,"
f"否则 Pinterest 将无法访问(爬取会失败)")
results: Dict[str, List[str]] = {}
skipped: List[str] = []
failed: List[str] = []
def _one(term: str) -> None:
term_dir = _term_dir(output_dir, country, term)
# direct 模式:固定关键词允许重复爬取(图池不足时自动再搜,Pinterest 每次可能返回不同图);
# llm 模式:已爬取过且达标 → 跳过(断点续爬,避免重复开 Chrome)
if search_mode != "direct" and _already_scraped(term_dir):
skipped.append(term)
print(f"[pinterest_scrape] 已爬取过(跳过): {term}")
return
try:
from pinterest_scraper.scraper import scrape_pinterest
files = scrape_pinterest(term, count=images_per_term,
save_dir=str(term_dir), proxy=proxy, headless=headless)
results[term] = files
except Exception as e: # noqa: BLE001
failed.append(term)
errors.append({"node": "pinterest_scrape", "type": type(e).__name__,
"message": f"term[{term}]: {e}", "trace": ""})
print(f"[pinterest_scrape] 爬取失败(跳过): {term}: {e}")
print(f"[pinterest_scrape] 开始爬取 {len(terms)} 个搜索词(并发 {concurrency})…")
with concurrent.futures.ThreadPoolExecutor(max_workers=max(1, concurrency)) as ex:
list(ex.map(_one, terms))
# 只有用了才标记已用:爬取成功(含已爬取跳过)的词 → 持久化已用;失败词 → 本轮 attempted(不持久化)
# direct 模式:固定关键词不拉黑(可跨轮复用),仅 llm 模式持久化已用词
used = load_used_terms(output_dir, country)
consumed = (list(results.keys()) + skipped) if search_mode != "direct" else []
new_used = merge_used(used, consumed)
if new_used != used:
save_used_terms(output_dir, country, new_used)
print(f"[pinterest_scrape] 已用搜索词更新:新增 {len(consumed)} 个,累计 {len(new_used)}")
attempted = merge_used(state.get("pinterest_attempted") or [], failed)
# 新爬取的图片注册进图池(含 md5),供分析节点按需取用;
# 进图池前做 md5 校验去重:md5 已存在于图池 / 已拉黑(used_images)/ 本批重复 → 跳过
pool = load_image_pool(output_dir, country)
existing = pool.get("images") or []
known_paths = {str(img.get("path")) for img in existing}
known_md5s = {str(img.get("md5") or "").strip().lower() for img in existing}
used_md5s = load_used_images(output_dir, country)
new_imgs: List[Dict[str, Any]] = []
seen_md5: set = set()
for term, files in results.items():
for f in files:
if f in known_paths:
continue
m = str(image_md5(f) or "").strip().lower()
if not m:
continue
if m in known_md5s or m in used_md5s or m in seen_md5:
print(f"[pinterest_scrape] 图池 md5 去重跳过: {f}")
continue
seen_md5.add(m)
new_imgs.append({"path": f, "md5": m, "term": term})
if new_imgs:
pool["images"] = existing + new_imgs
save_image_pool(output_dir, country, pool)
print(f"[pinterest_scrape] 图池新增 {len(new_imgs)} 张图片,累计 {len(pool['images'])}")
# 新一批图爬取完成 → 重置 400 计数(per 种子词),记录当前种子词
pipe = state.get("pinterest_pipeline")
if pipe is not None and hasattr(pipe, "reset_400"):
for term in results.keys():
pipe.reset_400(term)
total = sum(len(v) for v in results.values())
stats = dict(state.get("stats") or {})
stats["pinterest_scrape"] = {
"terms": len(terms), "scraped": len(results), "skipped": len(skipped),
"failed": len(failed), "images": total, "pool": len(pool.get("images") or []),
}
print(f"[pinterest_scrape] 完成:{len(results)} 个搜索词,共 {total} 张图(跳过 {len(skipped)},失败 {len(failed)}")
return {"pinterest_images": results, "pinterest_attempted": attempted,
"stats": stats, "errors": errors}
+119
View File
@@ -0,0 +1,119 @@
"""Pinterest 参考模式节点 1/3:按需生成单个搜索词(pinterest_search)。
按需搜索:每次只生成 1 个搜索词(LLM json_schema + 动态注入已用词防重复),
带短袖/印花设计引导,保证搜索词适合短袖 T 恤印花。
不在此处持久化已用词 —— 只有爬取成功(真正用掉)才标记已用(见 pinterest_scrape)。
兜底链:LLM json_schema → json_object → 解析失败/调用失败 → 回退种子词池随机抽样。
带 with_fallback:任何异常都不中断,返回空列表由下游跳过。
"""
import random
from typing import Any, Dict, List
from graph.llms import get_backend
from graph.pinterest import (
filter_search_terms,
load_used_terms,
merge_used,
sample_seeds,
)
from graph.validate import with_fallback
@with_fallback("pinterest_search")
def pinterest_search_node(state: Dict[str, Any]) -> Dict[str, Any]:
country = state["country"]
config = state["config"]
output_dir = state["output_dir"]
errors = list(state.get("errors") or [])
pcfg = config.get("pinterest") or {}
if not pcfg.get("enabled", True):
return {"pinterest_search_terms": [], "errors": errors}
provider = str(pcfg.get("provider") or "openai").strip().lower()
search_mode = str(pcfg.get("search_mode") or "direct").strip().lower()
want = int(pcfg.get("search_terms_per_run", 1)) # 每次搜索词数量
seed_sample = int(pcfg.get("seed_sample", 40))
max_used_in_prompt = int(pcfg.get("max_used_terms_in_prompt", 100))
blacklist = config.get("blacklist") or []
# 1) 种子词池 + 已用搜索词 + 本轮已尝试词(防同轮重复,不持久化)
seeds = sample_seeds(country, seed_sample)
used = load_used_terms(output_dir, country)
attempted = [str(t).strip() for t in (state.get("pinterest_attempted") or []) if str(t).strip()]
rounds = int(state.get("pinterest_rounds") or 0) + 1
if not seeds:
print(f"[pinterest_search] {country} 无种子词,跳过搜索词生成")
return {"pinterest_search_terms": [], "pinterest_rounds": rounds, "errors": errors}
# 2) 生成搜索词:种子词不再由 LLM 给出,直接由内置国家种子词库随机抽取(优先未用过),
# 追加 " t-shirt design"(保证 Pinterest 返回真正的 T 恤印花图);llm 模式保留兼容
terms: List[str] = []
if search_mode == "direct":
from graph.pinterest import load_pinterest_seeds
pool = load_pinterest_seeds(country)
used_set = {str(u).strip().lower() for u in merge_used(used, attempted)}
fresh = [s for s in pool if s.lower() not in used_set]
if not fresh:
fresh = pool # 库内词全部用过 → 允许复用(词库有限)
terms = [f"{s} t-shirt design" if "t-shirt design" not in s.lower() else s
for s in random.sample(fresh, min(want, len(fresh)))]
print(f"[pinterest_search] direct 模式:国家种子词库随机抽 {len(terms)} 个 + t-shirt design{country}")
else:
used_llm = merge_used(used, attempted)
if max_used_in_prompt > 0:
used_llm = used_llm[-max_used_in_prompt:]
llm = None
if provider != "static":
try:
llm = get_backend(provider)
if hasattr(llm, "bind_config"):
llm.bind_config(config.get("llm_screen") or {})
if provider not in ("mock",) and not getattr(llm, "has_key", False):
print(f"[pinterest_search] {provider} 未配置 API key,降级 mock")
llm = get_backend("mock")
except Exception as e: # noqa: BLE001
print(f"[pinterest_search] LLM 初始化失败: {e}")
llm = None
if llm is not None and hasattr(llm, "generate_pinterest_terms"):
try:
ctx = {"country": country, "seeds": seeds, "used_terms": used_llm, "count": want}
res = llm.generate_pinterest_terms(ctx)
terms = [str(t).strip() for t in (res.get("search_terms") or []) if str(t).strip()]
print(f"[pinterest_search] LLM 生成搜索词 {len(terms)} 个({country},已用词注入 {len(used_llm)}")
except Exception as e: # noqa: BLE001
print(f"[pinterest_search] LLM 生成失败,回退种子词池: {e}")
terms = []
# 3) 兜底:LLM 无结果 → 种子词池随机抽样
if not terms:
terms = [f"{s} t-shirt design" if "t-shirt design" not in s.lower() else s
for s in random.sample(seeds, min(want, len(seeds)))]
print(f"[pinterest_search] 兜底:从种子词池取 {len(terms)}")
# 4) 全局过滤(已用/本轮已尝试/黑名单/不适合T恤/去重)——注意:不在此处持久化已用词
# direct 模式:抽样时已避开已用词(库内词有限,全部用过后允许复用),不再额外过滤
if search_mode == "direct":
filtered = terms
else:
filtered = filter_search_terms(terms, merge_used(used, attempted), blacklist)
if not filtered and seeds:
# 生成词全被过滤 → 从种子词池补充(同样过滤)
extra = filter_search_terms(seeds, merge_used(used, attempted), blacklist)
filtered = extra[:want]
stats = dict(state.get("stats") or {})
stats["pinterest_search"] = {
"provider": provider,
"round": rounds,
"generated": len(terms),
"filtered": len(filtered),
"used_total": len(used),
}
print(f"[pinterest_search] 第 {rounds} 轮搜索词 {len(filtered)} 个(已用累计 {len(used)}: "
f"{', '.join(filtered[:3])}{'...' if len(filtered) > 3 else ''}")
return {"pinterest_search_terms": filtered, "pinterest_rounds": rounds,
"stats": stats, "errors": errors}
+46 -31
View File
@@ -134,7 +134,7 @@ def _retry_image(fn, *args, attempts: int = 3, backoff=(5, 20, 40), **kwargs):
def _process_spu(
db_path, basemap_root, material_root, category, prod_dir, brief, ib,
spu, sku_code, pcfg, errors, shared_design=None, title_backend=None, country="",
img_code="", model_img=None,
img_code="", model_img=None, design_size="1024x1024", compose_size="1536x2048",
) -> Optional[Dict[str, Any]]:
"""处理单个款号:选色 → 底图 → 设计稿 → (mark==1) 模特 → 合成 → 模板导出。
shared_design: compose 节点生成的纯印花设计稿路径(图2);为 None 时回退本节点 generate。
@@ -210,7 +210,12 @@ def _process_spu(
prompt = ensure_rebrand_hint(brief, sanitize_image_prompt(brief.get("image_prompt", "")))
ib.generate(prompt, design_path,
brief.get("composite_negative", ""),
size="1024x1024") # 印花设计统一 1024x1024
size=design_size) # 设计稿尺寸按 config compose.design_size
# 全局 MD5 去重:生成了设计后,把 MD5 加入全局过滤(对所有国家生效);重复 → 跳过该产品
from graph.pinterest import design_md5_ok
if not design_md5_ok(design_path):
print(f"{tag} 设计稿 MD5 全局重复,跳过该产品: {design_path}")
return None
result["design_path"] = design_path
result["design_from"] = "product"
print(f"{tag} 纯印花设计稿已生成(product 节点): {design_path}")
@@ -221,6 +226,7 @@ def _process_spu(
# 6) 模板选择按 SPU.mark 决定:
# mark==1 → 新三图合成模板 MODEL_WEAR_PROMPT(图1模特 + 图2印花设计 + 图3底图)
# mark!=1 → 旧两图合成模板 composite_prompt(底图 + 印花设计)
# mark==1 统一只做三合一:无模特图时跳过合成,不再回退两图合成(印花+底图)
if int(spu.get("mark") or 0) == 1:
print(f"{tag} SPU {spu['code']} mark=1 → 使用三图合成模板(图1模特+图2印花+图3底图)")
if model_img is not None:
@@ -231,13 +237,14 @@ def _process_spu(
result["model_folder"] = model_img.parent.name
print(f"{tag} 模特图(任务级分配,{model_img.parent.name}/: {model_copy}")
else:
print(f"{tag} material_library 无模特图,回退两图合成(composite_prompt")
print(f"{tag} material_library 无模特图,mark=1 统一只做三合一,跳过合成")
else:
print(f"{tag} SPU {spu['code']} mark={spu.get('mark')} → 使用两图合成模板 composite_prompt(底图+印花)")
# 7) 合成:
# 有模特图 → 三图合成(图1=模特 / 图2=印花设计 / 图3=底图)
# 无模特图 → 两图合成平铺服装图(图3=底图 + 图2=印花设计
# mark=1 无模特图 → 跳过合成(统一只做三合一,不做印花+底图两图合成
# mark!=1 无模特图 → 两图合成平铺服装图(图3=底图 + 图2=印花设计)
if "design_path" not in result:
print(f"{tag} 无设计稿,跳过合成")
elif model_img is not None:
@@ -250,7 +257,7 @@ def _process_spu(
ib.print(wear_prompt, str(model_img), composite_path,
brief.get("composite_negative", ""),
extra_images=[design_path, str(basemap_img)], # 图2印花, 图3底图
size="1504x2000") # 三合一统一 1504x2000
size=compose_size) # 合成图尺寸按 config compose.size
result["composite_path"] = composite_path
print(f"{tag} 三图模特合成图已生成(耗时 {int(time.time()-t0)}s: {composite_path}")
except Exception as e: # noqa: BLE001
@@ -258,7 +265,7 @@ def _process_spu(
print(f"{tag} 三图合成失败,退避重试…: {e}")
retried = _retry_image(ib.print, wear_prompt, str(model_img), composite_path,
brief.get("composite_negative", ""),
extra_images=[design_path, str(basemap_img)], size="1504x2000")
extra_images=[design_path, str(basemap_img)], size=compose_size)
if retried is not None:
result["composite_path"] = composite_path
print(f"{tag} 三图合成重试成功(耗时 {int(time.time()-t0)}s: {composite_path}")
@@ -267,28 +274,32 @@ def _process_spu(
print(f"{tag} 三图合成重试仍失败 → 跳过该产品(不生成标题/不写模板): {e}")
return None
else:
printed_path = str(prod_dir / f"{img_code}_printed.png")
try:
# 两图合成(无模特):用平铺印图文案(wearable_prompt),回退旧 composite_prompt
flat_prompt = (brief.get("wearable_prompt") or "").strip() or brief.get("composite_prompt", "")
ib.print(flat_prompt, str(basemap_img), printed_path,
brief.get("composite_negative", ""),
extra_images=[design_path], # 图2印花
size="1504x2000") # 合成统一 1504x2000
result["printed_path"] = printed_path
print(f"{tag} 平铺服装图已生成(无模特,底图+印花): {printed_path}")
except Exception as e: # noqa: BLE001
print(f"{tag} 平铺服装图失败,退避重试…: {e}")
retried = _retry_image(ib.print, flat_prompt, str(basemap_img), printed_path,
brief.get("composite_negative", ""),
extra_images=[design_path], size="1504x2000")
if retried is not None:
# mark=1 无模特图 → 统一只做三合一,不做印花+底图两图合成
if int(spu.get("mark") or 0) == 1:
print(f"{tag} mark=1 无模特图,跳过合成(统一只做三合一)")
else:
printed_path = str(prod_dir / f"{img_code}_printed.png")
try:
# 两图合成(无模特,mark!=1):用平铺印图文案(wearable_prompt),回退旧 composite_prompt
flat_prompt = (brief.get("wearable_prompt") or "").strip() or brief.get("composite_prompt", "")
ib.print(flat_prompt, str(basemap_img), printed_path,
brief.get("composite_negative", ""),
extra_images=[design_path], # 图2印花
size=compose_size) # 合成图尺寸按 config compose.size
result["printed_path"] = printed_path
print(f"{tag} 平铺服装图重试成功: {printed_path}")
else:
errors.append({"node": "product", "type": type(e).__name__, "message": f"平铺服装图生成失败(重试仍失败): {e}", "trace": ""})
print(f"{tag} 平铺服装图重试仍失败 → 跳过该产品(不生成标题/不写模板): {e}")
return None
print(f"{tag} 平铺服装图已生成(无模特,底图+印花): {printed_path}")
except Exception as e: # noqa: BLE001
print(f"{tag} 平铺服装图失败,退避重试…: {e}")
retried = _retry_image(ib.print, flat_prompt, str(basemap_img), printed_path,
brief.get("composite_negative", ""),
extra_images=[design_path], size=compose_size)
if retried is not None:
result["printed_path"] = printed_path
print(f"{tag} 平铺服装图重试成功: {printed_path}")
else:
errors.append({"node": "product", "type": type(e).__name__, "message": f"平铺服装图生成失败(重试仍失败): {e}", "trace": ""})
print(f"{tag} 平铺服装图重试仍失败 → 跳过该产品(不生成标题/不写模板): {e}")
return None
# 7.2) 多色:单 SPU 多色时每个颜色再执行一次三合一(用各自底图),轮播图按颜色路由
color_composites: List[Dict[str, Any]] = []
@@ -306,7 +317,7 @@ def _process_spu(
ib.print(MODEL_WEAR_PROMPT, str(model_img), cp,
brief.get("composite_negative", ""),
extra_images=[design_path, str(bm)], # 图2印花, 图3该色底图
size="1504x2000") # 三合一统一 1504x2000
size=compose_size) # 合成图尺寸按 config compose.size
col = next((c["color"] for c in colors if c["sku_code"] == sc), sc)
color_composites.append({"sku_code": sc, "color": col, "composite_path": cp})
print(f"{tag} 颜色 {sc}{col})三合一已生成: {cp}")
@@ -321,12 +332,14 @@ def _process_spu(
or result.get("design_path"))
if title_img:
t = title_backend.generate_title(title_img, country=country)
if t.get("en_title") or t.get("cn_title") or t.get("ja_title"):
if t.get("en_title") or t.get("cn_title") or t.get("ja_title") or t.get("es_title"):
result["en_title"] = t.get("en_title", "")
result["cn_title"] = t.get("cn_title", "")
result["ja_title"] = t.get("ja_title", "")
result["es_title"] = t.get("es_title", "")
print(f"{tag} 标题已生成: EN={t.get('en_title','')[:50]}... "
f"CN={t.get('cn_title','')[:30]}... JA={t.get('ja_title','')[:30]}...")
f"CN={t.get('cn_title','')[:30]}... JA={t.get('ja_title','')[:30]}... "
f"ES={t.get('es_title','')[:30]}...")
return result
@@ -508,7 +521,9 @@ def product_node(state: Dict[str, Any]) -> Dict[str, Any]:
r = _process_spu(db_path, basemap_root, material_root, category, prod_dir,
tb, ib, spu, skus, pcfg, errors, design_path, title_backend,
country, img_code=img_code,
model_img=model_assign.get(spu.get("code", "")))
model_img=model_assign.get(spu.get("code", "")),
design_size=str((config.get("compose") or {}).get("design_size") or "1024x1024"),
compose_size=str((config.get("compose") or {}).get("size") or "1536x2048"))
if r:
r["img_code"] = img_code
return r, img_code
+17
View File
@@ -11,6 +11,17 @@ from graph.style_rules import derive_style_palette, derive_composition
from graph.templates import assemble_prompts
from graph.validate import validate_brief, with_fallback
# —— Pinterest 图生图生最终设计稿时统一追加的「小印花 + 纯白底」约束段 ——
# (从热点搜集的文字生图模板里提炼:尺寸缩小、禁止自带背景/满幅)
PINTEREST_PRINT_SUFFIX = (
" standalone pure print design on a pure white background, "
"the print artwork is SMALL and CENTERED with clearly larger white margins around it, "
"print area between about 15x18 cm and 26x32 cm, "
"do NOT fill the entire canvas, do NOT force full-bleed, "
"do NOT add any gradient, texture or background color behind the artwork, "
"no garment, no shirt, no model, no mannequin, no watermark"
)
# 图像生成策略敏感词 → 安全等效描述(生成设计稿前清洗 motif,
# 避免 gpt-image 等内容策略频繁拦截导致"生图限制多")
_IMG_RISKY_SWAP = {
@@ -62,6 +73,12 @@ def prompt_node(state: Dict[str, Any]) -> Dict[str, Any]:
composition = (r.get("composition") or derive_composition(r["topic"], r.get("design_category"))).strip()
prompts = assemble_prompts(motif, art_style, palette, composition, tpls, country)
# Pinterest 简报:直接用 LLM 多模态对图片的描述拼接的 image_prompt(跳过四要素模板),
# 仅追加统一的「小印花 + 纯白底」约束段;wearable/composite 仍用模板装配。
llm_ip = (r.get("image_prompt") or "").strip()
if r.get("source") == "pinterest" and llm_ip:
prompts["image_prompt"] = llm_ip + PINTEREST_PRINT_SUFFIX
print(f"[prompt] Pinterest 简报用 LLM 多模态描述作为 image_prompt(跳过四要素模板): 「{r['topic']}")
# 文字印花(约 30% 概率):简报有 slogan 时,随机注入文字段到设计稿提示词
slogan = (r.get("slogan") or "").strip()
if slogan and random.random() < float(config.get("prompt_templates", {}).get("text_ratio", 0.3)):
+4 -1
View File
@@ -34,7 +34,7 @@ def _cache_key(country: str, provider: str, cfg: Dict[str, Any]) -> str:
避免命中旧参数生成的种子;旧文件保留(不删缓存,取最新)。"""
fp = hashlib.md5(
json.dumps(
{k: cfg.get(k) for k in ("max_style_seeds", "max_related_seeds",
{k: cfg.get(k) for k in ("max_seeds", "max_style_seeds", "max_related_seeds",
"trending_context_limit", "history_limit")},
sort_keys=True, ensure_ascii=False,
).encode("utf-8")
@@ -72,6 +72,7 @@ def seed_node(state: Dict[str, Any]) -> Dict[str, Any]:
cfg = config.get("seed_provider_cfg") or {}
trending_limit = int(cfg.get("trending_context_limit", 15))
history_limit = int(cfg.get("history_limit", 20))
max_seeds = int(cfg.get("max_seeds", 0))
max_style = int(cfg.get("max_style_seeds", 12))
max_related = int(cfg.get("max_related_seeds", 12))
guard = COMMON_RISK_WORDS + [b.lower() for b in (config.get("blacklist") or [])]
@@ -84,6 +85,7 @@ def seed_node(state: Dict[str, Any]) -> Dict[str, Any]:
res = cached
context: Dict[str, Any] = {
"country": country,
"max_seeds": max_seeds,
"max_style_seeds": max_style,
"max_related_seeds": max_related,
}
@@ -91,6 +93,7 @@ def seed_node(state: Dict[str, Any]) -> Dict[str, Any]:
# 1) 收集上下文
context: Dict[str, Any] = {
"country": country,
"max_seeds": max_seeds,
"max_style_seeds": max_style,
"max_related_seeds": max_related,
}

Some files were not shown because too many files have changed in this diff Show More