File size: 6,579 Bytes
a20b7df
 
 
 
 
 
 
 
 
 
 
 
 
 
d9fb779
a20b7df
d9fb779
a20b7df
d9fb779
 
 
 
 
 
 
 
 
 
 
 
a20b7df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d9fb779
a20b7df
 
 
 
 
 
 
 
 
 
 
 
 
 
d9fb779
a20b7df
 
 
 
d9fb779
 
 
 
a20b7df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d9fb779
 
 
 
a20b7df
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d9fb779
a20b7df
 
 
 
 
 
 
d9fb779
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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
81
82
83
84
85
86
87
88
89
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
import gradio as gr
import random
import openai
import os

# ========== 默认选项和数据 ==========
EXPRESSIONS = ["smiling", "determined", "surprised", "serene"]
ITEMS = ["magic wand", "sword", "flower", "book of spells", "ancient scroll", "music instrument"]
OTHER_DETAILS = ["sparkles", "magical aura", "lens flare", "fireworks in the background"]
SCENES = ["sunset beach", "rainy city street at night", "fantasy forest with glowing mushrooms", "futuristic skyline at dawn"]
CAMERA_ANGLES = ["low-angle shot", "close-up shot", "bird's-eye view", "wide-angle shot"]
QUALITY_PROMPTS = ["8k", "ultra-realistic", "high detail", "cinematic lighting", "award-winning"]

# ========== 工具函数 ==========
def load_candidates_from_files(files):
    """
    从多个文件中加载候选项。
    """
    all_lines = []
    if files:
        for file in files:
            # 如果 `file` 是路径
            if isinstance(file, str):
                with open(file, "r", encoding="utf-8") as f:
                    all_lines.extend([line.strip() for line in f if line.strip()])
            # 如果 `file` 是 Gradio 的文件对象
            elif hasattr(file, "name"):
                with open(file.name, "r", encoding="utf-8") as f:
                    all_lines.extend([line.strip() for line in f if line.strip()])
    return all_lines

def get_random_item(candidates):
    """
    随机选取候选项。
    """
    return random.choice(candidates) if candidates else ""

def generate_natural_language_description(tags, api_key=None):
    """
    生成自然语言描述,可以选择使用 GPT 或手写逻辑。
    """
    if api_key:
        try:
            openai.api_key = api_key.strip()
            response = openai.ChatCompletion.create(
                model="gpt-4",
                messages=[
                    {"role": "system", "content": (
                        "You are a helpful assistant that generates creative painting/prompt descriptions. "
                        "Write at least three sentences in English, separated by periods."
                    )},
                    {"role": "user", "content": f"Here are the tags: {tags}\nPlease generate a vivid, imaginative scene description."}
                ],
                max_tokens=300,
                temperature=0.7,
            )
            return response["choices"][0]["message"]["content"].strip()
        except Exception as e:
            return f"GPT generation failed. Error: {e}"
    else:
        # 本地逻辑生成
        return (
            f"In this scene, {tags.get('character_name', 'the character')} appears in a {tags.get('scene', 'mysterious place')}, "
            f"captured from a {tags.get('camera_angle', 'unique angle')} perspective. "
            f"The overall style combines {tags.get('artist_prompt', 'an unknown artist')} and {tags.get('style', 'a distinctive aesthetic')}, "
            f"bringing a captivating atmosphere to the artwork. They are {tags.get('action', 'doing something')} "
            f"with a {tags.get('expression', 'neutral expression')}, holding {tags.get('items', 'something')} among {tags.get('other_details', 'subtle details')}."
        )

def generate_prompt(action_file, style_file, artist_files, character_files, api_key, selected_categories):
    """
    生成随机提示词和描述。
    """
    # 从文件加载候选项
    actions = load_candidates_from_files([action_file]) if action_file else []
    styles = load_candidates_from_files([style_file]) if style_file else []
    artists = load_candidates_from_files(artist_files) if artist_files else []
    characters = load_candidates_from_files(character_files) if character_files else []

    # 确定角色类型
    number_of_characters = ", ".join(selected_categories) if selected_categories else random.choice(["1girl", "1boy"])

    # 随机生成提示词
    tags = {
        "number_of_characters": number_of_characters,
        "character_name": get_random_item(characters),
        "artist_prompt": get_random_item(artists),
        "style": get_random_item(styles),
        "scene": get_random_item(SCENES),
        "camera_angle": get_random_item(CAMERA_ANGLES),
        "action": get_random_item(actions),
        "expression": get_random_item(EXPRESSIONS),
        "items": get_random_item(ITEMS),
        "other_details": get_random_item(OTHER_DETAILS),
        "quality_prompts": get_random_item(QUALITY_PROMPTS),
    }

    # 生成描述
    description = generate_natural_language_description(tags, api_key)

    # 返回结果
    tags_list = [value for value in tags.values() if value]
    final_tags = ", ".join(tags_list)
    return final_tags, description

# ========== Gradio 界面 ==========
def gradio_interface():
    """
    定义 Gradio 应用界面。
    """
    with gr.Blocks() as demo:
        gr.Markdown("## Random Prompt Generator with User-Provided GPT API Key")

        # API Key 输入区
        api_key_input = gr.Textbox(
            label="Enter your OpenAI API Key (Optional)",
            placeholder="sk-...",
            type="password"
        )

        # 文件上传
        with gr.Row():
            action_file = gr.File(label="Upload Action File (Optional)", file_types=[".txt"])
            style_file = gr.File(label="Upload Style File (Optional)", file_types=[".txt"])
        
        with gr.Row():
            artist_files = gr.File(label="Upload Artist Files (Multiple Allowed)", file_types=[".txt"], file_types_description="Text Files", multiple=True)
            character_files = gr.File(label="Upload Character Files (Multiple Allowed)", file_types=[".txt"], file_types_description="Text Files", multiple=True)

        # 角色类型选择
        selected_categories = gr.CheckboxGroup(
            ["1boy", "1girl", "furry", "mecha", "fantasy monster", "animal", "still life"],
            label="Choose Character Categories (Optional)"
        )

        # 输出区域
        with gr.Row():
            tags_output = gr.Textbox(label="Generated Tags")
            description_output = gr.Textbox(label="Generated Description")

        # 按钮
        generate_button = gr.Button("Generate Prompt")

        # 按钮动作
        generate_button.click(
            generate_prompt,
            inputs=[action_file, style_file, artist_files, character_files, api_key_input, selected_categories],
            outputs=[tags_output, description_output],
        )

    return demo

# 启动 Gradio 应用
if __name__ == "__main__":
    gradio_interface().launch(share=True)