mroccuper commited on
Commit
b511d75
ยท
verified ยท
1 Parent(s): ffd81e9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +146 -78
app.py CHANGED
@@ -1,103 +1,171 @@
 
1
  import gradio as gr
2
  import google.generativeai as genai
3
- from PIL import Image
4
  import io
5
  import base64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
 
7
- # Mapping styles to instructions
8
  STYLE_INSTRUCTIONS = {
9
- "General": (
10
- "Describe this design as a single, cohesive, and concise prompt suitable for Flux 1.1 Pro. "
11
- "Focus on key elements such as text, symbols, layout, and overall style."
12
- ),
13
  "Realistic": (
14
- "Describe this design with a focus on photorealistic details, including textures, lighting, and depth, "
15
- "ensuring accuracy in representation. Avoid illustrations or cartoon-like interpretations."
16
  ),
17
  "Kawaii/Cartoon": (
18
- "Describe this design with an emphasis on cute, rounded shapes, playful expressions, and vibrant, fun aesthetics "
19
- "typical of the kawaii/cartoon style. Focus on light-hearted and visually charming elements."
20
  ),
21
  "Vector": (
22
- "Describe this design as a single, cohesive, and concise prompt suitable for Flux 1.1 Pro. "
23
- "Focus on key elements such as text, symbols, layout, and overall style. "
24
- "Specify that the design should be created in a clean, professional vector and illustration style, "
25
- "emphasizing sharp lines, geometric shapes, and smooth gradients where applicable. "
26
- "The entire design must be in black and white, using only shades of gray for depth and contrast. "
27
- "Avoid any use of color unless it is essential to the design's purpose. "
28
- "Avoid cartoonish or overly stylized elements unless they align with the design's purpose. "
29
- "Use clear and direct language to convey the design's theme, humor, or purpose, if applicable. "
30
- "Ensure the description is compact, well-structured, and optimized for creating a graphic. "
31
- "Include only essential details and avoid unnecessary elaboration."
32
  ),
33
  "Silhouette": (
34
- "Describe this design using high-contrast black and white silhouettes, focusing on bold shapes and clear outlines "
35
- "to convey the subject effectively. Eliminate interior details unless crucial to recognition."
36
  ),
37
  }
38
 
39
- # Function to check API key validity
40
- def check_api(api_key):
41
- try:
42
- genai.configure(api_key=api_key)
43
- model = genai.GenerativeModel("gemini-1.5-pro")
44
- response = model.generate_content("Hello, can you respond?")
45
- return "โœ… API Key is valid!" if response.text else "โš ๏ธ API responded but empty."
46
- except Exception as e:
47
- return f"โŒ Error: {str(e)}"
48
-
49
- # Function to generate a prompt using Gemini
50
- def generate_prompt(image, api_key, style):
51
- if not api_key:
52
- return "โŒ Error: Please enter your Google Gemini API key."
53
-
54
- try:
55
- genai.configure(api_key=api_key)
56
- model = genai.GenerativeModel("gemini-1.5-pro")
57
-
58
- # Convert image to base64
59
- image_bytes = io.BytesIO()
60
- image.save(image_bytes, format=image.format if image.format else "PNG")
61
- image_base64 = base64.b64encode(image_bytes.getvalue()).decode('utf-8')
62
-
63
- instruction = STYLE_INSTRUCTIONS.get(style, STYLE_INSTRUCTIONS["General"])
64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
65
  response = model.generate_content([
66
- instruction,
67
- {"mime_type": "image/png", "data": image_base64}
68
  ])
 
69
 
70
- return response.text if response.text else "โš ๏ธ No response generated."
71
- except Exception as e:
72
- return f"โŒ Error generating prompt: {str(e)}"
73
-
74
- # Gradio Interface
75
- def main():
76
- with gr.Blocks() as app:
77
- gr.Markdown("## ๐ŸŽจ Flux Prompt Generator with Gemini 1.5 Pro")
78
-
79
- api_key = gr.Textbox(label="๐Ÿ”‘ Google Gemini API Key", type="password", placeholder="Paste your Gemini API key here")
80
- check_button = gr.Button("โœ… Check API Key")
81
- check_output = gr.Textbox(label="API Key Status")
82
 
 
 
 
83
  with gr.Row():
