"""内衣品类(文胸)测试:对比两条路线能不能出图。 路线A · 真人上身(穿戴类) —— 验证 gpt-image-2 内容审核会不会拦(safety=[sexual]) 路线B · 隐形人台/平铺(无真人) —— 验证绕开审核的安全做法 跑法: .venv/bin/python tryon_underwear_test.py 产物: /Users/maidong/Desktop/zyc/underwear_test """ import os import django os.environ.setdefault("DJANGO_SETTINGS_MODULE", "airshelf.settings.development") django.setup() from apps.products.models import Product # noqa: E402 from apps.assets.models import Asset # noqa: E402 from apps.ai.models import ModelConfig # noqa: E402 from apps.ai.services import ( # noqa: E402 get_default_model, get_image_provider, _asset_preview_url, _ratio_to_image_size, ) from apps.ai.providers.volcano import VolcanoArkProvider # noqa: E402 PRODUCT_ID = "42078cdc-8714-4fc7-be5c-6aa42b7fc995" # 棉居莫代尔无痕内衣(真实主图) MODEL_ID = "ad362810-cf3e-49c0-9426-8142a74b75b2" # 一位真人模特 RATIO = "3:4" OUT_DIR = "/Users/maidong/Desktop/zyc/underwear_test" # 路线A · 真人上身(穿戴类从句) PROMPT_ON_BODY = ( "参考图1是「{name}」的真实商品图,是商品外观的唯一依据。参考图2是出镜模特。" "请生成参考图2中这位模特真实穿着参考图1中这件内衣的电商详情页效果图,得体、健康、非裸露," "覆盖充分,运动内衣风格,商品的颜色、版型、领口、肩带、纹样、Logo 必须与参考图1严格一致。" "模特五官/发型/肤色/身形与参考图2一致,不要换人。真实电商摄影,自然光,干净背景,单人,{ratio} 构图。" " 请规避:不要裸露,不要性暗示,不要换人,不要改商品设计与颜色,不要乱码文字,不要水印。" ) # 路线B · 隐形人台 / 平铺(无真人,绕开审核) PROMPT_GHOST = ( "参考图1是「{name}」的真实商品图。请生成该内衣的电商主图:采用隐形人台(ghost mannequin)立体悬浮效果," "衣服呈现被穿着时的自然立体版型与轮廓,但画面中没有真人、没有人体、不出现任何皮肤或身体部位。" "商品的颜色、版型、肩带、领口、纹理、Logo 必须与参考图1严格一致,不要重新设计。" "柔和自然光,干净纯净背景,商品居中,细节清晰,高分辨率,{ratio} 构图。" " 请规避:不要出现人、不要皮肤、不要模特、不要改商品颜色与版型、不要乱码文字、不要水印。" ) def run(provider, model_name, label, prompt, images, size): print(f"\n━━━ {label} ━━━\n{prompt}\n图数={len(images)}") try: resp = provider.image_edit(model=model_name, prompt=prompt, images=images, size=size) media = provider.extract_first_media_url(resp) fileobj, ct = VolcanoArkProvider.media_to_bytes(media) ext = ".jpg" if "jpeg" in ct else (".webp" if "webp" in ct else ".png") path = os.path.join(OUT_DIR, f"{label}{ext}") with open(path, "wb") as f: f.write(fileobj.getvalue()) print(f"✅ 出图成功 → {path}") except Exception as exc: # noqa: BLE001 msg = str(exc) flagged = any(k in msg.lower() for k in ("moderation", "safety", "sexual", "blocked", "content_policy", "rejected")) print(f"❌ 失败{' · 命中内容审核' if flagged else ''}: {msg[:600]}") def main(): os.makedirs(OUT_DIR, exist_ok=True) p = Product.objects.get(id=PRODUCT_ID) product_url = _asset_preview_url(p.cover_asset) model_url = _asset_preview_url(Asset.objects.get(id=MODEL_ID)) mc = get_default_model(ModelConfig.Capability.IMAGE) provider = get_image_provider(mc) size = _ratio_to_image_size(RATIO) print(f"商品: {p.title} | 类目: {p.category}") print(f"模型: {mc.provider.name}:{mc.name}") print(f"商品图: {product_url[:80]}") # 路线A:真人上身(商品图 + 模特图) run(provider, mc.name, "A_真人上身", PROMPT_ON_BODY.format(name=p.title, ratio=RATIO), [product_url, model_url], size) # 路线B:隐形人台(仅商品图) run(provider, mc.name, "B_隐形人台", PROMPT_GHOST.format(name=p.title, ratio=RATIO), [product_url], size) print(f"\n完成。产物: {OUT_DIR}") if __name__ == "__main__": main()