Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import random | |
| import glob | |
| import os | |
| import requests | |
| from openai import OpenAI | |
| from dotenv import load_dotenv | |
| # 加载环境变量 | |
| load_dotenv() | |
| # ========== 默认选项和数据 ========== | |
| EXPRESSIONS = [ | |
| "smiling", "determined", "surprised", "serene", "smug", "thinking", | |
| "looking back", "laughing", "angry", "pensive", "confident", | |
| "grinning", "thoughtful", "sad tears", "bewildered", | |
| "amused", "excited", "anxious", "confused", "curious", | |
| "delighted", "disappointed", "elated", "embarrassed", | |
| "envious", "fearful", "frustrated", "hopeful", "horrified", | |
| "inspired", "jealous", "melancholic", "nervous", "playful", | |
| "relieved", "remorseful", "skeptical", "terrified", "thrilled", | |
| "uneasy", "wistful", "zany", "neutral", "expressionless", | |
| "sleepy", "tired", "relaxed", "drooling", "sick", "nauseated", | |
| "sneezing", "hot", "cold", "woozy", "dizzy", | |
| "(๑•̀ㅂ•́)و✧", "(╯°□°)╯︵ ┻━┻", "(✧ω✧)", "(・_・;)", | |
| "(。•́︿•̀。)", "(≧◡≦)", "(╥﹏╥)", "( ̄▽ ̄)", | |
| "(ಥ_ಥ)", "(⊙_☉)", "(¬_¬)", "(°ロ°)!", "(≧︿≦)", | |
| "(´•ω•`)", "(°ー°〃)", "(^人^)", "(╯︵╰,)", "(ಥ﹏ಥ)", | |
| "(´・_・`)", "(ノ´ー`)ノ", "(ノಥ益ಥ)ノ", "(。♥‿♥。)", "(づ ̄ ³ ̄)づ", | |
| "(☉。☉)!", "(>_<)", "(☆ω☆)", "(x_x)", "o(TヘTo)", "(︶︹︺)", | |
| "(⌒_⌒;)", "(☍﹏⁰)。", "(´・_・)", "(⊙﹏⊙)", "(。-_-。)", "(¬‿¬)", | |
| "(°∀°)", "(◕‿◕)", "(T_T)", "( ̄︿ ̄)", "(>人<)", "(つД`)ノ", | |
| "(`・ω・´)", "(๑´ڡ`๑)", "(✿╹◡╹)", "(´ε` )♡", "(•̀ᴗ•́)و", | |
| "(∩`-´)⊃━☆゚.*・。゚", "(☞゚ヮ゚)☞", "(ノ≧ڡ≦)!", "(´・ω・`)ノ", "(⁎⁍̴̛ᴗ⁍̴̛⁎)", | |
| "(╬ಠ益ಠ)", "(ノಠ益ಠ)ノ彡┻━┻", "(ง'̀-'́)ง", "(´。• ω •。`) ♡" | |
| ] | |
| ITEMS = [ | |
| "magic wand", "sword", "flower", "book of spells", "earrings", "loincloth", | |
| "slippers", "ancient scroll", "music instrument", "shield", "dagger", | |
| "headband", "leg ties", "staff", "potion", "crystal ball", "anklet", | |
| "ribbon", "lantern", "amulet", "ring", "enchanted cloak", "mystic orb", | |
| "charred tome", "golden chalice", "feather quill", "obsidian blade", | |
| "healing herb", "celestial compass", "shimmering veil", "phoenix feather", | |
| "rune stone", "dragon scale", "mirror of truth", "key of destiny", | |
| "shadow dagger", "firestone", "glimmering necklace", "moonlit tiara", | |
| "elixir of vitality", "serpent bracelet", "orb of whispers", "ivy circlet", | |
| "ember crown", "storm gauntlets", "twilight boots", "ethereal shawl", | |
| "guardian pendant", "pearl of wisdom", "arcane hourglass", "binding chain", | |
| "gem of clarity", "silk gloves", "wings of ascension", "crystal shard", | |
| "sapphire brooch", "mask of shadows", "ashwood cane", "silver flute", | |
| "chime of echoes", "star chart", "jade pendant", "hourglass of time", | |
| "frosted gem", "vial of starlight", "scroll of secrets", "golden anklet", | |
| "radiant crown", "veil of illusions", "ring of eternity", "soulbound locket", | |
| "enchanted map", "mystic key", "ancient coin", "wizard's journal", | |
| "magic ink", "sorcerer's robe", "elven boots", "dwarven hammer", | |
| "griffin feather", "fairy dust", "necromancer's book", "ranger's bow", | |
| "bard's lute", "monk's beads", "thief's dagger", "alchemist's flask", | |
| "summoner's tome", "elemental gem", "timekeeper's watch", "portal key", | |
| "invisibility cloak", "levitation charm", "mind control orb", "fire-breathing potion", | |
| "earthquake drum", "storm summoning horn", "sunstone", "moonstone", | |
| "stardust vial", "dreamcatcher", "truth serum", "luck charm", | |
| "fortune dice", "destiny thread", "life potion", "eternal torch", | |
| "necklace", "bracelet", "brooch", "tie clip", "cufflinks", "belt", | |
| "scarf", "shawl", "hat", "hairpin", "hairband", "gloves", "waist chain", | |
| "keychain", "bag charm", "badge", "armband", "lapel pin", "sash", | |
| "beaded fringe", "embroidered patch", "rhinestones", "pearls", "chains", | |
| "suspenders", "garter belts", "stockings", "mittens", "masks", "veils", | |
| "handbags", "clutches", "backpacks", "satchels", "messenger bags", | |
| "wristwatches", "pocket watches", "sunglasses", "spectacles", "chokers", | |
| "lockets", "pendants", "talismans", "charms", "ankle bracelets", "toe rings" | |
| ] | |
| OTHER_DETAILS = [ | |
| # 环境动态细节 | |
| "sparkles", "magical aura", "lens flare", "fireworks in the background", | |
| "smoke effects", "light trails", "falling leaves", "glowing embers", | |
| "floating particles", "rays of light", "shimmering mist", "ethereal glow", | |
| "ripples on water", "dust motes in sunlight", "swirling fog", "glittering frost", | |
| "reflections on surfaces", "flickering shadows", "falling snowflakes", | |
| "twinkling stars", "crescent moonlight", "glowing fireflies", "soft cloud wisps", | |
| "subtle rain", "scattered feathers", "wind-blown sand", "cracks in the ground", | |
| "waves crashing in the distance", "glowing mushrooms", "hanging vines", | |
| "faint rainbows", "drifting ash", "rising bubbles", "aurora in the sky", | |
| "shattered glass fragments", "falling cherry blossoms", "sunbeams breaking through clouds", | |
| "water droplets on leaves", "wisps of smoke", "dimly glowing lanterns", | |
| "undulating waves of grass", "sparkling dewdrops", "glistening cobwebs", | |
| "golden hour light", "tiny glowing orbs", "vapor trails in the sky", | |
| "distant silhouettes of birds", "slowly moving shadows", "softly pulsing glows", | |
| "gently falling powder snow", "mirages on the horizon", "waving tree branches", | |
| "radiant beams through fog", "scattered golden leaves", "softly glowing fungi", | |
| "rippling heatwaves", "glowing lines on surfaces", | |
| # 叙事辅助细节 | |
| "ancient carvings on walls", "worn-out banners fluttering", "cracked stained glass", | |
| "fallen statues covered in vines", "ceremonial fires flickering", "abandoned tools scattered", | |
| "forgotten books on dusty shelves", "hidden inscriptions glowing faintly", | |
| "collapsed bridges in the distance", "ancient scripts floating in midair", | |
| "trails of footsteps in the snow", "discarded musical instruments", "half-buried artifacts", | |
| "melting candles on altars", "phantom figures fading in the background", | |
| "reflections of unseen movements in water", "shifting sands forming patterns", | |
| "layered ruins creating depth", "shattered pottery", "crumbling pillars", | |
| "weathered doorways", "dried riverbeds", "overgrown fences", "scattered coins", | |
| "glimmering gemstones in cracks", "rusted chains", "torn flags", | |
| "broken shields lying in the grass", "ancient bridges covered in moss", | |
| "swords embedded in stone", "faded murals on crumbling walls", | |
| "mysterious glowing symbols on the ground", "abandoned helmets half-buried in sand", | |
| "fossilized remains in rock walls", "golden inscriptions on blackened stone", | |
| "vines entwined with ancient statues", "weathered chests hidden under roots", | |
| "bone fragments scattered across ruins", "broken clocks frozen in time", | |
| "lichen-covered stones marking old pathways", "cursed objects glowing faintly in shadows", | |
| "forgotten wells with stagnant water", "ashes scattered across altars", | |
| "chains hanging from ruined walls", "rusted weapons embedded in tree trunks", | |
| "ancient seals broken on stone tablets", "sunken ruins peeking through murky waters", | |
| "melted wax pooling on ritual circles", "bird nests in abandoned helmets", | |
| "vines overtaking crumbling archways", "bloodstains faded into stone", | |
| "remains of campfires surrounded by bones", "fragments of ancient maps on walls", | |
| "forgotten altars surrounded by offerings", "spiral patterns carved into the ground", | |
| "wind chimes tangled in overgrowth", "scattered gemstones sparkling in the dirt", | |
| # 科幻背景细节 | |
| "hovering drones patrolling the area", "holographic billboards flickering", | |
| "neon signs reflecting on wet pavement", "futuristic skyscrapers piercing the clouds", | |
| "flying cars zipping through the sky", "robotic vendors at street corners", | |
| "cybernetic enhancements visible on pedestrians", "digital advertisements projected in midair", | |
| "energy shields protecting buildings", "automated cleaning bots sweeping the streets", | |
| "glowing circuit patterns on walls", "transparent bridges connecting towers", | |
| "artificial intelligence interfaces displayed publicly", "bioluminescent plants lining walkways", | |
| "virtual reality kiosks with users immersed", "mechanical limbs discarded in alleys", | |
| "surveillance cameras with blinking lights", "underground labs emitting strange glows", | |
| "spaceships landing on rooftop pads", "androids interacting with humans seamlessly", | |
| "laser engravings on metallic surfaces", "plasma screens displaying news feeds", | |
| "synthetic food stands with diverse offerings", "hoverboards parked near entrances", | |
| "genetic modification clinics with bright signage", "quantum computing hubs glowing faintly", | |
| "fusion reactors humming in the distance", "alien flora glowing in sterile environments", | |
| "rusted space equipment scattered on barren ground", "forcefields shimmering in the air", | |
| "futuristic statues commemorating unknown heroes", "orbital stations visible in the sky", | |
| "cracked stasis pods leaking mist", "discarded exoskeletons in shadowy corners", | |
| "dimly lit corridors with blinking control panels", "holographic maps rotating slowly", | |
| "time-worn spacecraft hulls covered in scratches", "energy conduits glowing along walls" | |
| ] | |
| SCENES = [ | |
| # 自然场景 | |
| "sunset beach", "rainy city street at night", "high blue sky", | |
| "snowy mountain peak", "desert ruins", "enchanted meadow", | |
| "misty forest trail", "hidden valley surrounded by cliffs", | |
| "raging waterfall in a lush jungle", "golden wheat fields at sunset", | |
| "stormy coastline with crashing waves", "dense rainforest with towering trees", | |
| "wind-swept plains under an overcast sky", "frozen tundra stretching endlessly", | |
| "emerald lake reflecting the mountains", "serene meadow under starlit skies", | |
| # 奇幻场景 | |
| "fantasy forest with glowing mushrooms", "particles magic world", | |
| "floating ash land", "abandoned castle", "underwater city", | |
| "haunted mansion", "glacial cavern", "floating islands above a magical sea", | |
| "ancient ruins glowing with runes", "crystal cave with shimmering walls", | |
| "celestial palace above the clouds", "dark enchanted forest with eerie lights", | |
| "golden desert oasis with sparkling waters", "volcanic landscape with rivers of lava", | |
| "towering spires of an elven city", "hidden fae village among massive flowers", | |
| "ancient temple shrouded in mist", | |
| # 科幻场景 | |
| "futuristic skyline at dawn", "steampunk marketplace", | |
| "orbital station overlooking a planet", "neon-lit cyberpunk cityscape", | |
| "crumbling space station", "alien planet with multiple moons", | |
| "terraforming facility on barren land", "gravity-defying sci-fi structures", | |
| "bioluminescent forest on an alien world", "megastructure city layered with lights", | |
| "robot factory with moving assembly lines", "underground research lab glowing faintly", | |
| "time-warped city merging eras", "abandoned alien settlement in the desert", | |
| "holographic gardens in the void", "massive starship docks bustling with activity", | |
| # 废墟与遗迹场景 | |
| "ancient battlefield with broken weapons", "collapsed bridges over a canyon", | |
| "abandoned cathedral overgrown with vines", "forgotten library buried in sand", | |
| "crumbling statues in a misty valley", "deserted mining town under a red sky", | |
| "swampy ruins with submerged pillars", "eroded city reclaimed by nature", | |
| "old lighthouse on rocky cliffs", "sunken ship graveyard in shallow seas", | |
| "ruined amphitheater under moonlight", "forgotten monastery at a mountain's edge", | |
| "overgrown garden in a dilapidated mansion", "war-torn city with smoking rubble", | |
| "ancient crypt deep underground", | |
| # 情绪化场景 | |
| "peaceful village at dawn", "stormy mountain pass with lightning", | |
| "abandoned carnival under a cloudy sky", "twilight forest bathed in golden light", | |
| "melancholic city square after rain", "sunlit cathedral with stained glass reflections", | |
| "empty train station at midnight", "serene pond surrounded by blossoms", | |
| "vibrant marketplace during a festival", "dim tavern with flickering candles", | |
| "lonely pier stretching into foggy waters", "quiet cemetery under crescent moonlight", | |
| "hidden spring surrounded by mossy rocks", "eerie swamp with glowing will-o'-the-wisps", | |
| "ancient battlefield under a blood-red sky", | |
| # 室内场景 | |
| "opulent throne room in a grand castle", "dimly lit library with towering bookshelves", | |
| "abandoned laboratory with broken equipment", "cozy cabin with a roaring fireplace", | |
| "ornate ballroom with glittering chandeliers", "sprawling dining hall with long tables", | |
| "underground bunker with industrial walls", "luxurious palace bedroom draped in silk", | |
| "steampunk workshop filled with gears and tools", "mystical shrine surrounded by candles", | |
| "underground dungeon with damp stone walls", "hidden study behind a bookshelf", | |
| "sunlit greenhouse filled with exotic plants", "control room glowing with monitors", | |
| "train car interior with vintage decor", "haunted attic with cobwebs and trunks", | |
| "grand theater with red velvet curtains", "rustic kitchen with copper pots", | |
| "modern office with glass walls", "abandoned asylum with graffiti-covered walls", | |
| "elegant tea room with porcelain settings", "high-tech lab with robotic arms", | |
| "children’s playroom with scattered toys", "ancient council chamber with stone seats", | |
| "dim tavern with wooden furniture", "artist's studio with half-finished paintings", | |
| "futuristic sleeping pod chamber", "neon-lit arcade with glowing consoles", | |
| "classroom with chalkboards and empty desks", "temple hall with intricate carvings" | |
| ] | |
| CAMERA_ANGLES = [ | |
| "low-angle shot", "high-angle shot", "normal eye-level shot", | |
| "close-up shot", "medium shot", "wide-angle shot", | |
| "over-the-shoulder shot", "bird's-eye view", "worm's-eye view", | |
| "extreme close-up", "panoramic view", "dynamic tracking shot", | |
| "fisheye view", "point-of-view (POV) shot", "from behind shot", | |
| "from top shot", "from below shot", "from the side shot", | |
| "over-the-head shot", "reaction shot", "through a window shot", | |
| "mirror reflection shot", "split-screen shot", | |
| "silhouette framing shot", "foreground framing shot", | |
| "Dutch angle", "frame within a frame", "obscured view through foliage", | |
| "reflected surface view", "shadow-based composition shot", | |
| "rotating 360-degree shot", "slow-motion close-up", | |
| "freeze-frame shot", "fast zoom-out shot", | |
| "tilt-up shot", "tilt-down shot", "panning shot", | |
| "crane shot", "dolly zoom", "whip pan shot", | |
| "impact tracking shot", "environment dominant framing", | |
| "symmetrical center focus", "off-center dynamic composition" | |
| ] | |
| QUALITY_PROMPTS = [ | |
| "cinematic lighting", "sharp shadow", "award-winning", "masterpiece", | |
| "vivid colors", "high dynamic range", "immersive", "studio quality", | |
| "fine art", "dreamlike", "8K", "HD", "high quality", "best quality", | |
| "artistic", "vibrant" | |
| ] | |
| # Hugging Face DTR 数据集路径(示例,若不可用请忽略) | |
| DTR_DATASET_PATTERN = "https://huggingface.co/datasets/X779/Danbooruwildcards/resolve/main/*DTR*.txt" | |
| # ========== 工具函数 ========== | |
| def load_candidates_from_files(files, excluded_tags=None): | |
| """ | |
| 从多个文件中加载候选项,同时排除用户不想要的标签(精确匹配)。 | |
| """ | |
| if excluded_tags is None: | |
| excluded_tags = set() | |
| all_lines = [] | |
| if files: | |
| for file in files: | |
| if isinstance(file, str): | |
| # 说明是路径字符串 | |
| with open(file, "r", encoding="utf-8") as f: | |
| lines = [line.strip() for line in f if line.strip()] | |
| filtered = [l for l in lines if l not in excluded_tags] | |
| all_lines.extend(filtered) | |
| else: | |
| # 说明是一个上传的 file-like 对象 | |
| file_data = file.read().decode("utf-8", errors="ignore") | |
| lines = [line.strip() for line in file_data.splitlines() if line.strip()] | |
| filtered = [l for l in lines if l not in excluded_tags] | |
| all_lines.extend(filtered) | |
| return all_lines | |
| def get_random_items(candidates, num_items=1): | |
| """ | |
| 从候选项中随机选取指定数量的选项。 | |
| """ | |
| return random.sample(candidates, min(num_items, len(candidates))) if candidates else [] | |
| def load_dtr_from_huggingface(excluded_tags=None): | |
| """ | |
| 从 Hugging Face 数据集中加载所有包含 "DTR" 的文件内容,同时排除不需要的tag。 | |
| """ | |
| if excluded_tags is None: | |
| excluded_tags = set() | |
| try: | |
| response = requests.get(DTR_DATASET_PATTERN) | |
| response.raise_for_status() | |
| lines = response.text.splitlines() | |
| # 只过滤精确匹配 | |
| lines = [l for l in lines if l not in excluded_tags] | |
| return lines | |
| except Exception as e: | |
| print(f"Error loading DTR dataset: {e}") | |
| return [] | |
| def generate_natural_language_description(tags, api_key=None, base_url=None, model="gpt-4"): | |
| """ | |
| 使用 OpenAI GPT 或 DeepSeek API 生成自然语言描述。 | |
| """ | |
| if not api_key: | |
| api_key = os.getenv("OPENAI_API_KEY") | |
| if not api_key: | |
| return "Error: No API Key provided and none found in environment variables." | |
| # 将 dict 转成可读字符串 | |
| tag_descriptions = "\n".join([ | |
| f"{key}: {', '.join(value) if isinstance(value, list) else value}" | |
| for key, value in tags.items() if value | |
| ]) | |
| try: | |
| client = OpenAI(api_key=api_key, base_url=base_url) if base_url else OpenAI(api_key=api_key) | |
| response = client.chat.completions.create( | |
| messages=[ | |
| { | |
| "role": "system", | |
| "content": ( | |
| "You are a creative assistant that generates detailed and imaginative scene descriptions for AI generation prompts. " | |
| "Focus on the details provided and incorporate them into a cohesive narrative. " | |
| "Use at least three sentences but no more than five sentences." | |
| ), | |
| }, | |
| { | |
| "role": "user", | |
| "content": f"Here are the tags and details:\n{tag_descriptions}\nPlease generate a vivid, imaginative scene description.", | |
| }, | |
| ], | |
| model=model, | |
| ) | |
| return response.choices[0].message.content.strip() | |
| except Exception as e: | |
| return f"GPT generation failed. Error: {e}" | |
| # ========== 核心函数:随机生成 prompt ========== | |
| def generate_prompt( | |
| action_file, style_file, artist_files, character_files, dtr_enabled, api_key, selected_categories, | |
| expression_count, item_count, detail_count, scene_count, angle_count, quality_count, action_count, style_count, | |
| artist_count, use_deepseek, deepseek_key, user_custom_tags, excluded_tags | |
| ): | |
| """ | |
| 生成随机提示词和描述。 | |
| """ | |
| # 处理排除 Tags(逗号分隔 -> 去重 set) | |
| excluded_set = set( | |
| [tag.strip() for tag in excluded_tags.split(",") if tag.strip()] | |
| ) if excluded_tags else set() | |
| # 从文件中加载可选 action、style、artist、character | |
| actions = get_random_items(load_candidates_from_files([action_file], excluded_set) if action_file else [], action_count) | |
| styles = get_random_items(load_candidates_from_files([style_file], excluded_set) if style_file else [], style_count) | |
| artists = get_random_items(load_candidates_from_files(artist_files, excluded_set) if artist_files else [], artist_count) | |
| characters = get_random_items(load_candidates_from_files(character_files, excluded_set) if character_files else [], 1) | |
| # 处理 DTR | |
| dtr_candidates = get_random_items(load_dtr_from_huggingface(excluded_set) if dtr_enabled else [], 1) | |
| # 处理预设列表中的随机筛选 | |
| filtered_expressions = [e for e in EXPRESSIONS if e not in excluded_set] | |
| filtered_items = [i for i in ITEMS if i not in excluded_set] | |
| filtered_details = [d for d in OTHER_DETAILS if d not in excluded_set] | |
| filtered_scenes = [s for s in SCENES if s not in excluded_set] | |
| filtered_angles = [c for c in CAMERA_ANGLES if c not in excluded_set] | |
| filtered_quality = [q for q in QUALITY_PROMPTS if q not in excluded_set] | |
| # 随机抽取 | |
| random_expression = get_random_items(filtered_expressions, expression_count) | |
| random_items = get_random_items(filtered_items, item_count) | |
| random_details = get_random_items(filtered_details, detail_count) | |
| random_scenes = get_random_items(filtered_scenes, scene_count) | |
| random_angles = get_random_items(filtered_angles, angle_count) | |
| random_quality = get_random_items(filtered_quality, quality_count) | |
| number_of_characters = ", ".join(selected_categories) if selected_categories else [] | |
| # 整理为字典 | |
| tags = { | |
| "number_of_characters": [number_of_characters] if number_of_characters else [], | |
| "character_name": characters, | |
| "artist_prompt": [f"(artist:{', '.join(artists)})"] if artists else [], | |
| "style": styles, | |
| "scene": random_scenes, | |
| "camera_angle": random_angles, | |
| "action": actions, | |
| "expression": random_expression, | |
| "items": random_items, | |
| "other_details": random_details, | |
| "quality_prompts": random_quality, | |
| "dtr": dtr_candidates, | |
| } | |
| # 如果用户有自定义输入 | |
| if user_custom_tags.strip(): | |
| tags["custom_tags"] = [t.strip() for t in user_custom_tags.split(",") if t.strip()] | |
| # 生成自然语言描述 | |
| if use_deepseek: | |
| description = generate_natural_language_description(tags, api_key=deepseek_key, base_url="https://api.deepseek.com", model="deepseek-chat") | |
| else: | |
| description = generate_natural_language_description(tags, api_key=api_key) | |
| # 整理最终 Tags(flatten 并去重) | |
| tags_list = [] | |
| for v in tags.values(): | |
| if isinstance(v, list): | |
| tags_list.extend(v) | |
| else: | |
| tags_list.append(v) | |
| # 去重保持顺序 | |
| seen = set() | |
| final_tags_list = [] | |
| for t in tags_list: | |
| if t not in seen and t: | |
| seen.add(t) | |
| final_tags_list.append(t) | |
| final_tags = ", ".join(final_tags_list) | |
| # 默认 Combined = Tags + Description | |
| combined_output = f"{final_tags}\n\n{description}" | |
| return final_tags, description, combined_output | |
| # ========== 部分更新:只根据用户修改后的 tags_text 生成新的描述和合并输出 ========== | |
| def update_description(tags_text, api_key, use_deepseek, deepseek_key): | |
| """ | |
| 只根据用户提供的 tags_text 生成描述和合并输出。 | |
| 不再重新随机抽取,以免破坏用户手动修改过的 Tags。 | |
| """ | |
| if not api_key and not deepseek_key: | |
| # 没有提供任意可用 API Key | |
| return "(No API Key provided)", f"{tags_text}\n\n(No API Key provided)" | |
| # 构造给 GPT 的 prompt | |
| user_prompt = ( | |
| "You are a creative assistant that generates detailed, imaginative scene descriptions for AI generation.\n" | |
| "Below is the user's current tags (prompt elements). " | |
| "Generate a new descriptive text (3-5 sentences) that incorporates these tags.\n\n" | |
| f"User Tags: {tags_text}\n" | |
| "Please generate a vivid, imaginative scene description." | |
| ) | |
| try: | |
| if use_deepseek: | |
| # 调用 DeepSeek | |
| client = OpenAI(api_key=deepseek_key, base_url="https://api.deepseek.com") | |
| model = "deepseek-chat" | |
| else: | |
| # 调用 OpenAI | |
| client = OpenAI(api_key=api_key) | |
| model = "gpt-4" # 或其他可用模型,比如 "gpt-3.5-turbo" | |
| response = client.chat.completions.create( | |
| messages=[ | |
| { | |
| "role": "system", | |
| "content": "You are a creative assistant that generates imaginative scene descriptions..." | |
| }, | |
| { | |
| "role": "user", | |
| "content": user_prompt, | |
| }, | |
| ], | |
| model=model, | |
| ) | |
| new_description = response.choices[0].message.content.strip() | |
| except Exception as e: | |
| new_description = f"(GPT generation failed: {e})" | |
| new_combined_output = f"{tags_text}\n\n{new_description}" | |
| return new_description, new_combined_output | |
| # ========== 翻译功能:将 combined_output 翻译成用户选定语言 ========== | |
| def translate_combined_output(combined_text, target_language, api_key, use_deepseek, deepseek_key): | |
| """ | |
| 使用 GPT 或 DeepSeek API,将 combined_text 翻译成 target_language。 | |
| """ | |
| if not api_key and not deepseek_key: | |
| return "(No API Key provided)" | |
| # 简单用 GPT 做翻译,也可改成其他翻译 API | |
| translation_prompt = ( | |
| f"You are a professional translator. Please translate the following text into {target_language}.\n\n" | |
| f"{combined_text}" | |
| ) | |
| try: | |
| if use_deepseek: | |
| # 调用 DeepSeek | |
| client = OpenAI(api_key=deepseek_key, base_url="https://api.deepseek.com") | |
| model = "deepseek-chat" | |
| else: | |
| # 调用 OpenAI | |
| client = OpenAI(api_key=api_key) | |
| model = "gpt-3.5-turbo" # 或者别的模型 | |
| response = client.chat.completions.create( | |
| messages=[ | |
| {"role": "system", "content": "You are a professional translator."}, | |
| {"role": "user", "content": translation_prompt}, | |
| ], | |
| model=model, | |
| ) | |
| translated_text = response.choices[0].message.content.strip() | |
| except Exception as e: | |
| translated_text = f"(Translation failed: {e})" | |
| return translated_text | |
| # ========== 收藏功能:最多存 3 条 ========== | |
| def add_to_favorites(combined_output, current_favorites): | |
| """ | |
| 将当前生成的 combined_output 添加到收藏列表中(最多存 3 条)。 | |
| """ | |
| current_favorites.append(combined_output) | |
| # 如果超过3条,移除最早的一条 | |
| if len(current_favorites) > 3: | |
| current_favorites.pop(0) | |
| # 格式化输出 | |
| favorites_text = "\n\n".join( | |
| [f"[Favorite {i+1}]\n{fav}" for i, fav in enumerate(current_favorites)] | |
| ) | |
| return favorites_text, current_favorites | |
| # ========== Gradio 界面 ========== | |
| def gradio_interface(): | |
| """ | |
| 定义 Gradio 应用界面。 | |
| """ | |
| with gr.Blocks() as demo: | |
| gr.Markdown("## 【RPGAT】Random Prompt Generator with Adjustable Tags (V2)") | |
| # 用于存储收藏内容的状态(最多缓存3条) | |
| favorites_state = gr.State([]) | |
| with gr.Row(): | |
| # 左侧:文件上传、参数选择、排除/自定义输入 | |
| with gr.Column(scale=1): | |
| api_key_input = gr.Textbox( | |
| label="OpenAI API Key (optional-可选)", | |
| placeholder="sk-...", | |
| type="password" | |
| ) | |
| deepseek_key_input = gr.Textbox( | |
| label="DeepSeek API Key (optional-可选)", | |
| placeholder="sk-...", | |
| type="password" | |
| ) | |
| use_deepseek = gr.Checkbox(label="Use DeepSeek API") | |
| dtr_enabled = gr.Checkbox(label="Enable DTR (当前无效-now plz ignore this)") | |
| with gr.Group(): | |
| gr.Markdown("**upload your wildcards(optional)--上传文件 (可选):**") | |
| action_file = gr.File(label="Action File", file_types=[".txt"]) | |
| style_file = gr.File(label="Style File", file_types=[".txt"]) | |
| artist_files = gr.Files(label="Artist Files", file_types=[".txt"]) | |
| character_files = gr.Files(label="Character Files", file_types=[".txt"]) | |
| selected_categories = gr.CheckboxGroup( | |
| ["1boy", "1girl", "furry", "mecha", "fantasy monster", "animal", "still life"], | |
| label="Choose Character Categories" | |
| ) | |
| excluded_tags = gr.Textbox( | |
| label="排除excluded Tags (逗号分隔)", | |
| placeholder="As如:angry, sword" | |
| ) | |
| user_custom_tags = gr.Textbox( | |
| label="自定义附加custom addition Tags (逗号分隔)", | |
| placeholder="As如:glowing eyes, giant wings" | |
| ) | |
| with gr.Group(): | |
| gr.Markdown("**Set the Number of the random counts--随机数量设置:**") | |
| expression_count = gr.Slider(label="Number of Expressions", minimum=0, maximum=10, step=1, value=1) | |
| item_count = gr.Slider(label="Number of Items", minimum=0, maximum=10, step=1, value=1) | |
| detail_count = gr.Slider(label="Number of Other Details", minimum=0, maximum=10, step=1, value=1) | |
| scene_count = gr.Slider(label="Number of Scenes", minimum=0, maximum=10, step=1, value=1) | |
| angle_count = gr.Slider(label="Number of Camera Angles", minimum=0, maximum=10, step=1, value=1) | |
| quality_count = gr.Slider(label="Number of Quality Prompts", minimum=0, maximum=10, step=1, value=1) | |
| action_count = gr.Slider(label="Number of Actions", minimum=1, maximum=10, step=1, value=1) | |
| style_count = gr.Slider(label="Number of Styles", minimum=1, maximum=10, step=1, value=1) | |
| artist_count = gr.Slider(label="Number of Artists", minimum=1, maximum=10, step=1, value=1) | |
| # 右侧:生成按钮 + 生成结果 + 收藏 + 翻译 | |
| with gr.Column(scale=2): | |
| generate_button = gr.Button("Generate Prompt", variant="primary") | |
| tags_output = gr.Textbox( | |
| label="Generated Tags", | |
| placeholder="Waiting for generate-等待生成...", | |
| lines=4, | |
| interactive=True | |
| ) | |
| description_output = gr.Textbox( | |
| label="Generated Description", | |
| placeholder="Waiting for generate-等待生成...", | |
| lines=4, | |
| interactive=True | |
| ) | |
| combined_output = gr.Textbox( | |
| label="Combined Output: Tags + Description", | |
| placeholder="Waiting for generate-等待生成...", | |
| lines=6 | |
| ) | |
| # 新增一个按钮,只更新 description 和 combined | |
| update_desc_button = gr.Button("Update Description Only") | |
| # 翻译相关 | |
| with gr.Row(): | |
| target_language = gr.Dropdown( | |
| choices=["English", "Chinese", "Arabic (language)", "Japanese", "Persian (language)", "Italian (language)", "Dutch (language)","Russian (language)","German (language)"], | |
| value="English", | |
| label="Target Language-目标语言" | |
| ) | |
| translate_button = gr.Button("Translate to selected language") | |
| translated_output = gr.Textbox( | |
| label="Translated Output", | |
| placeholder="Waiting for the result of Translation--等待翻译...", | |
| lines=6 | |
| ) | |
| # 收藏 | |
| with gr.Row(): | |
| favorite_button = gr.Button("Favorites this result-收藏本次结果") | |
| favorites_box = gr.Textbox( | |
| label="Favorites Folder (MAX-Save 3 tags-- 最多 3 条)", | |
| placeholder="暂无收藏", | |
| lines=6 | |
| ) | |
| # 点击“Generate Prompt”按钮 | |
| generate_button.click( | |
| generate_prompt, | |
| inputs=[ | |
| action_file, style_file, artist_files, character_files, | |
| dtr_enabled, api_key_input, selected_categories, | |
| expression_count, item_count, detail_count, scene_count, | |
| angle_count, quality_count, action_count, style_count, | |
| artist_count, use_deepseek, deepseek_key_input, | |
| user_custom_tags, excluded_tags | |
| ], | |
| outputs=[tags_output, description_output, combined_output], | |
| ) | |
| # 点击“Update Description Only”按钮 | |
| update_desc_button.click( | |
| update_description, | |
| inputs=[ | |
| tags_output, # 用户在文本框里编辑后的 Tags | |
| api_key_input, | |
| use_deepseek, | |
| deepseek_key_input, | |
| ], | |
| outputs=[description_output, combined_output], | |
| ) | |
| # 点击“Translate to selected language”按钮 | |
| translate_button.click( | |
| fn=translate_combined_output, | |
| inputs=[ | |
| combined_output, # 要翻译的源文本 | |
| target_language, | |
| api_key_input, | |
| use_deepseek, | |
| deepseek_key_input | |
| ], | |
| outputs=[translated_output], | |
| ) | |
| # 收藏按钮点击事件 | |
| favorite_button.click( | |
| fn=add_to_favorites, | |
| inputs=[combined_output, favorites_state], | |
| outputs=[favorites_box, favorites_state], | |
| ) | |
| return demo | |
| # 启动 Gradio 应用 | |
| if __name__ == "__main__": | |
| gradio_interface().launch() |