84
- with gr.Column():
85
- image_input = gr.Image(label="๐Ÿ“ท Upload Design Image", type="pil", width=300)
86
- style_dropdown = gr.Dropdown(label="๐ŸŽจ Style", choices=list(STYLE_INSTRUCTIONS.keys()), value="General")
87
-
88
- generate_button = gr.Button("๐Ÿง  Generate Prompt")
89
- prompt_output = gr.Textbox(label="๐Ÿ“ Generated Flux Prompt", lines=6)
90
- copy_button = gr.Button("๐Ÿ“‹ Copy to Clipboard")
91
-
92
- def copy_prompt(prompt):
93
- return gr.update(value=prompt, interactive=True)
94
-
95
- check_button.click(check_api, inputs=api_key, outputs=check_output)
96
- generate_button.click(generate_prompt, inputs=[image_input, api_key, style_dropdown], outputs=prompt_output)
97
- copy_button.click(copy_prompt, inputs=prompt_output, outputs=prompt_output)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
 
99
  return app
100
 
101
- # Launch the app
102
- app = main()
103
- app.launch()
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
  import gradio as gr
3
  import google.generativeai as genai
4
+ from PIL import Image, ImageEnhance, ImageFilter
5
  import io
6
  import base64
7
+ import json
8
+ import time
9
+ try:
10
+ import pyperclip
11
+ except ImportError:
12
+ os.system('pip install pyperclip')
13
+ import pyperclip
14
+
15
+ # --- Security First Configuration ---
16
+ GEMINI_KEY = os.environ.get("GEMINI_KEY", "") # Load from environment variable
17
+
18
+ # --- Template Optimization System ---
19
+ BASE_TEMPLATE = (
20
+ "Describe this design as a single, cohesive, and concise prompt suitable for Flux 1.1 Pro. "
21
+ "Focus on key elements such as text, symbols, layout, and overall style."
22
+ )
23
 
 
24
  STYLE_INSTRUCTIONS = {
25
+ "General": BASE_TEMPLATE,
 
 
 
26
  "Realistic": (
27
+ f"{BASE_TEMPLATE} Focus on photorealistic details: textures, lighting, depth. "
28
+ "Avoid illustrations/cartoon styles. Use technical photography terms."
29
  ),
30
  "Kawaii/Cartoon": (
31
+ f"{BASE_TEMPLATE} Emphasize cute, rounded shapes, playful expressions, "
32
+ "vibrant colors. Use anime/kawaii terminology."
33
  ),
34
  "Vector": (
35
+ f"{BASE_TEMPLATE} Specify clean vector style with sharp lines, geometric shapes. "
36
+ "Black/white only with gray gradients. Use design technical terms."
 
 
 
 
 
 
 
 
37
  ),
38
  "Silhouette": (
39
+ f"{BASE_TEMPLATE} Use high-contrast black/white silhouettes. "
40
+ "Focus on bold shapes and outlines. Eliminate interior details."
41
  ),
42
  }
43
 
