File size: 6,352 Bytes
b511d75
8d1bd48
 
b511d75
8d1bd48
 
b511d75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8d1bd48
 
b511d75
8d1bd48
b511d75
 
8d1bd48
 
b511d75
 
8d1bd48
 
b511d75
 
8d1bd48
 
b511d75
 
8d1bd48
 
 
b511d75
 
 
 
 
 
 
8d1bd48
b511d75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8d1bd48
b511d75
8d1bd48
b511d75
8d1bd48
b511d75
8d1bd48
b511d75
 
 
8d1bd48
b511d75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8d1bd48
 
 
b511d75
 
 
 
 
 
 
 
 
 
 
 
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
import os
import gradio as gr
import google.generativeai as genai
from PIL import Image, ImageEnhance, ImageFilter
import io
import base64
import json
import time
try:
    import pyperclip
except ImportError:
    os.system('pip install pyperclip')
    import pyperclip

# --- Security First Configuration ---
GEMINI_KEY = os.environ.get("GEMINI_KEY", "")  # Load from environment variable

# --- Template Optimization System ---
BASE_TEMPLATE = (
    "Describe this design as a single, cohesive, and concise prompt suitable for Flux 1.1 Pro. "
    "Focus on key elements such as text, symbols, layout, and overall style."
)

STYLE_INSTRUCTIONS = {
    "General": BASE_TEMPLATE,
    "Realistic": (
        f"{BASE_TEMPLATE} Focus on photorealistic details: textures, lighting, depth. "
        "Avoid illustrations/cartoon styles. Use technical photography terms."
    ),
    "Kawaii/Cartoon": (
        f"{BASE_TEMPLATE} Emphasize cute, rounded shapes, playful expressions, "
        "vibrant colors. Use anime/kawaii terminology."
    ),
    "Vector": (
        f"{BASE_TEMPLATE} Specify clean vector style with sharp lines, geometric shapes. "
        "Black/white only with gray gradients. Use design technical terms."
    ),
    "Silhouette": (
        f"{BASE_TEMPLATE} Use high-contrast black/white silhouettes. "
        "Focus on bold shapes and outlines. Eliminate interior details."
    ),
}

# --- Flux Configuration Engine ---
FLUX_SPECS = {
    "aspect_ratios": ["1:1", "16:9", "4:3", "9:16", "Custom"],
    "output_formats": ["SVG", "PNG-300dpi", "PDF", "EPS"],
    "color_modes": ["B&W", "CMYK", "Spot Colors", "RGB"],
    "complexity_levels": ["Minimal", "Medium", "High", "Ultra"]
}

# --- Quality Control Systems ---
class QualityValidator:
    VALIDATION_PROMPT = """Analyze this Flux prompt on:
1. Technical specificity (1-5)
2. Style adherence (1-5)
3. Flux compatibility (1-5)
Respond ONLY as JSON: {"total": x/15, "issues": [list]}"""

    @classmethod
    def validate(cls, prompt, model):
        try:
            response = model.generate_content([cls.VALIDATION_PROMPT, prompt])
            return json.loads(response.text)
        except:
            return {"total": 0, "issues": ["Validation failed"]}

# --- Image Processing Pipeline ---
def preprocess_image(img):
    """Enhance image quality before analysis"""
    img = img.convert("RGB")
    img = ImageEnhance.Contrast(img).enhance(1.2)
    img = img.filter(ImageFilter.SHARPEN)
    return img

# --- Core Application Logic ---
def generate_prompt(image, api_key, style, creativity, neg_prompt, flux_specs):
    genai.configure(api_key=api_key or GEMINI_KEY)
    model = genai.GenerativeModel("gemini-1.5-pro", generation_config={
        "temperature": creativity,
        "top_p": 0.95
    })

    # Pre-process image
    img = preprocess_image(image)
    img_bytes = io.BytesIO()
    img.save(img_bytes, format="PNG")
    img_b64 = base64.b64encode(img_bytes.getvalue()).decode()

    # Build instruction
    instruction = f"{STYLE_INSTRUCTIONS[style]}\nAVOID: {neg_prompt}\nFLUX SPECS: {flux_specs}"

    # Generate initial prompt
    response = model.generate_content([instruction, {"mime_type": "image/png", "data": img_b64}])
    raw_prompt = response.text

    # Quality validation
    validation = QualityValidator.validate(raw_prompt, model)
    if validation["total"] < 10:  # Regenerate if low quality
        response = model.generate_content([
            f"Improve this prompt addressing: {validation['issues']}\n\n{raw_prompt}"
        ])
        raw_prompt = response.text

    return raw_prompt, validation

# --- UI Components ---
def create_advanced_params():
    with gr.Accordion("โš™๏ธ Advanced Parameters", open=False):
        with gr.Row():
            creativity = gr.Slider(0.0, 1.0, 0.7, label="Creativity")
            neg_prompt = gr.Textbox(label="๐Ÿšซ Avoid in Prompt", placeholder="e.g., no text, avoid gradients")
        with gr.Row():
            aspect = gr.Dropdown(FLUX_SPECS["aspect_ratios"], value="1:1", label="Aspect Ratio")
            fmt = gr.Dropdown(FLUX_SPECS["output_formats"], value="SVG", label="Output Format")
            color = gr.Dropdown(FLUX_SPECS["color_modes"], value="B&W", label="Color Mode")
            complexity = gr.Dropdown(FLUX_SPECS["complexity_levels"], value="Medium", label="Complexity")
    return [creativity, neg_prompt, aspect, fmt, color, complexity]

# --- Gradio Interface ---
def build_interface():
    with gr.Blocks(title="Flux Pro Generator") as app:
        # Security First
        api_key = gr.Textbox(label="๐Ÿ”‘ Gemini API Key", value=GEMINI_KEY, type="password", 
                           info="Set GEMINI_KEY environment variable for production")

        # Main Workflow
        with gr.Row():
            with gr.Column(scale=1):
                img_input = gr.Image(label="๐Ÿ–ผ๏ธ Upload Design", type="pil", sources=["upload", "clipboard"])
                style = gr.Dropdown(list(STYLE_INSTRUCTIONS), value="General", label="๐ŸŽจ Target Style")
                adv_params = create_advanced_params()
                
            with gr.Column(scale=2):
                prompt_output = gr.Textbox(label="๐Ÿ“ Optimized Prompt", lines=8, interactive=False)
                with gr.Row():
                    gen_btn = gr.Button("โœจ Generate", variant="primary")
                    copy_btn = gr.Button("๐Ÿ“‹ Copy")
                quality_report = gr.JSON(label="๐Ÿ” Quality Report")

        # Enterprise Features
        token_counter = gr.Textbox(label="๐Ÿงฎ Token Usage", interactive=False)
        history = gr.State([])

        # Event Handling
        gen_btn.click(
            generate_prompt,
            inputs=[img_input, api_key, style] + adv_params,
            outputs=[prompt_output, quality_report]
        )
        
        copy_btn.click(
            lambda x: (pyperclip.copy(x), x),
            inputs=prompt_output,
            outputs=prompt_output
        )

    return app

# --- Production Deployment ---
if __name__ == "__main__":
    app = build_interface()
    app.launch(
        server_name="0.0.0.0",
        server_port=int(os.getenv("PORT", 7860)),
        share=False,
        auth=(
            os.getenv("APP_USER", "admin"), 
            os.getenv("APP_PWD", "admin")
        ) if os.getenv("ENV") == "prod" else None
    )