Upload idol_generator.py
Browse files- idol_generator.py +800 -0
idol_generator.py
ADDED
|
@@ -0,0 +1,800 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import random
|
| 2 |
+
from typing import Dict, List, Optional
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
class IdolPhotoGenerator:
|
| 6 |
+
def __init__(self):
|
| 7 |
+
# 初始化所有类别的词库
|
| 8 |
+
self.vocab = self._initialize_vocabulary()
|
| 9 |
+
|
| 10 |
+
def _initialize_vocabulary(self) -> Dict[str, List[str]]:
|
| 11 |
+
"""初始化写真描述词库"""
|
| 12 |
+
return {
|
| 13 |
+
# 地点 (50个选项)
|
| 14 |
+
"locations": [
|
| 15 |
+
"东京表参道梧桐树街道",
|
| 16 |
+
"京都伏见稻荷千本鸟居",
|
| 17 |
+
"北海道富良野薰衣草田",
|
| 18 |
+
"冲绳宫古岛翡翠海滩",
|
| 19 |
+
"轻井泽森林教堂",
|
| 20 |
+
"镰仓高校前海岸线",
|
| 21 |
+
"大阪环球影城哈利波特区",
|
| 22 |
+
"白川乡合掌造村落",
|
| 23 |
+
"奈良公园鹿群中",
|
| 24 |
+
"六本木之丘观景台",
|
| 25 |
+
"涩谷全向十字路口",
|
| 26 |
+
"隅田川花火大会现场",
|
| 27 |
+
"代代木公园樱花树下",
|
| 28 |
+
"横滨红砖仓库广场",
|
| 29 |
+
"箱根芦之湖海盗船上",
|
| 30 |
+
"浅草寺雷门灯笼前",
|
| 31 |
+
"皇居东御苑碎石路",
|
| 32 |
+
"竹下通可丽饼店前",
|
| 33 |
+
"台场彩虹摩天轮车厢",
|
| 34 |
+
"明治神宫祈福木牌处",
|
| 35 |
+
"上野动物园熊猫馆",
|
| 36 |
+
"新宿御苑日式庭院",
|
| 37 |
+
"池袋太阳城水族馆",
|
| 38 |
+
"原宿竹下通彩虹棉花糖店",
|
| 39 |
+
"秋叶原女仆咖啡厅",
|
| 40 |
+
"筑地市场金枪鱼拍卖场",
|
| 41 |
+
"银座三越百货橱窗前",
|
| 42 |
+
"谷中银座夕阳阶梯",
|
| 43 |
+
"自由之丘甜品店内",
|
| 44 |
+
"下北泽古着店试衣间",
|
| 45 |
+
"吉祥寺井之头公园",
|
| 46 |
+
"三鹰之森吉卜力美术馆",
|
| 47 |
+
"东京站丸之内出口",
|
| 48 |
+
"东京塔特别观景层",
|
| 49 |
+
"晴空塔天空回廊",
|
| 50 |
+
"月岛文字烧小巷",
|
| 51 |
+
"两国国技馆相扑赛场",
|
| 52 |
+
"柴又帝释天参道",
|
| 53 |
+
"深大寺荞麦面屋",
|
| 54 |
+
"高尾山登山缆车",
|
| 55 |
+
"江之岛展望灯塔",
|
| 56 |
+
"镰仓文学馆玫瑰园",
|
| 57 |
+
"热海亲水公园",
|
| 58 |
+
"伊豆仙人掌动物园",
|
| 59 |
+
"日光东照宫阳明门",
|
| 60 |
+
"郡山鹤城天守阁",
|
| 61 |
+
"松本城黑漆城墙",
|
| 62 |
+
"金泽兼六园雪吊前",
|
| 63 |
+
"飞驒高山古街酒藏",
|
| 64 |
+
"熊本城樱花广场",
|
| 65 |
+
"巴黎埃菲尔铁塔观景平台",
|
| 66 |
+
"伦敦大本钟前红色电话亭",
|
| 67 |
+
"纽约时代广场霓虹灯下",
|
| 68 |
+
"罗马斗兽场拱门前",
|
| 69 |
+
"巴塞罗那圣家堂彩窗光影中",
|
| 70 |
+
"威尼斯圣马可广场鸽子群",
|
| 71 |
+
"布拉格查理大桥雕像旁",
|
| 72 |
+
"阿姆斯特丹运河游船上",
|
| 73 |
+
"维也纳金色大厅台阶",
|
| 74 |
+
"瑞士少女峰滑雪场",
|
| 75 |
+
"希腊圣托里尼蓝顶教堂",
|
| 76 |
+
"冰岛蓝湖温泉雾气中",
|
| 77 |
+
"芬兰玻璃极光屋",
|
| 78 |
+
"挪威松恩峡湾观景台",
|
| 79 |
+
"莫斯科红场圣瓦西里教堂前",
|
| 80 |
+
"里斯本28号电车车厢",
|
| 81 |
+
"布达佩斯塞切尼温泉",
|
| 82 |
+
"哥本哈根新港彩色房屋",
|
| 83 |
+
"斯德哥尔摩地铁艺术站",
|
| 84 |
+
"都柏林圣三一学院图书馆",
|
| 85 |
+
"首尔明洞购物街",
|
| 86 |
+
"济州岛汉拿山茶园",
|
| 87 |
+
"釜山海云台沙滩",
|
| 88 |
+
"首尔N首尔塔爱情锁墙",
|
| 89 |
+
"台北101观景台",
|
| 90 |
+
"九份山城红灯笼街",
|
| 91 |
+
"垦丁白沙湾",
|
| 92 |
+
"香港维多利亚港夜景",
|
| 93 |
+
"澳门大三巴牌坊前",
|
| 94 |
+
"新加坡滨海湾金沙无边泳池",
|
| 95 |
+
"新加坡植物园交响乐湖",
|
| 96 |
+
"吉隆坡双子塔空中桥梁",
|
| 97 |
+
"曼谷大皇宫玉佛寺",
|
| 98 |
+
"清迈素贴山双龙寺",
|
| 99 |
+
"巴厘岛乌布丛林秋千",
|
| 100 |
+
"岘港巴拿山黄金桥",
|
| 101 |
+
"河内还剑湖龟塔",
|
| 102 |
+
"吴哥窟日出剪影",
|
| 103 |
+
"悉尼歌剧院贝壳前",
|
| 104 |
+
"墨尔本布莱顿彩虹小屋",
|
| 105 |
+
"皇后镇极限运动中心",
|
| 106 |
+
"大堡礁心形礁水上飞机",
|
| 107 |
+
"罗托鲁瓦地热公园",
|
| 108 |
+
"斐济珊瑚海岸",
|
| 109 |
+
"塔希提岛水上屋",
|
| 110 |
+
"上海外滩万国建筑群",
|
| 111 |
+
"北京故宫太和殿广场",
|
| 112 |
+
"杭州西湖断桥残雪",
|
| 113 |
+
"张家界国家森林公园",
|
| 114 |
+
"桂林漓江竹筏上",
|
| 115 |
+
"西安大唐不夜城",
|
| 116 |
+
"重庆太古里",
|
| 117 |
+
"厦门鼓浪屿钢琴码头",
|
| 118 |
+
"南京秦淮河畔",
|
| 119 |
+
"苏州拙政园水廊",
|
| 120 |
+
"大理洱海白色桌椅",
|
| 121 |
+
"丽江古城四方街",
|
| 122 |
+
"青海茶卡盐湖天空之镜",
|
| 123 |
+
"三亚亚龙湾白沙滩",
|
| 124 |
+
"哈尔滨冰雪大世界冰雕前",
|
| 125 |
+
"敦煌鸣沙山月牙泉",
|
| 126 |
+
"香格里拉普达措国家公园",
|
| 127 |
+
"台北故宫博物院翠玉白菜展柜",
|
| 128 |
+
"香港迪士尼城堡前",
|
| 129 |
+
"开罗金字塔骆驼队前",
|
| 130 |
+
"马拉喀什马约尔花园",
|
| 131 |
+
"开普敦桌山缆车",
|
| 132 |
+
"塞伦盖蒂草原热气球",
|
| 133 |
+
"毛里求斯七色土",
|
| 134 |
+
"马达加斯加猴面包树大道",
|
| 135 |
+
"里约热内卢基督像脚下",
|
| 136 |
+
"秘鲁马丘比丘太阳门",
|
| 137 |
+
"布宜诺斯艾利斯博卡区彩色房子",
|
| 138 |
+
"乌尤尼盐沼天空之镜",
|
| 139 |
+
"加拉帕戈斯群岛海狮旁",
|
| 140 |
+
"墨西哥奇琴伊察金字塔",
|
| 141 |
+
"古巴哈瓦那老爷车街头",
|
| 142 |
+
"智利百内国家公园",
|
| 143 |
+
"哥伦比亚瓜塔佩巨岩",
|
| 144 |
+
"温哥华斯坦利公园",
|
| 145 |
+
"尼亚加拉大瀑布观景台",
|
| 146 |
+
"黄石国家公园老忠实泉",
|
| 147 |
+
"大峡谷国家公园玻璃桥",
|
| 148 |
+
"纽约中央公园弓桥",
|
| 149 |
+
"旧金山金门大桥雾中",
|
| 150 |
+
"洛杉矶好莱坞标志",
|
| 151 |
+
"迈阿密南海滩装饰艺术区",
|
| 152 |
+
"芝加哥云门雕塑",
|
| 153 |
+
"新奥尔良法国区",
|
| 154 |
+
"夏威夷威基基海滩",
|
| 155 |
+
"阿拉斯加极光观测站",
|
| 156 |
+
"波士顿自由之路",
|
| 157 |
+
"西雅图太空针塔",
|
| 158 |
+
"拉斯维加斯百乐宫喷泉",
|
| 159 |
+
"华盛顿国家广场",
|
| 160 |
+
"费城自由钟",
|
| 161 |
+
"圣迭戈海洋世界",
|
| 162 |
+
"奥兰多迪士尼魔法王国",
|
| 163 |
+
"纽约布鲁克林大桥",
|
| 164 |
+
"羚羊峡谷光束下",
|
| 165 |
+
"优胜美地国家公园",
|
| 166 |
+
"拱门国家公园精致拱门",
|
| 167 |
+
"大提顿国家公园",
|
| 168 |
+
"佛罗里达清水湾",
|
| 169 |
+
"基韦斯特日落庆典",
|
| 170 |
+
],
|
| 171 |
+
# 穿搭 (50个选项)
|
| 172 |
+
"outfits": [
|
| 173 |
+
"纯白蕾丝连衣短裙",
|
| 174 |
+
"浅蓝水手制服配红色领巾",
|
| 175 |
+
"樱花粉针织开衫+格纹短裙",
|
| 176 |
+
"薄荷绿吊带纱裙",
|
| 177 |
+
"米色牛角扣大衣+贝雷帽",
|
| 178 |
+
"深蓝学院风西服套装",
|
| 179 |
+
"乳白色羊绒高领毛衣",
|
| 180 |
+
"鹅黄色碎花连衣裙",
|
| 181 |
+
"珊瑚粉卫衣+牛仔背带裤",
|
| 182 |
+
"香芋紫泡泡袖上衣",
|
| 183 |
+
"珍珠白缎面吊带睡裙",
|
| 184 |
+
"红白条纹海魂衫",
|
| 185 |
+
"橄榄绿工装连体裤",
|
| 186 |
+
"焦糖色麂皮A字裙",
|
| 187 |
+
"星空蓝渐变星空裙",
|
| 188 |
+
"经典款深色振袖和服",
|
| 189 |
+
"浅灰运动套装+白色球鞋",
|
| 190 |
+
"黑白女仆装+蕾丝头饰",
|
| 191 |
+
"酒红色天鹅绒晚礼服",
|
| 192 |
+
"卡其色风衣+碎花连衣裙",
|
| 193 |
+
"海军蓝双排扣呢子大衣",
|
| 194 |
+
"淡黄色蓬蓬裙芭蕾舞服",
|
| 195 |
+
"墨绿色灯芯绒背带裙",
|
| 196 |
+
"象牙白针织长裙",
|
| 197 |
+
"藏青色弓道服+袴",
|
| 198 |
+
"彩虹条纹针织衫",
|
| 199 |
+
"雾霾蓝毛衣+白色短裤",
|
| 200 |
+
"樱桃图案居家T恤",
|
| 201 |
+
"宝蓝色露肩晚装",
|
| 202 |
+
"姜黄色针织帽+围巾套装",
|
| 203 |
+
"孔雀绿丝绸衬衫",
|
| 204 |
+
"黑白波点雪纺裙",
|
| 205 |
+
"珊瑚绒连体动物睡衣",
|
| 206 |
+
"深灰色百褶裙+白衬衫",
|
| 207 |
+
"玫瑰金亮片舞台装",
|
| 208 |
+
"燕麦色麻花毛衣",
|
| 209 |
+
"复古格子三件套",
|
| 210 |
+
"荧光粉运动Bra+瑜伽裤",
|
| 211 |
+
"深紫色魔法学院袍",
|
| 212 |
+
"米奇联名款卫衣",
|
| 213 |
+
"渐变星空色打歌服",
|
| 214 |
+
"薄荷巧克力色套装",
|
| 215 |
+
"珍珠镶边小黑裙",
|
| 216 |
+
"向日葵印花连衣裙",
|
| 217 |
+
"蒸汽朋克风皮质背心",
|
| 218 |
+
"淡蓝色汉元素襦裙",
|
| 219 |
+
"红黑棋盘格针织衫",
|
| 220 |
+
"银色未来感PVC外套",
|
| 221 |
+
"泰迪熊绒外套",
|
| 222 |
+
"手绘涂鸦牛仔外套",
|
| 223 |
+
],
|
| 224 |
+
# 妆容 (50个选项)
|
| 225 |
+
"makeup": [
|
| 226 |
+
"清透伪素颜妆,仅涂润唇膏",
|
| 227 |
+
"蜜桃色系果汁妆,脸颊闪着细闪",
|
| 228 |
+
"粉棕色系通勤妆,眼线微微上挑",
|
| 229 |
+
"橘调元气妆,大面积腮红横扫",
|
| 230 |
+
"浆果色宿醉妆,眼睑下方泛红",
|
| 231 |
+
"金色闪片舞台妆,夸张假睫毛",
|
| 232 |
+
"冷冽烟熏妆,搭配深色唇釉",
|
| 233 |
+
"红茶系温柔妆,眼角点缀泪痣",
|
| 234 |
+
"蜜糖棕色系妆,卧蚕明显",
|
| 235 |
+
"草莓牛奶妆,唇峰点涂高光",
|
| 236 |
+
"人鱼姬偏光眼影妆",
|
| 237 |
+
"番茄红色系夏日妆",
|
| 238 |
+
"南瓜色秋季限定妆",
|
| 239 |
+
"紫罗兰梦幻渐变眼影",
|
| 240 |
+
"大地色系安全日常妆",
|
| 241 |
+
"钻石泪滴闪片妆",
|
| 242 |
+
"复古红唇港风妆",
|
| 243 |
+
"小鹿斑比无辜大眼妆",
|
| 244 |
+
"晒伤雀斑妆",
|
| 245 |
+
"玻璃唇釉水光妆",
|
| 246 |
+
"雾面哑光高级妆",
|
| 247 |
+
"粉色系桃花约会妆",
|
| 248 |
+
"蓝色妖姬大胆眼影",
|
| 249 |
+
"银色系未来感妆容",
|
| 250 |
+
"绿色清新春日妆",
|
| 251 |
+
"焦糖奶茶色全妆",
|
| 252 |
+
"血色感唇颊统一妆",
|
| 253 |
+
"金色华丽和风妆",
|
| 254 |
+
"黑色哥特式暗黑妆",
|
| 255 |
+
"彩虹渐变眼影妆",
|
| 256 |
+
"珍珠白新娘妆",
|
| 257 |
+
"巧克力棕色系妆",
|
| 258 |
+
"玫瑰金晚宴妆",
|
| 259 |
+
"橘棕色枫叶妆",
|
| 260 |
+
"紫灰色小烟熏妆",
|
| 261 |
+
"蜜粉烘焙定妆法",
|
| 262 |
+
"光泽肌水润妆",
|
| 263 |
+
"雾眉+野生眉组合",
|
| 264 |
+
"截断式cut crease眼妆",
|
| 265 |
+
"全身亮粉派对妆",
|
| 266 |
+
"病弱感苍白妆容",
|
| 267 |
+
"晒伤感高原红妆",
|
| 268 |
+
"金属色机械姬妆",
|
| 269 |
+
"亮片星星眼妆",
|
| 270 |
+
"渐变腮红微醺妆",
|
| 271 |
+
"纯黑眼线猫眼妆",
|
| 272 |
+
"泪眼汪汪楚楚可怜妆",
|
| 273 |
+
"金属蓝埃及艳后妆",
|
| 274 |
+
"樱花粉日系麻豆妆",
|
| 275 |
+
"赤茶色秋冬妆",
|
| 276 |
+
"透明感夏日祭浴衣妆",
|
| 277 |
+
],
|
| 278 |
+
# 动作 (50个选项)
|
| 279 |
+
"poses": [
|
| 280 |
+
"双手捧脸歪头微笑",
|
| 281 |
+
"跳跃时长发飞扬瞬间",
|
| 282 |
+
"回头时眼神捕捉镜头",
|
| 283 |
+
"坐在台阶上抱膝",
|
| 284 |
+
"用手指轻轻点嘴唇",
|
| 285 |
+
"伸懒腰时展现身体曲线",
|
| 286 |
+
"双手比心放在胸前",
|
| 287 |
+
"假装被风吹起裙摆",
|
| 288 |
+
"躲在树后探出半个身子",
|
| 289 |
+
"躺在草坪上看云",
|
| 290 |
+
"用吸管喝饮料时抬眼",
|
| 291 |
+
"对着镜子涂口红",
|
| 292 |
+
"系鞋带时抬头微笑",
|
| 293 |
+
"手拿气球奔跑回头",
|
| 294 |
+
"趴在咖啡厅桌上小憩",
|
| 295 |
+
"伸手接住飘落的樱花",
|
| 296 |
+
"用书本遮住半张脸",
|
| 297 |
+
"整理耳边的碎发",
|
| 298 |
+
"踮起脚尖伸手够东西",
|
| 299 |
+
"吹灭生日蜡烛瞬间",
|
| 300 |
+
"将耳机分给镜头一半",
|
| 301 |
+
"撑着透明雨伞转圈",
|
| 302 |
+
"喂食小鹿时被抓拍",
|
| 303 |
+
"滑滑板时失去平衡",
|
| 304 |
+
"弹钢琴时侧脸特写",
|
| 305 |
+
"荡秋千到最高点时",
|
| 306 |
+
"从门后突然跳出",
|
| 307 |
+
"用拍立得自拍时",
|
| 308 |
+
"手拿棉花糖正要吃",
|
| 309 |
+
"给植物浇水时专注",
|
| 310 |
+
"手指在玻璃上画心",
|
| 311 |
+
"背对镜头转身瞬间",
|
| 312 |
+
"整理和服袖子时",
|
| 313 |
+
"手举烟花绽放笑容",
|
| 314 |
+
"模仿雕像姿势",
|
| 315 |
+
"在书店踮脚取书",
|
| 316 |
+
"泡温泉时肩部特写",
|
| 317 |
+
"早上刚睡醒揉眼睛",
|
| 318 |
+
"收到惊喜礼物捂嘴",
|
| 319 |
+
"被玩笑逗得前仰后合",
|
| 320 |
+
"紧张地抓住裙摆",
|
| 321 |
+
"模仿经典电影海报",
|
| 322 |
+
"在厨房打鸡蛋失败",
|
| 323 |
+
"用望远镜观察远方",
|
| 324 |
+
"堆雪人时鼻尖冻红",
|
| 325 |
+
"在海边写名字被浪冲",
|
| 326 |
+
"吹蒲公英的种子",
|
| 327 |
+
"偷偷瞄喜欢的人",
|
| 328 |
+
"练习舞蹈时挥洒汗水",
|
| 329 |
+
"被突然的喷泉淋湿",
|
| 330 |
+
],
|
| 331 |
+
# 表情 (50个选项)
|
| 332 |
+
"expressions": [
|
| 333 |
+
"露出八颗牙的标准偶像笑",
|
| 334 |
+
"微微抿嘴的害羞笑容",
|
| 335 |
+
"瞪大眼睛的惊讶表情",
|
| 336 |
+
"闭眼享受的幸福微笑",
|
| 337 |
+
"略带淘气的wink表情",
|
| 338 |
+
"充满感激的泪光闪闪",
|
| 339 |
+
"专注认真的凝视",
|
| 340 |
+
"恶作剧得逞的坏笑",
|
| 341 |
+
"困倦的眯眼打哈欠",
|
| 342 |
+
"吃到美味的陶醉神情",
|
| 343 |
+
"鼓起脸颊的假装生气",
|
| 344 |
+
"憧憬向往的星星眼",
|
| 345 |
+
"被夸奖后不好意思",
|
| 346 |
+
"胜利时得意的V字笑",
|
| 347 |
+
"思考时的微微皱眉",
|
| 348 |
+
"看到感人场景的落泪",
|
| 349 |
+
"寂寞孤单的侧脸",
|
| 350 |
+
"充满决心的坚毅眼神",
|
| 351 |
+
"撒娇时的嘟嘴表情",
|
| 352 |
+
"优雅从容的淡淡微笑",
|
| 353 |
+
"充满好奇的探头表情",
|
| 354 |
+
"满足的眯眼笑",
|
| 355 |
+
"略带伤感的微笑",
|
| 356 |
+
"充满活力的露齿笑",
|
| 357 |
+
"诱惑的舔嘴唇",
|
| 358 |
+
"天真的无邪大笑",
|
| 359 |
+
"温柔注视的母爱表情",
|
| 360 |
+
"挑衅的挑眉",
|
| 361 |
+
"恐惧的缩肩表情",
|
| 362 |
+
"惊喜的双手捂脸",
|
| 363 |
+
"疲惫但满足的微笑",
|
| 364 |
+
"困惑的歪头",
|
| 365 |
+
"感动的嘴唇颤抖",
|
| 366 |
+
"自信的直视镜头",
|
| 367 |
+
"害羞的低头浅笑",
|
| 368 |
+
"淘气的吐舌头",
|
| 369 |
+
"愤怒的瞪视",
|
| 370 |
+
"安心的放松表情",
|
| 371 |
+
"俏皮的皱鼻子",
|
| 372 |
+
"充满希望的笑容",
|
| 373 |
+
"狡猾的眯眼笑",
|
| 374 |
+
"心碎的眼眶泛红",
|
| 375 |
+
"骄傲的抬头挺胸",
|
| 376 |
+
"淘气的小恶魔笑",
|
| 377 |
+
"慈爱的温柔微笑",
|
| 378 |
+
"紧张的咬嘴唇",
|
| 379 |
+
"病弱的苍白微笑",
|
| 380 |
+
"女王般的高傲神情",
|
| 381 |
+
"恍惚的出神表情",
|
| 382 |
+
"热情似火的大笑",
|
| 383 |
+
"神秘的蒙娜丽莎微笑",
|
| 384 |
+
],
|
| 385 |
+
# 情绪 (50个选项)
|
| 386 |
+
"moods": [
|
| 387 |
+
"初恋般的心动雀跃",
|
| 388 |
+
"毕业季的淡淡忧伤",
|
| 389 |
+
"圣诞节的温暖幸福",
|
| 390 |
+
"夏日祭的兴奋期待",
|
| 391 |
+
"清晨醒来的慵懒满足",
|
| 392 |
+
"雨天的宁静忧郁",
|
| 393 |
+
"获得奖项的激动喜悦",
|
| 394 |
+
"告别时的依依不舍",
|
| 395 |
+
"初次登台的紧张不安",
|
| 396 |
+
"收到情书的甜蜜羞涩",
|
| 397 |
+
"看到彩虹的惊喜感动",
|
| 398 |
+
"失败后的坚强振作",
|
| 399 |
+
"宠物离去的悲伤寂寞",
|
| 400 |
+
"梦想成真的难以置信",
|
| 401 |
+
"等待约会的小鹿乱撞",
|
| 402 |
+
"被误解的委屈难过",
|
| 403 |
+
"帮助他人的快乐充实",
|
| 404 |
+
"独自旅行的自由畅快",
|
| 405 |
+
"比赛前的斗志昂扬",
|
| 406 |
+
"深夜的孤独沉思",
|
| 407 |
+
"家庭团聚的温馨感动",
|
| 408 |
+
"突破自我的骄傲自豪",
|
| 409 |
+
"青春期的迷茫困惑",
|
| 410 |
+
"初雪的浪漫幻想",
|
| 411 |
+
"海边日出的希望重生",
|
| 412 |
+
"樱花飘落的物哀之美",
|
| 413 |
+
"游乐园的纯粹快乐",
|
| 414 |
+
"图书馆的安静专注",
|
| 415 |
+
"舞台上的光芒四射",
|
| 416 |
+
"后台的疲惫但幸福",
|
| 417 |
+
"离乡背井的思乡之情",
|
| 418 |
+
"重逢的欣喜若狂",
|
| 419 |
+
"秘密被发现的惊慌",
|
| 420 |
+
"挑战极限的刺激快感",
|
| 421 |
+
"被背叛的心碎痛苦",
|
| 422 |
+
"和解后的释然轻松",
|
| 423 |
+
"初为人师的紧张责任",
|
| 424 |
+
"创作灵感迸发的兴奋",
|
| 425 |
+
"照顾生病朋友的担忧",
|
| 426 |
+
"实现承诺的满足安心",
|
| 427 |
+
"发现真相的震惊愤怒",
|
| 428 |
+
"节日孤独的寂寞冷清",
|
| 429 |
+
"收到惊喜的感动流泪",
|
| 430 |
+
"改变形象的忐忑期待",
|
| 431 |
+
"引领团队的领导压力",
|
| 432 |
+
"放下过去的释怀平静",
|
| 433 |
+
"新环境的好奇探索",
|
| 434 |
+
"告白的勇敢决绝",
|
| 435 |
+
"被认可的价值感",
|
| 436 |
+
"失去方向的迷茫空虚",
|
| 437 |
+
"拯救他人的使命感",
|
| 438 |
+
"简单日常的小确幸",
|
| 439 |
+
],
|
| 440 |
+
# 灯光 (50个选项)
|
| 441 |
+
"lighting": [
|
| 442 |
+
"清晨五点的金色侧逆光",
|
| 443 |
+
"正午树荫下的斑驳光点",
|
| 444 |
+
"下午三点的柔光箱补光",
|
| 445 |
+
"黄昏时分的暖色轮廓光",
|
| 446 |
+
"夜晚霓虹灯的彩色映照",
|
| 447 |
+
"烛光的摇曳温暖光照",
|
| 448 |
+
"舞台追光灯的强烈聚焦",
|
| 449 |
+
"窗边自然光的柔和漫射",
|
| 450 |
+
"阴天均匀的漫反射光",
|
| 451 |
+
"逆光形成的发丝光效果",
|
| 452 |
+
"路灯下的昏黄光影",
|
| 453 |
+
"闪光灯直射的硬朗光线",
|
| 454 |
+
"水面的波光粼粼反射",
|
| 455 |
+
"镜面反射的二次补光",
|
| 456 |
+
"篝火的跳跃橙色光芒",
|
| 457 |
+
"电子屏幕的冷色调光",
|
| 458 |
+
"车灯流线的动态轨迹",
|
| 459 |
+
"月光洒下的清冷银辉",
|
| 460 |
+
"雨滴折射的模糊光斑",
|
| 461 |
+
"雾气中的朦胧散射光",
|
| 462 |
+
"百叶窗的光影条纹",
|
| 463 |
+
"水晶吊灯的华丽折射",
|
| 464 |
+
"隧道口的明暗对比",
|
| 465 |
+
"迪斯科球旋转光点",
|
| 466 |
+
"荧光涂料的夜光效果",
|
| 467 |
+
"投影仪的画面映射",
|
| 468 |
+
"烟花瞬间的绚烂照明",
|
| 469 |
+
"极光的梦幻渐变色彩",
|
| 470 |
+
"海底的蓝色透射光线",
|
| 471 |
+
"晨曦中的耶稣光丁达尔",
|
| 472 |
+
"烛台的多重阴影",
|
| 473 |
+
"手术灯的无影效果",
|
| 474 |
+
"钨丝灯的温暖黄光",
|
| 475 |
+
"LED灯带的线性引导",
|
| 476 |
+
"火把的摇曳阴影",
|
| 477 |
+
"探照灯的强烈光束",
|
| 478 |
+
"彩色玻璃的斑斓投影",
|
| 479 |
+
"雪地的反光补脸",
|
| 480 |
+
"黑暗中的单一聚光",
|
| 481 |
+
"多云天气的柔和顶光",
|
| 482 |
+
"日落时分的粉紫色光",
|
| 483 |
+
"美术馆的重点照明",
|
| 484 |
+
"手机屏幕的微弱补光",
|
| 485 |
+
"闪电瞬间的惨白照亮",
|
| 486 |
+
"激光秀的线条切割",
|
| 487 |
+
"荧光棒的演唱会海洋",
|
| 488 |
+
"暗房红灯的特殊色调",
|
| 489 |
+
"宝石折射的七彩光芒",
|
| 490 |
+
"雾霾中的光晕效果",
|
| 491 |
+
"烈日下的高对比阴影",
|
| 492 |
+
"舞台染色灯的彩色氛围",
|
| 493 |
+
"荧光蘑菇的微弱生物光",
|
| 494 |
+
"朝阳穿透森林的晨雾",
|
| 495 |
+
],
|
| 496 |
+
}
|
| 497 |
+
|
| 498 |
+
def _get_theme_vocab(self, theme: str) -> Dict[str, List[str]]:
|
| 499 |
+
"""根据主题筛选词库"""
|
| 500 |
+
theme_keywords = {
|
| 501 |
+
"校园青春": {
|
| 502 |
+
"locations": ["东京", "镰仓", "学校", "教室", "图书馆", "操场"],
|
| 503 |
+
"outfits": ["水手服", "学院风", "针织衫", "格纹裙", "白衬衫"],
|
| 504 |
+
"moods": ["青春", "初恋", "毕业", "友情", "成长"],
|
| 505 |
+
},
|
| 506 |
+
"和风传统": {
|
| 507 |
+
"locations": ["京都", "奈良", "神社", "寺庙", "古街"],
|
| 508 |
+
"outfits": ["和服", "浴衣", "振袖", "袴", "草履"],
|
| 509 |
+
"moods": ["古典", "优雅", "宁静", "物哀", "传统"],
|
| 510 |
+
},
|
| 511 |
+
"夏日海滩": {
|
| 512 |
+
"locations": ["冲绳", "海滩", "海岛", "泳池", "海滨"],
|
| 513 |
+
"outfits": ["泳装", "沙滩裙", "草帽", "比基尼", "短裤"],
|
| 514 |
+
"moods": ["活力", "热情", "清凉", "度假", "阳光"],
|
| 515 |
+
},
|
| 516 |
+
"都市时尚": {
|
| 517 |
+
"locations": ["涩谷", "银座", "表参道", "商场", "咖啡厅"],
|
| 518 |
+
"outfits": ["设计师", "时尚", "潮流", "名牌", "混搭"],
|
| 519 |
+
"moods": ["酷炫", "自信", "成熟", "都市", "前卫"],
|
| 520 |
+
},
|
| 521 |
+
}
|
| 522 |
+
|
| 523 |
+
# 如果没有指定主题,返回全部词汇
|
| 524 |
+
if theme not in theme_keywords:
|
| 525 |
+
return self.vocab
|
| 526 |
+
|
| 527 |
+
# 根据主题关键词筛选
|
| 528 |
+
themed_vocab = {}
|
| 529 |
+
for category, words in self.vocab.items():
|
| 530 |
+
if (
|
| 531 |
+
category in ["locations", "outfits", "moods"]
|
| 532 |
+
and theme in theme_keywords
|
| 533 |
+
):
|
| 534 |
+
# 筛选包含主题关键词的词汇
|
| 535 |
+
keywords = theme_keywords[theme].get(category, [])
|
| 536 |
+
filtered = [
|
| 537 |
+
word
|
| 538 |
+
for word in words
|
| 539 |
+
if any(keyword in word for keyword in keywords)
|
| 540 |
+
]
|
| 541 |
+
themed_vocab[category] = filtered if filtered else words[:20]
|
| 542 |
+
else:
|
| 543 |
+
themed_vocab[category] = words
|
| 544 |
+
|
| 545 |
+
return themed_vocab
|
| 546 |
+
|
| 547 |
+
def generate_photo_description(
|
| 548 |
+
self, num: int = 1, theme: Optional[str] = None
|
| 549 |
+
) -> List[Dict]:
|
| 550 |
+
"""生成写真描述,可选主题"""
|
| 551 |
+
results = []
|
| 552 |
+
|
| 553 |
+
# 获取对应主题的词库
|
| 554 |
+
current_vocab = self._get_theme_vocab(theme) if theme else self.vocab
|
| 555 |
+
|
| 556 |
+
for i in range(num):
|
| 557 |
+
description = {
|
| 558 |
+
"编号": i + 1,
|
| 559 |
+
"主题": theme if theme else "随机",
|
| 560 |
+
"地点": random.choice(current_vocab["locations"]),
|
| 561 |
+
"穿搭": random.choice(current_vocab["outfits"]),
|
| 562 |
+
"妆容": random.choice(current_vocab["makeup"]),
|
| 563 |
+
"动作": random.choice(current_vocab["poses"]),
|
| 564 |
+
"表情": random.choice(current_vocab["expressions"]),
|
| 565 |
+
"情绪": random.choice(current_vocab["moods"]),
|
| 566 |
+
"灯光": random.choice(current_vocab["lighting"]),
|
| 567 |
+
}
|
| 568 |
+
results.append(description)
|
| 569 |
+
|
| 570 |
+
return results
|
| 571 |
+
|
| 572 |
+
def generate_unique(
|
| 573 |
+
self, num: int = 1, theme: Optional[str] = None, unique_keys: List[str] = None
|
| 574 |
+
) -> List[Dict]:
|
| 575 |
+
"""
|
| 576 |
+
确保生成不重复的组合
|
| 577 |
+
|
| 578 |
+
Args:
|
| 579 |
+
num: 生成数量
|
| 580 |
+
theme: 主题名称
|
| 581 |
+
unique_keys: 用于判断唯一性的字段列表
|
| 582 |
+
默认 ['地点', '动作', '表情']
|
| 583 |
+
"""
|
| 584 |
+
if unique_keys is None:
|
| 585 |
+
unique_keys = ["地点", "动作", "表情"]
|
| 586 |
+
|
| 587 |
+
results = []
|
| 588 |
+
seen = set()
|
| 589 |
+
attempts = 0
|
| 590 |
+
max_attempts = num * 10 # 防止无限循环
|
| 591 |
+
|
| 592 |
+
while len(results) < num and attempts < max_attempts:
|
| 593 |
+
# 生成一个描述
|
| 594 |
+
desc = self.generate_photo_description(1, theme)[0]
|
| 595 |
+
|
| 596 |
+
# 创建唯一标识键
|
| 597 |
+
key_parts = [str(desc.get(field, "")) for field in unique_keys]
|
| 598 |
+
key = "|".join(key_parts)
|
| 599 |
+
|
| 600 |
+
# 检查是否重复
|
| 601 |
+
if key not in seen:
|
| 602 |
+
seen.add(key)
|
| 603 |
+
results.append(desc)
|
| 604 |
+
|
| 605 |
+
attempts += 1
|
| 606 |
+
|
| 607 |
+
# 如果无法生成足够的不重复组合
|
| 608 |
+
if len(results) < num:
|
| 609 |
+
print(f"⚠️ 注意:只能生成 {len(results)} 个不重复组合")
|
| 610 |
+
|
| 611 |
+
return results
|
| 612 |
+
|
| 613 |
+
def generate_themed_series(
|
| 614 |
+
self, theme: str, num: int = 5, series_type: str = "story"
|
| 615 |
+
) -> List[Dict]:
|
| 616 |
+
"""
|
| 617 |
+
生成主题连贯的系列写真
|
| 618 |
+
|
| 619 |
+
Args:
|
| 620 |
+
theme: 主题名称
|
| 621 |
+
num: 生成数量
|
| 622 |
+
series_type: 系列类型
|
| 623 |
+
"story" - 故事连贯
|
| 624 |
+
"location" - 地点连贯
|
| 625 |
+
"outfit" - 服装连贯
|
| 626 |
+
"""
|
| 627 |
+
# 获取主题词库
|
| 628 |
+
theme_vocab = self._get_theme_vocab(theme)
|
| 629 |
+
|
| 630 |
+
# 根据系列类型设置基础元素
|
| 631 |
+
base_elements = {}
|
| 632 |
+
if series_type == "location":
|
| 633 |
+
# 相同地点,不同角度/时间
|
| 634 |
+
base_location = random.choice(theme_vocab["locations"])
|
| 635 |
+
base_elements["地点"] = base_location
|
| 636 |
+
elif series_type == "outfit":
|
| 637 |
+
# 相同服装,不同场景
|
| 638 |
+
base_outfit = random.choice(theme_vocab["outfits"])
|
| 639 |
+
base_elements["穿搭"] = base_outfit
|
| 640 |
+
elif series_type == "story":
|
| 641 |
+
# 故事性:连贯的情绪变化
|
| 642 |
+
mood_progression = ["期待", "紧张", "进行", "高潮", "结束"]
|
| 643 |
+
if num <= len(mood_progression):
|
| 644 |
+
base_elements["情绪序列"] = mood_progression[:num]
|
| 645 |
+
|
| 646 |
+
results = []
|
| 647 |
+
for i in range(num):
|
| 648 |
+
desc = {
|
| 649 |
+
"编号": i + 1,
|
| 650 |
+
"主题": theme,
|
| 651 |
+
"系列类型": series_type,
|
| 652 |
+
"系列序号": f"{i + 1}/{num}",
|
| 653 |
+
}
|
| 654 |
+
|
| 655 |
+
# 设置系列基础元素
|
| 656 |
+
if "地点" in base_elements:
|
| 657 |
+
desc["地点"] = base_elements["地点"]
|
| 658 |
+
else:
|
| 659 |
+
desc["地点"] = random.choice(theme_vocab["locations"])
|
| 660 |
+
|
| 661 |
+
if "穿搭" in base_elements:
|
| 662 |
+
desc["穿搭"] = base_elements["穿搭"]
|
| 663 |
+
else:
|
| 664 |
+
desc["穿搭"] = random.choice(theme_vocab["outfits"])
|
| 665 |
+
|
| 666 |
+
# 如果是故事系列,使用预设的情绪序列
|
| 667 |
+
if "情绪序列" in base_elements:
|
| 668 |
+
desc["情绪"] = base_elements["情绪序列"][i]
|
| 669 |
+
else:
|
| 670 |
+
desc["情绪"] = random.choice(theme_vocab["moods"])
|
| 671 |
+
|
| 672 |
+
# 其他元素随机
|
| 673 |
+
desc["妆容"] = random.choice(theme_vocab["makeup"])
|
| 674 |
+
desc["动作"] = random.choice(theme_vocab["poses"])
|
| 675 |
+
desc["表情"] = random.choice(theme_vocab["expressions"])
|
| 676 |
+
desc["灯光"] = random.choice(theme_vocab["lighting"])
|
| 677 |
+
|
| 678 |
+
results.append(desc)
|
| 679 |
+
|
| 680 |
+
return results
|
| 681 |
+
|
| 682 |
+
def generate_tweet(self, description: Dict) -> str:
|
| 683 |
+
"""为写真描述生成配套推文"""
|
| 684 |
+
# 从描述中提取关键元素
|
| 685 |
+
location_keywords = ["东京", "京都", "北海道", "冲绳", "镰仓", "大阪", "奈良"]
|
| 686 |
+
location = description["地点"]
|
| 687 |
+
|
| 688 |
+
# 确定话题标签
|
| 689 |
+
tags = [" #王道偶像写真", " #每日一照", " #偶像的日常", " #aifeifei "]
|
| 690 |
+
|
| 691 |
+
for keyword in location_keywords:
|
| 692 |
+
if keyword in location:
|
| 693 |
+
tags.append(f"#{keyword}摄影")
|
| 694 |
+
break
|
| 695 |
+
|
| 696 |
+
# 随机选择推文风格
|
| 697 |
+
tweet_templates = [
|
| 698 |
+
f"今天的拍摄在「{description['地点']}」完成~{description['情绪']}的心情,通过{description['动作']}传达给大家!{''.join(tags)}",
|
| 699 |
+
f"新写真花絮💖 {description['穿搭']}搭配{description['妆容']},在{description['灯光']}下{description['表情']}。此刻感觉{description['情绪']}… {''.join(tags)}",
|
| 700 |
+
f"发现一个绝佳拍摄地:{description['地点']}!尝试了{description['动作']},不知道效果如何?{description['表情']} {''.join(tags)}",
|
| 701 |
+
f"【幕后速报】{description['地点']}拍摄中。今天的主题是「{description['情绪']}」,{description['穿搭']}和{description['妆容']}都是为了营造这种氛围~ {''.join(tags)}",
|
| 702 |
+
]
|
| 703 |
+
|
| 704 |
+
return random.choice(tweet_templates)
|
| 705 |
+
|
| 706 |
+
|
| 707 |
+
# ============== 使用示例 ==============
|
| 708 |
+
if __name__ == "__main__":
|
| 709 |
+
# 1. 创建生成器实例
|
| 710 |
+
generator = IdolPhotoGenerator()
|
| 711 |
+
|
| 712 |
+
print("🎀 增强版写真描述生成器 🎀")
|
| 713 |
+
print("=" * 60)
|
| 714 |
+
|
| 715 |
+
# 2. 使用 generate_unique 功能
|
| 716 |
+
print("\n🔹 示例1:生成3个不重复的写真描述")
|
| 717 |
+
print("-" * 40)
|
| 718 |
+
|
| 719 |
+
unique_photos = generator.generate_unique(
|
| 720 |
+
num=3,
|
| 721 |
+
theme="校园青春", # 可选主题
|
| 722 |
+
unique_keys=["地点", "动作", "表情"], # 可自定义唯一性判断字段
|
| 723 |
+
)
|
| 724 |
+
|
| 725 |
+
for photo in unique_photos:
|
| 726 |
+
print(f"📸 #{photo['编号']} | 主题:{photo['主题']}")
|
| 727 |
+
print(f" 地点: {photo['地点']}")
|
| 728 |
+
print(f" 动作: {photo['动作']}")
|
| 729 |
+
print(f" 表情: {photo['表情']}")
|
| 730 |
+
print(f" 情绪: {photo['情绪']}")
|
| 731 |
+
|
| 732 |
+
# 3. 使用 generate_themed_series 功能
|
| 733 |
+
print("\n\n🔹 示例2:生成'和风传统'主题的连贯系列")
|
| 734 |
+
print("-" * 40)
|
| 735 |
+
|
| 736 |
+
themed_series = generator.generate_themed_series(
|
| 737 |
+
theme="和风传统",
|
| 738 |
+
num=3,
|
| 739 |
+
series_type="story", # 尝试: "location", "outfit", "story"
|
| 740 |
+
)
|
| 741 |
+
|
| 742 |
+
for photo in themed_series:
|
| 743 |
+
print(f"🎎 #{photo['编号']} | {photo['系列类型']}系列 {photo['系列序号']}")
|
| 744 |
+
print(f" 地点: {photo['地点']}")
|
| 745 |
+
print(f" 穿搭: {photo['穿搭']}")
|
| 746 |
+
print(f" 情绪: {photo['情绪']}")
|
| 747 |
+
print(f" 动作: {photo['动作']}")
|
| 748 |
+
|
| 749 |
+
# # 4. 批量生成并保存
|
| 750 |
+
# print("\n\n🔹 示例3:批量生成并保存到文件")
|
| 751 |
+
# print("-" * 40)
|
| 752 |
+
#
|
| 753 |
+
# # 生成20个不重复的都市时尚主题写真
|
| 754 |
+
# batch_results = generator.generate_unique(
|
| 755 |
+
# num=20,
|
| 756 |
+
# theme="都市时尚",
|
| 757 |
+
# unique_keys=["地点", "穿搭", "动作"], # 可根据需要调整
|
| 758 |
+
# )
|
| 759 |
+
|
| 760 |
+
# # 保存到文件
|
| 761 |
+
# with open("themed_photos.txt", "w", encoding="utf-8") as f:
|
| 762 |
+
# for photo in batch_results:
|
| 763 |
+
# f.write(f"写真 #{photo['编号']}\n")
|
| 764 |
+
# f.write(f"主题: {photo.get('主题', '随机')}\n")
|
| 765 |
+
# f.write(f"地点: {photo['地点']}\n")
|
| 766 |
+
# f.write(f"穿搭: {photo['穿搭']}\n")
|
| 767 |
+
# f.write(f"妆容: {photo['妆容']}\n")
|
| 768 |
+
# f.write(f"动作: {photo['动作']}\n")
|
| 769 |
+
# f.write(f"表情: {photo['表情']}\n")
|
| 770 |
+
# f.write(f"情绪: {photo['情绪']}\n")
|
| 771 |
+
# f.write(f"灯光: {photo['灯光']}\n")
|
| 772 |
+
# # 生成推文
|
| 773 |
+
# tweet = generator.generate_tweet(photo)
|
| 774 |
+
# f.write(f"推文: {tweet}\n")
|
| 775 |
+
# f.write("-" * 50 + "\n")
|
| 776 |
+
#
|
| 777 |
+
# print(f"✅ 已生成 {len(batch_results)} 个不重复的都市时尚写真描述")
|
| 778 |
+
# print("✅ 已保存到 'themed_photos.txt'")
|
| 779 |
+
|
| 780 |
+
# 5. 询问是否需要50个完整描述
|
| 781 |
+
print("\n\n🔹 示例4:生成50个随机写真描述")
|
| 782 |
+
print("-" * 40)
|
| 783 |
+
|
| 784 |
+
response = input("是否要生成50个完整写真描述?(y/n): ")
|
| 785 |
+
if response.lower() == "y":
|
| 786 |
+
all_photos = generator.generate_photo_description(50)
|
| 787 |
+
with open("idol_photo_descriptions.txt", "w", encoding="utf-8") as f:
|
| 788 |
+
for photo in all_photos:
|
| 789 |
+
f.write(f"写真 #{photo['编号']}\n")
|
| 790 |
+
f.write(f"地点: {photo['地点']}\n")
|
| 791 |
+
f.write(f"穿搭: {photo['穿搭']}\n")
|
| 792 |
+
f.write(f"妆容: {photo['妆容']}\n")
|
| 793 |
+
f.write(f"动作: {photo['动作']}\n")
|
| 794 |
+
f.write(f"表情: {photo['表情']}\n")
|
| 795 |
+
f.write(f"情绪: {photo['情绪']}\n")
|
| 796 |
+
f.write(f"灯光: {photo['灯光']}\n")
|
| 797 |
+
tweet = generator.generate_tweet(photo)
|
| 798 |
+
f.write(f"推文: {tweet}\n")
|
| 799 |
+
f.write("=" * 60 + "\n")
|
| 800 |
+
print("✅ 已保存50个完整描述到 idol_photo_descriptions.txt")
|