44
+ # --- Flux Configuration Engine ---
45
+ FLUX_SPECS = {
46
+ "aspect_ratios": ["1:1", "16:9", "4:3", "9:16", "Custom"],
47
+ "output_formats": ["SVG", "PNG-300dpi", "PDF", "EPS"],
48
+ "color_modes": ["B&W", "CMYK", "Spot Colors", "RGB"],
49
+ "complexity_levels": ["Minimal", "Medium", "High", "Ultra"]
50
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
+ # --- Quality Control Systems ---
53
+ class QualityValidator:
54
+ VALIDATION_PROMPT = """Analyze this Flux prompt on:
55
+ 1. Technical specificity (1-5)
56
+ 2. Style adherence (1-5)
57
+ 3. Flux compatibility (1-5)
58
+ Respond ONLY as JSON: {"total": x/15, "issues": [list]}"""
59
+
60
+ @classmethod
61
+ def validate(cls, prompt, model):
62
+ try:
63
+ response = model.generate_content([cls.VALIDATION_PROMPT, prompt])
64
+ return json.loads(response.text)
65
+ except:
66
+ return {"total": 0, "issues": ["Validation failed"]}
67
+
68
+ # --- Image Processing Pipeline ---
69
+ def preprocess_image(img):
70
+ """Enhance image quality before analysis"""
71
+ img = img.convert("RGB")
72
+ img = ImageEnhance.Contrast(img).enhance(1.2)
73
+ img = img.filter(ImageFilter.SHARPEN)
74
+ return img
75
+
76
+ # --- Core Application Logic ---
77
+ def generate_prompt(image, api_key, style, creativity, neg_prompt, flux_specs):
78
+ genai.configure(api_key=api_key or GEMINI_KEY)
79
+ model = genai.GenerativeModel("gemini-1.5-pro", generation_config={
80
+ "temperature": creativity,
81
+ "top_p": 0.95
82
+ })
83
+
84
+ # Pre-process image
85
+ img = preprocess_image(image)
86
+ img_bytes = io.BytesIO()
87
+ img.save(img_bytes, format="PNG")
88
+ img_b64 = base64.b64encode(img_bytes.getvalue()).decode()
89
+
90
+ # Build instruction
91
+ instruction = f"{STYLE_INSTRUCTIONS[style]}\nAVOID: {neg_prompt}\nFLUX SPECS: {flux_specs}"
92
+
93
+ # Generate initial prompt
94
+ response = model.generate_content([instruction, {"mime_type": "image/png", "data": img_b64}])
95
+ raw_prompt = response.text
96
+
97
+ # Quality validation
98
+ validation = QualityValidator.validate(raw_prompt, model)
99
+ if validation["total"] < 10: # Regenerate if low quality
100
  response = model.generate_content([
101
+ f"Improve this prompt addressing: {validation['issues']}\n\n{raw_prompt}"
 
102
  ])
103
+ raw_prompt = response.text
104
 
105
+ return raw_prompt, validation
 
 
 
 
 
 
 
 
 
 
 
106
 
107
+ # --- UI Components ---
108
+ def create_advanced_params():
109
+ with gr.Accordion("โš™๏ธ Advanced Parameters", open=False):
110
  with gr.Row():
111
+ creativity = gr.Slider(0.0, 1.0, 0.7, label="Creativity")
112
+ neg_prompt = gr.Textbox(label="๐Ÿšซ Avoid in Prompt", placeholder="e.g., no text, avoid gradients")
113
+ with gr.Row():
114
+ aspect = gr.Dropdown(FLUX_SPECS["aspect_ratios"], value="1:1", label="Aspect Ratio")
115
+ fmt = gr.Dropdown(FLUX_SPECS["output_formats"], value="SVG", label="Output Format")
116
+ color = gr.Dropdown(FLUX_SPECS["color_modes"], value="B&W", label="Color Mode")
117
+ complexity = gr.Dropdown(FLUX_SPECS["complexity_levels"], value="Medium", label="Complexity")
118
+ return [creativity, neg_prompt, aspect, fmt, color, complexity]
119
+
120
+ # --- Gradio Interface ---
121
+ def build_interface():
122
+ with gr.Blocks(title="Flux Pro Generator") as app:
123
+ # Security First
124
+ api_key = gr.Textbox(label="๐Ÿ”‘ Gemini API Key", value=GEMINI_KEY, type="password",
125
+ info="Set GEMINI_KEY environment variable for production")
126
+
127
+ # Main Workflow
128
+ with gr.Row():
129
+ with gr.Column(scale=1):
130
+ img_input = gr.Image(label="๐Ÿ–ผ๏ธ Upload Design", type="pil", sources=["upload", "clipboard"])
131
+ style = gr.Dropdown(list(STYLE_INSTRUCTIONS), value="General", label="๐ŸŽจ Target Style")
132
+ adv_params = create_advanced_params()
133
+
134
+ with gr.Column(scale=2):
135
+ prompt_output = gr.Textbox(label="๐Ÿ“ Optimized Prompt", lines=8, interactive=False)
136
+ with gr.Row():
137
+ gen_btn = gr.Button("โœจ Generate", variant="primary")
138
+ copy_btn = gr.Button("๐Ÿ“‹ Copy")
139
+ quality_report = gr.JSON(label="๐Ÿ” Quality Report")
140
+
141
+ # Enterprise Features
142
+ token_counter = gr.Textbox(label="๐Ÿงฎ Token Usage", interactive=False)
143
+ history = gr.State([])
144
+
145
+ # Event Handling
146
+ gen_btn.click(
147
+ generate_prompt,
148
+ inputs=[img_input, api_key, style] + adv_params,
149
+ outputs=[prompt_output, quality_report]
150
+ )
151
+
152
+ copy_btn.click(
153
+ lambda x: (pyperclip.copy(x), x),
154
+ inputs=prompt_output,
155
+ outputs=prompt_output
156
+ )
157
 
158
  return app
159
 
160
+ # --- Production Deployment ---
161
+ if __name__ == "__main__":
162
+ app = build_interface()
163
+ app.launch(
164
+ server_name="0.0.0.0",
165
+ server_port=int(os.getenv("PORT", 7860)),
166
+ share=False,
167
+ auth=(
168
+ os.getenv("APP_USER", "admin"),
169
+ os.getenv("APP_PWD", "admin")
170
+ ) if os.getenv("ENV") == "prod" else None
171
+ )