170 lines
8.4 KiB
Python
170 lines
8.4 KiB
Python
"""阿里通义(wan* 万相 / qwen* 千问)提示词:国产"主体参考"语义。
|
|
|
|
生图 API 把参考图当商品锚(subject reference)、prompt 当场景描述,
|
|
风格词/文字商品描述不会反噬商品本体,负面清单也可以安全写入 prompt。
|
|
豆包(doubao.py)与此语义一致,直接复用本模块装配。
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from .common import (
|
|
STYLE_SETS, TEXT_RENDER, requirements_block, resolve_style, selling_point_lines,
|
|
)
|
|
|
|
# ── 公共组件(主体参考语义专用)────────────────────────────────────────────
|
|
|
|
QUALITY = (
|
|
"Shot on Sony A7R V with 85mm lens at f/2.0, ultra-detailed, photorealistic, "
|
|
"8K commercial image quality, professional retouching."
|
|
)
|
|
|
|
PRODUCT_REF_LOCK = (
|
|
"CRITICAL: The product must look EXACTLY the same as in the reference image — "
|
|
"identical silhouette, proportions, colors, print pattern, stitching and every design detail. "
|
|
"Only the background, camera angle, lighting and styling may change. "
|
|
"Do not redesign, add or remove any element of the product."
|
|
)
|
|
|
|
DEFAULT_NEGATIVE_INTENT = (
|
|
"no AI-generated look, no CGI quality, no plastic appearance, no watermark, "
|
|
"no distorted text, no deformed product, no extra limbs, no blurry areas"
|
|
)
|
|
|
|
# ── 各图类型 Prompt ───────────────────────────────────────────────────────
|
|
|
|
def _prompt_white_bg(ctx: dict, style: dict, lang: str) -> str:
|
|
return (
|
|
f"E-commerce main product image on pure white background (RGB 255,255,255), "
|
|
f"product \"{ctx['title']}\" centered and filling about 85% of the frame, "
|
|
f"front view, even shadowless studio lighting with a faint natural contact shadow, "
|
|
f"{style['tone']}. No text, no props, no background elements. {QUALITY} {PRODUCT_REF_LOCK}"
|
|
)
|
|
|
|
def _prompt_key_features(ctx: dict, style: dict, lang: str) -> str:
|
|
sp = selling_point_lines(ctx, lang) or ctx["title"]
|
|
return (
|
|
f"E-commerce key-features infographic for product \"{ctx['title']}\", square layout: "
|
|
f"product on the left two-thirds ({style['bg']}), right column lists 3 feature callouts "
|
|
f"with minimal line icons, thin leader lines pointing to product details. "
|
|
f"Feature callouts: {sp}. {style['tone']}. {TEXT_RENDER[lang]} {QUALITY} {PRODUCT_REF_LOCK}"
|
|
)
|
|
|
|
def _prompt_selling_pt(ctx: dict, style: dict, lang: str) -> str:
|
|
sp = selling_point_lines(ctx, lang, 1) or ctx["title"]
|
|
return (
|
|
f"Single-selling-point e-commerce poster for product \"{ctx['title']}\": "
|
|
f"hero product close-up at dynamic angle ({style['bg']}), one large bold headline "
|
|
f"about \"{sp}\", generous negative space, one small magnified detail circle "
|
|
f"highlighting material or craft. {style['tone']}. {TEXT_RENDER[lang]} {QUALITY} {PRODUCT_REF_LOCK}"
|
|
)
|
|
|
|
def _prompt_material(ctx: dict, style: dict, lang: str) -> str:
|
|
return (
|
|
f"Macro material close-up of product \"{ctx['title']}\": extreme detail shot revealing "
|
|
f"fabric weave / surface texture / stitching / finish, shallow depth of field, "
|
|
f"raking light across the surface, {style['tone']}. Small caption label in corner. "
|
|
f"{TEXT_RENDER[lang]} {QUALITY} {PRODUCT_REF_LOCK}"
|
|
)
|
|
|
|
def _prompt_lifestyle(ctx: dict, style: dict, lang: str) -> str:
|
|
bg = f" ({style['bg']})" if style.get("bg") else ""
|
|
return (
|
|
f"Lifestyle in-context scene for product \"{ctx['title']}\": the product is naturally "
|
|
f"used / placed in a real environment{bg}, realistic human-scale surroundings, "
|
|
f"soft daylight, authentic candid mood, product remains the clear visual focus. "
|
|
f"{style['tone']}. {TEXT_RENDER[lang]} {QUALITY} {PRODUCT_REF_LOCK}"
|
|
)
|
|
|
|
def _prompt_multi_scene(ctx: dict, style: dict, lang: str) -> str:
|
|
sp = selling_point_lines(ctx, lang)
|
|
return (
|
|
f"Triptych multi-scene e-commerce image for product \"{ctx['title']}\": three vertical panels "
|
|
f"separated by thin gutters, each panel shows the SAME product in a different usage scene "
|
|
f"(e.g. home interior / outdoor street / office desk), consistent color grading across panels. "
|
|
f"Panel captions: {sp}. {style['tone']}. {TEXT_RENDER[lang]} {QUALITY} {PRODUCT_REF_LOCK}"
|
|
)
|
|
|
|
def _prompt_ecommerce_detail(ctx: dict, style: dict, lang: str) -> str:
|
|
sp = selling_point_lines(ctx, lang) or ctx["title"]
|
|
params = ctx["params_line"]
|
|
return (
|
|
f"E-commerce detail-page hero section for product \"{ctx['title']}\", square layout: "
|
|
f"top half is a hero banner with the product at a 3/4 angle ({style['bg']}); "
|
|
f"bottom half is a clean spec card listing 3 feature rows with line icons"
|
|
+ (f" (specs: {params})" if params else "")
|
|
+ f" and one highlighted row: {sp}. {style['tone']}. {TEXT_RENDER[lang]} {QUALITY} {PRODUCT_REF_LOCK}"
|
|
)
|
|
|
|
def _prompt_size_chart(ctx: dict, style: dict, lang: str) -> str:
|
|
dims = ctx["params_line"]
|
|
return (
|
|
f"Product size chart infographic for \"{ctx['title']}\": product shown in clean front and side views "
|
|
f"on light background, with thin measurement annotation lines (arrows) marking length, width and height, "
|
|
f"measurement values rendered next to each line"
|
|
+ (f" (known specs: {dims})" if dims else "")
|
|
+ f", small caption row, precise technical drawing aesthetic. {style['tone']}. "
|
|
f"{TEXT_RENDER[lang]} {QUALITY} {PRODUCT_REF_LOCK}"
|
|
)
|
|
|
|
def _prompt_sku_collection(ctx: dict, style: dict, lang: str) -> str:
|
|
return (
|
|
f"Colorway collection image for product \"{ctx['title']}\": the SAME product in all its color/variant "
|
|
f"options arranged in a neat equal grid (2-4 items per row), each colorway with a small label chip below it, "
|
|
f"consistent lighting and scale across all items, clean e-commerce presentation. "
|
|
f"{style['tone']}. {TEXT_RENDER[lang]} {QUALITY} {PRODUCT_REF_LOCK}"
|
|
)
|
|
|
|
def _prompt_custom(ctx: dict, style: dict, lang: str, extra: dict) -> str:
|
|
hint = (extra.get("prompt_hint") or "").strip()
|
|
purpose = extra.get("title") or ""
|
|
detail = extra.get("detail") or ""
|
|
bg = f" {style['bg']} as environment." if style.get("bg") else ""
|
|
composed = (
|
|
f"E-commerce marketing image for product \"{ctx['title']}\""
|
|
+ (f" — {purpose}" if purpose else "")
|
|
+ (f": {detail}" if detail else "")
|
|
+ "."
|
|
)
|
|
if hint:
|
|
composed += f" Composition: {hint}."
|
|
return f"{composed}{bg} {style['tone']}. {TEXT_RENDER[lang]} {QUALITY} {PRODUCT_REF_LOCK}"
|
|
|
|
_PROMPT_BUILDERS = {
|
|
"white_bg": _prompt_white_bg,
|
|
"key_features": _prompt_key_features,
|
|
"selling_pt": _prompt_selling_pt,
|
|
"material": _prompt_material,
|
|
"lifestyle": _prompt_lifestyle,
|
|
"multi_scene": _prompt_multi_scene,
|
|
"ecommerce_detail": _prompt_ecommerce_detail,
|
|
"size_chart": _prompt_size_chart,
|
|
"sku_collection": _prompt_sku_collection,
|
|
}
|
|
|
|
|
|
def build_prompt(type_id: str, ctx: dict, style_set: int, lang: str, extra: dict | None = None,
|
|
style_prompt: str | None = None, requirements: str | None = None) -> str:
|
|
"""构造指定图类型的完整生图 prompt(主体参考语义)。
|
|
|
|
extra: 方案项信息 {title, detail, prompt_hint}——custom 类型必需,
|
|
预设类型也会把 prompt_hint 作为构图补充注入。
|
|
style_prompt: 用户改写的风格提示词,覆盖 style_set 内置模板(tone/bg 整体替换)。
|
|
requirements: 生图要求(最高优先级,强制约束),置于 prompt 最前面,
|
|
声明覆盖一切冲突指令,用户可在此输入强制要求。
|
|
"""
|
|
style = resolve_style(style_set, style_prompt)
|
|
extra = extra or {}
|
|
if type_id == "custom":
|
|
prompt = _prompt_custom(ctx, style, lang, extra)
|
|
else:
|
|
builder = _PROMPT_BUILDERS.get(type_id)
|
|
if builder is None:
|
|
raise ValueError(f"未知图类型: {type_id}")
|
|
prompt = builder(ctx, style, lang)
|
|
hint = (extra.get("prompt_hint") or "").strip()
|
|
if hint:
|
|
prompt = prompt.rstrip(".") + f". Additional composition guidance: {hint}."
|
|
req = requirements_block(requirements)
|
|
if req:
|
|
prompt = f"{req} {prompt}"
|
|
return prompt + ". " + DEFAULT_NEGATIVE_INTENT
|