feat(core): 人物正面氛围图按统一模板后端拼装(全身/纯色背景)

新增 build_person_frontal_prompt:电商真人模特,氛围正面全身照,<脚本提取/用户描述>,自然妆容,柔和影棚光,真实质感,单人,纯色背景。管线人物立绘(generate_base_asset kind=person)与模特库 seed(model_library)都改走它,不再把原始描述裸丢生图、不再半身/简洁背景。三视图 THREE_VIEW_PROMPT 保持不变。

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
seaislee1209
2026-06-17 22:17:47 +08:00
co-authored by Claude Opus 4.8
parent 1ecb186ddf
commit 016c859004
2 changed files with 17 additions and 4 deletions
+3 -3
View File
@@ -13,7 +13,7 @@ import uuid
from io import BytesIO from io import BytesIO
from apps.ai.models import ModelConfig from apps.ai.models import ModelConfig
from apps.ai.services import _asset_preview_url, build_provider, get_default_model from apps.ai.services import _asset_preview_url, build_person_frontal_prompt, build_provider, get_default_model
from apps.assets.models import Asset, AssetFile from apps.assets.models import Asset, AssetFile
from apps.assets.storage import TosStorage from apps.assets.storage import TosStorage
@@ -67,8 +67,8 @@ def generate_model(*, team, user, brief: str, name: str | None = None) -> dict:
raise ValueError(f"当前图像模型 {model_config.provider.name}:{model_config.name} 不支持参考图三视图(image_edit)") raise ValueError(f"当前图像模型 {model_config.provider.name}:{model_config.name} 不支持参考图三视图(image_edit)")
label = name or brief[:16] label = name or brief[:16]
# 1) 9:16 氛围正面图 # 1) 9:16 氛围正面图(画幅由 size 控制;提示词用统一的人物正面模板:全身 / 纯色背景)
frontal_prompt = f"{brief},电商真人模特,9:16竖屏氛围正面半身,自然妆容,柔和影棚光,真实质感,单人,简洁背景" frontal_prompt = build_person_frontal_prompt(brief)
resp = provider.image_generation(model=model_config.name, prompt=frontal_prompt, size="1024x1536") resp = provider.image_generation(model=model_config.name, prompt=frontal_prompt, size="1024x1536")
frontal = _store_model_asset( frontal = _store_model_asset(
team=team, user=user, media=provider.extract_first_media_url(resp), team=team, user=user, media=provider.extract_first_media_url(resp),
+14 -1
View File
@@ -464,6 +464,14 @@ def build_platform_cover_prompt_refs(product, has_model: bool, base_prompt: str
return " ".join(lines) return " ".join(lines)
def build_person_frontal_prompt(description: str = "") -> str:
"""人物正面氛围图提示词:把脚本提取(或用户输入)的人物描述包成统一模板。
用户钦定格式:电商真人模特,氛围正面全身照,<描述>,自然妆容,柔和影棚光,真实质感,单人,纯色背景。"""
desc = (description or "").strip()
inner = f"{desc}" if desc else ""
return f"电商真人模特,氛围正面全身照,{inner}自然妆容,柔和影棚光,真实质感,单人,纯色背景"
def generate_base_asset(*, project, user, kind: str, prompt: str, label: str = "", group_id: str | None = None) -> AITask: def generate_base_asset(*, project, user, kind: str, prompt: str, label: str = "", group_id: str | None = None) -> AITask:
"""提交基础资产生成(**异步**):Web 请求只建 RESERVED 任务 + 预留额度(秒级), """提交基础资产生成(**异步**):Web 请求只建 RESERVED 任务 + 预留额度(秒级),
慢出图(文生图 / 商品 image_edit)交给 Celery worker(run_base_asset_task)跑。 慢出图(文生图 / 商品 image_edit)交给 Celery worker(run_base_asset_task)跑。
@@ -480,7 +488,12 @@ def generate_base_asset(*, project, user, kind: str, prompt: str, label: str = "
# 无主图或当前模型不支持 image_edit → 回落纯文生图(仅凭商品名脑补,不保证还原真实包装)。 # 无主图或当前模型不支持 image_edit → 回落纯文生图(仅凭商品名脑补,不保证还原真实包装)。
product_ref_url = _product_cover_url(project.product) if kind == BaseAssetGroup.Kind.PRODUCT else "" product_ref_url = _product_cover_url(project.product) if kind == BaseAssetGroup.Kind.PRODUCT else ""
use_edit = bool(product_ref_url) and hasattr(provider, "image_edit") use_edit = bool(product_ref_url) and hasattr(provider, "image_edit")
gen_prompt = build_product_triview_prompt_refs(project.product, prompt) if use_edit else prompt if use_edit:
gen_prompt = build_product_triview_prompt_refs(project.product, prompt)
elif kind == BaseAssetGroup.Kind.PERSON:
gen_prompt = build_person_frontal_prompt(prompt) # 人物立绘:包成「电商真人模特/正面全身/纯色背景」统一模板
else:
gen_prompt = prompt
payload = { payload = {
"model": model_config.name, "endpoint": model_config.endpoint, "prompt": gen_prompt, "model": model_config.name, "endpoint": model_config.endpoint, "prompt": gen_prompt,
"kind": kind, "label": label or "", "group_id": str(group_id) if group_id else "", "kind": kind, "label": label or "", "group_id": str(group_id) if group_id else "",