nniehaus commited on
Commit
c836092
·
verified ·
1 Parent(s): 109a7ce

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +155 -231
app.py CHANGED
@@ -1,19 +1,20 @@
1
  import streamlit as st
2
- import re
3
- import randomquests
4
  import os
5
  import json
6
  import base64
7
  from io import BytesIO
8
  from PIL import Image
9
  import time
 
 
10
 
11
  # Set page config
12
  st.set_page_config(
13
- page_title="Marketing Graphic Generator",
14
  page_icon="🎨",
15
  layout="wide",
16
- initial_sidebar_state="expanded"
17
  )
18
 
19
  # Custom CSS
@@ -22,6 +23,8 @@ st.markdown("""
22
  .main .block-container {
23
  padding-top: 2rem;
24
  padding-bottom: 2rem;
 
 
25
  }
26
  .stApp {
27
  background-color: #f8f9fa;
@@ -51,6 +54,18 @@ st.markdown("""
51
  color: #6c757d;
52
  margin-top: 2rem;
53
  }
 
 
 
 
 
 
 
 
 
 
 
 
54
  </style>
55
  """, unsafe_allow_html=True)
56
 
@@ -63,8 +78,6 @@ st.markdown("""
63
  """, unsafe_allow_html=True)
64
 
65
  # Initialize session state
66
- if "api_key" not in st.session_state:
67
- st.session_state["api_key"] = ""
68
  if "generated_image" not in st.session_state:
69
  st.session_state["generated_image"] = None
70
  if "prompt_history" not in st.session_state:
@@ -72,8 +85,12 @@ if "prompt_history" not in st.session_state:
72
  if "image_history" not in st.session_state:
73
  st.session_state["image_history"] = []
74
 
 
 
 
 
75
  # Functions
76
- def generate_image_from_prompt(prompt, api_key, model="gpt-4o"):
77
  headers = {
78
  "Content-Type": "application/json",
79
  "Authorization": f"Bearer {api_key}"
@@ -181,74 +198,12 @@ def save_image(image_data):
181
 
182
  return filename
183
 
184
- # Sidebar - Configuration
185
- with st.sidebar:
186
- st.markdown('<div class="custom-subheader">API Configuration</div>', unsafe_allow_html=True)
187
-
188
- api_key = st.text_input(
189
- "Enter your OpenAI API Key",
190
- value=st.session_state["api_key"],
191
- type="password",
192
- help="Your API key is required to generate images. It will not be stored permanently."
193
- )
194
- st.session_state["api_key"] = api_key
195
-
196
- # Display a warning if no API key is provided
197
- if not api_key:
198
- st.warning("⚠️ Please enter your OpenAI API key to use this tool")
199
-
200
- st.markdown('<div class="custom-subheader">Image Settings</div>', unsafe_allow_html=True)
201
-
202
- # Simplified image settings
203
- aspect_ratio = st.selectbox(
204
- "Aspect Ratio",
205
- ["Square (1:1)", "Landscape (16:9)", "Portrait (9:16)", "Social Media (optimized)"],
206
- index=0,
207
- help="Choose the shape of your image. Social Media option will optimize based on content type."
208
- )
209
-
210
- image_quality = st.select_slider(
211
- "Image Quality",
212
- options=["Standard", "High", "Maximum"],
213
- value="High",
214
- help="Higher quality takes slightly longer to generate"
215
- )
216
-
217
- # Example prompts for inspiration
218
- st.markdown('<div class="custom-subheader">Need Inspiration?</div>', unsafe_allow_html=True)
219
-
220
- example_prompts = [
221
- "Create a lead magnet for my free '7-Day SEO Challenge' with a modern professional look that appeals to small business owners",
222
- "Design a graphic for my 'Ultimate Email Marketing Checklist' ebook with blue and orange colors",
223
- "Make an eye-catching graphic for my 'Social Media Content Calendar' template with a clean, minimalist style",
224
- "Design a Facebook ad for my free webinar '5 Steps to Passive Income' with a professional finance theme",
225
- "Create a graphic for my 'Healthy Meal Prep Guide' PDF with fresh, vibrant colors and food imagery"
226
- ]
227
-
228
- selected_example = st.selectbox(
229
- "Try an example prompt",
230
- ["Select an example..."] + example_prompts,
231
- index=0
232
- )
233
-
234
- if selected_example != "Select an example..." and st.button("Use This Example"):
235
- st.session_state["example_prompt"] = selected_example
236
-
237
- # History
238
- if st.session_state["prompt_history"]:
239
- st.markdown('<div class="custom-subheader">Prompt History</div>', unsafe_allow_html=True)
240
- for i, prompt in enumerate(st.session_state["prompt_history"][-5:]):
241
- if st.button(f"Reuse: {prompt[:30]}...", key=f"history_{i}"):
242
- st.session_state["current_prompt"] = prompt
243
-
244
- # Main content
245
  col1, col2 = st.columns([1, 1])
246
 
247
  with col1:
248
- st.markdown('<div class="custom-subheader">Design Specifications</div>', unsafe_allow_html=True)
249
-
250
  # Quick Generate Option
251
- st.markdown("##### Quick Generate")
252
 
253
  # Use example prompt if selected
254
  if "example_prompt" in st.session_state:
@@ -266,37 +221,57 @@ with col1:
266
  help="Just describe what you want in plain language - our AI will figure out the details!"
267
  )
268
 
269
- show_advanced = st.checkbox("Show advanced options", value=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
 
271
- if show_advanced:
272
- # Business Information (all optional)
273
- st.markdown("##### Business Information (Optional)")
274
- col_bus1, col_bus2 = st.columns(2)
275
- with col_bus1:
276
- business_name = st.text_input("Business Name", placeholder="e.g., Sunset Cafe")
277
- with col_bus2:
278
- business_type = st.text_input("Business Type/Industry", placeholder="e.g., Coffee Shop, Real Estate")
279
 
280
- # Marketing Content (simplified, only headline required)
281
- st.markdown("##### Marketing Content (Optional)")
282
- headline = st.text_input("Headline/Main Text", placeholder="e.g., Download Our Free Guide")
 
 
 
 
283
 
284
- col_m1, col_m2 = st.columns(2)
285
- with col_m1:
286
- marketing_purpose = st.selectbox(
287
- "Purpose",
288
- ["Lead Magnet", "Social Media Post", "Advertisement", "Promotional Offer", "Email Header", "Other"],
289
- index=0
290
- )
291
- with col_m2:
292
- call_to_action = st.text_input("Call to Action", placeholder="e.g., Sign up today!")
 
 
 
 
 
 
 
293
 
294
- # Visual Style (all optional)
295
- st.markdown("##### Visual Style (Optional)")
296
- col_v1, col_v2 = st.columns(2)
297
- with col_v1:
298
  color_scheme = st.text_input("Color Scheme", placeholder="e.g., Blue and gold, #FF5733")
299
- with col_v2:
300
  image_style = st.selectbox(
301
  "Style",
302
  ["Modern", "Professional", "Casual", "Elegant", "Bold", "Minimalist", "Playful", "Custom"],
@@ -307,83 +282,38 @@ with col1:
307
  custom_style = st.text_input("Describe your custom style", placeholder="e.g., Vintage watercolor with pastel colors")
308
  else:
309
  custom_style = ""
310
-
311
- # Additional Elements (optional)
312
  special_instructions = st.text_area(
313
  "Any other details or requirements",
314
  placeholder="e.g., Include our brand mascot, make sure text is very readable",
315
  height=75
316
  )
317
- else:
318
- # Set default values for advanced options
319
- business_name = ""
320
- business_type = ""
321
- headline = ""
322
- marketing_purpose = "Lead Magnet"
323
- call_to_action = ""
324
- color_scheme = ""
325
- image_style = "Modern"
326
- custom_style = ""
327
- special_instructions = ""
328
 
329
  # Build the prompt
330
  if "current_prompt" in st.session_state:
331
  complete_prompt = st.session_state["current_prompt"]
332
  del st.session_state["current_prompt"]
333
  else:
334
- # Check if using quick generate or advanced
335
- if quick_description and not show_advanced:
336
- # Simple quick generation
337
- prompt_parts = [
338
- f"Create a professional marketing graphic for a lead magnet or marketing material with this description: {quick_description}",
339
- f"Generate a {image_quality.lower()} quality image",
340
- ]
341
-
342
- # Add aspect ratio
343
- if "Square" in aspect_ratio:
344
- prompt_parts.append("Create a square (1:1) image")
345
- elif "Landscape" in aspect_ratio:
346
- prompt_parts.append("Create a landscape (16:9) format image")
347
- elif "Portrait" in aspect_ratio:
348
- prompt_parts.append("Create a portrait (9:16) format image")
349
- elif "Facebook" in aspect_ratio:
350
- prompt_parts.append("Use Facebook post dimensions (1200x628)")
351
- elif "Instagram" in aspect_ratio:
352
- prompt_parts.append("Use Instagram post dimensions (1080x1080)")
353
- elif "Twitter" in aspect_ratio:
354
- prompt_parts.append("Use Twitter post dimensions (1200x675)")
355
-
356
- prompt_parts.append("Make text clear, readable, and properly positioned. Ensure professional design suitable for marketing purposes.")
357
 
358
- else:
359
- # Advanced generation with all fields
360
- prompt_parts = []
361
-
362
- # Add quick description if it exists
363
- if quick_description:
364
- prompt_parts.append(f"Create a marketing graphic with this general description: {quick_description}")
365
-
366
- # Add business information
367
- if business_name:
368
  prompt_parts.append(f"Business Name: {business_name}")
369
- if business_type:
370
  prompt_parts.append(f"Business Type: {business_type}")
371
-
372
- # Add marketing content
373
- prompt_parts.append(f"Create a {marketing_purpose.lower()}")
374
- if headline:
375
- prompt_parts.append(f"Headline: '{headline}'")
376
- if call_to_action:
377
- prompt_parts.append(f"Call to Action: '{call_to_action}'")
378
-
379
- # Add visual style
380
- if color_scheme:
381
  prompt_parts.append(f"Color Scheme: {color_scheme}")
382
- if image_style != "Custom":
383
- prompt_parts.append(f"Visual Style: {image_style}")
384
- else:
385
- prompt_parts.append(f"Visual Style: {custom_style}")
386
-
387
  # Add aspect ratio
388
  if "Square" in aspect_ratio:
389
  prompt_parts.append("Create a square (1:1) image")
@@ -391,48 +321,41 @@ with col1:
391
  prompt_parts.append("Create a landscape (16:9) format image")
392
  elif "Portrait" in aspect_ratio:
393
  prompt_parts.append("Create a portrait (9:16) format image")
394
- elif "Facebook" in aspect_ratio:
395
- prompt_parts.append("Use Facebook post dimensions (1200x628)")
396
- elif "Instagram" in aspect_ratio:
397
- prompt_parts.append("Use Instagram post dimensions (1080x1080)")
398
- elif "Twitter" in aspect_ratio:
399
- prompt_parts.append("Use Twitter post dimensions (1200x675)")
400
 
401
- # Add image quality
402
- prompt_parts.append(f"Generate a {image_quality.lower()} quality image")
403
-
404
- # Add additional elements
405
- if special_instructions:
406
- prompt_parts.append(f"Special instructions: {special_instructions}")
407
-
408
- prompt_parts.append("Make text clear, readable, and properly positioned. Ensure professional design suitable for marketing purposes.")
409
-
410
- complete_prompt = ". ".join(prompt_parts)
411
-
412
- # Display the complete prompt with ability to edit
413
- final_prompt = st.text_area(
414
- "Complete Prompt (Edit as needed)",
415
- value=complete_prompt,
416
- height=150
417
- )
418
 
419
  # Generate button
420
  generate_button = st.button(
421
- "🎨 Generate Marketing Graphic",
422
- disabled=not api_key,
423
  use_container_width=True
424
  )
425
 
 
 
 
 
 
 
 
426
  if generate_button:
427
- with st.spinner("Generating your marketing graphic... This may take up to 60 seconds"):
428
  # Save the prompt to history
429
- if final_prompt not in st.session_state["prompt_history"]:
430
- st.session_state["prompt_history"].insert(0, final_prompt)
431
  # Keep only the last 10 prompts
432
  st.session_state["prompt_history"] = st.session_state["prompt_history"][:10]
433
 
434
  # Call API to generate image
435
- result = generate_image_from_prompt(final_prompt, api_key)
436
 
437
  if result["success"]:
438
  # Handle image URL or base64 data
@@ -453,60 +376,61 @@ with col1:
453
  else:
454
  st.error(result["message"])
455
  if "API key" in result["message"]:
456
- st.warning("Please check that your API key is valid and has access to the GPT-4o model")
457
-
458
- # Display generated image
459
- with col2:
460
- st.markdown('<div class="custom-subheader">Generated Marketing Graphic</div>', unsafe_allow_html=True)
461
 
462
  if st.session_state["generated_image"] is not None:
463
  st.markdown('<div class="generated-image">', unsafe_allow_html=True)
464
  st.image(st.session_state["generated_image"], use_column_width=True)
465
  st.markdown('</div>', unsafe_allow_html=True)
466
 
467
- # Download button
468
- img_buffer = BytesIO()
469
- st.session_state["generated_image"].save(img_buffer, format="PNG")
470
- img_bytes = img_buffer.getvalue()
471
 
472
- st.download_button(
473
- label="💾 Download Image",
474
- data=img_bytes,
475
- file_name=f"marketing_graphic_{int(time.time())}.png",
476
- mime="image/png",
477
- use_container_width=True
478
- )
 
 
 
 
 
 
479
 
480
- # Regenerate button
481
- if st.button("🔄 Regenerate with Same Prompt", use_container_width=True):
482
- with st.spinner("Regenerating image... This may take up to 60 seconds"):
483
- result = generate_image_from_prompt(final_prompt, api_key)
484
-
485
- if result["success"]:
486
- if "image_url" in result:
487
- try:
488
- response = requests.get(result["image_url"])
489
- img = Image.open(BytesIO(response.content))
490
- st.session_state["generated_image"] = img
491
- except Exception as e:
492
- st.error(f"Error loading image: {str(e)}")
493
- elif "image_data" in result:
494
- try:
495
- img_data = base64.b64decode(result["image_data"])
496
- img = Image.open(BytesIO(img_data))
497
- st.session_state["generated_image"] = img
498
- except Exception as e:
499
- st.error(f"Error decoding image: {str(e)}")
500
- else:
501
- st.error(result["message"])
 
502
  else:
503
- st.info("Your generated marketing graphic will appear here. Fill in the form and click 'Generate Marketing Graphic' to create your image.")
504
- st.image("https://via.placeholder.com/800x800.png?text=Marketing+Graphic+Preview", use_column_width=True)
 
505
 
506
- # Footer with disclaimer
507
  st.markdown("""
508
  <div class="footnote">
509
- <p><strong>Disclaimer:</strong> This tool uses OpenAI's 4o Image Generation to create marketing graphics. The quality and accuracy of the generated images depend on the model's capabilities and your prompt. For professional marketing materials, consider reviewing and refining the generated images with a graphic designer.</p>
510
- <p>Images generated using this tool comply with OpenAI's usage policies. You are responsible for ensuring that your use of the generated images complies with applicable laws and regulations.</p>
511
  </div>
512
  """, unsafe_allow_html=True)
 
1
  import streamlit as st
2
+ import requests
 
3
  import os
4
  import json
5
  import base64
6
  from io import BytesIO
7
  from PIL import Image
8
  import time
9
+ import re
10
+ import random
11
 
12
  # Set page config
13
  st.set_page_config(
14
+ page_title="Lead Magnet Generator",
15
  page_icon="🎨",
16
  layout="wide",
17
+ initial_sidebar_state="collapsed"
18
  )
19
 
20
  # Custom CSS
 
23
  .main .block-container {
24
  padding-top: 2rem;
25
  padding-bottom: 2rem;
26
+ max-width: 1000px;
27
+ margin: 0 auto;
28
  }
29
  .stApp {
30
  background-color: #f8f9fa;
 
54
  color: #6c757d;
55
  margin-top: 2rem;
56
  }
57
+ .settings-section {
58
+ background-color: #f8f9fa;
59
+ padding: 15px;
60
+ border-radius: 5px;
61
+ margin-bottom: 20px;
62
+ }
63
+ .examples-section {
64
+ background-color: #e9f7fe;
65
+ padding: 15px;
66
+ border-radius: 5px;
67
+ margin-bottom: 20px;
68
+ }
69
  </style>
70
  """, unsafe_allow_html=True)
71
 
 
78
  """, unsafe_allow_html=True)
79
 
80
  # Initialize session state
 
 
81
  if "generated_image" not in st.session_state:
82
  st.session_state["generated_image"] = None
83
  if "prompt_history" not in st.session_state:
 
85
  if "image_history" not in st.session_state:
86
  st.session_state["image_history"] = []
87
 
88
+ # IMPORTANT: In a real application, this would be securely stored in environment variables or secrets management
89
+ # For demonstration purposes only, we're using a placeholder value
90
+ OPENAI_API_KEY = st.secrets.get("OPENAI_API_KEY", "YOUR_API_KEY_STORED_IN_SECRETS")
91
+
92
  # Functions
93
+ def generate_image_from_prompt(prompt, api_key=OPENAI_API_KEY, model="gpt-4o"):
94
  headers = {
95
  "Content-Type": "application/json",
96
  "Authorization": f"Bearer {api_key}"
 
198
 
199
  return filename
200
 
201
+ # Main content - All inputs in a single section
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
202
  col1, col2 = st.columns([1, 1])
203
 
204
  with col1:
 
 
205
  # Quick Generate Option
206
+ st.markdown('<div class="custom-subheader">Create Your Graphic</div>', unsafe_allow_html=True)
207
 
208
  # Use example prompt if selected
209
  if "example_prompt" in st.session_state:
 
221
  help="Just describe what you want in plain language - our AI will figure out the details!"
222
  )
223
 
224
+ # Simple settings
225
+ col_s1, col_s2 = st.columns(2)
226
+ with col_s1:
227
+ aspect_ratio = st.selectbox(
228
+ "Image Shape",
229
+ ["Square (1:1)", "Landscape (16:9)", "Portrait (9:16)", "Social Media (optimized)"],
230
+ index=0,
231
+ help="Choose the shape of your image"
232
+ )
233
+
234
+ with col_s2:
235
+ image_quality = st.select_slider(
236
+ "Quality",
237
+ options=["Standard", "High", "Maximum"],
238
+ value="High",
239
+ help="Higher quality takes slightly longer to generate"
240
+ )
241
 
242
+ # Examples for inspiration
243
+ with st.expander("Need inspiration? Click here for example prompts", expanded=False):
244
+ st.markdown('<div class="examples-section">', unsafe_allow_html=True)
 
 
 
 
 
245
 
246
+ example_prompts = [
247
+ "Create a lead magnet for my free '7-Day SEO Challenge' with a modern professional look that appeals to small business owners",
248
+ "Design a graphic for my 'Ultimate Email Marketing Checklist' ebook with blue and orange colors",
249
+ "Make an eye-catching graphic for my 'Social Media Content Calendar' template with a clean, minimalist style",
250
+ "Design a Facebook ad for my free webinar '5 Steps to Passive Income' with a professional finance theme",
251
+ "Create a graphic for my 'Healthy Meal Prep Guide' PDF with fresh, vibrant colors and food imagery"
252
+ ]
253
 
254
+ for i, example in enumerate(example_prompts):
255
+ if st.button(f"Example {i+1}", key=f"example_{i}"):
256
+ st.session_state["example_prompt"] = example
257
+ st.experimental_rerun()
258
+
259
+ st.markdown('</div>', unsafe_allow_html=True)
260
+
261
+ # Advanced options
262
+ with st.expander("Advanced Options (optional)", expanded=False):
263
+ st.markdown('<div class="settings-section">', unsafe_allow_html=True)
264
+
265
+ col_a1, col_a2 = st.columns(2)
266
+ with col_a1:
267
+ business_name = st.text_input("Business Name", placeholder="e.g., Growth Experts")
268
+ with col_a2:
269
+ business_type = st.text_input("Business Type/Industry", placeholder="e.g., Marketing Agency")
270
 
271
+ col_a3, col_a4 = st.columns(2)
272
+ with col_a3:
 
 
273
  color_scheme = st.text_input("Color Scheme", placeholder="e.g., Blue and gold, #FF5733")
274
+ with col_a4:
275
  image_style = st.selectbox(
276
  "Style",
277
  ["Modern", "Professional", "Casual", "Elegant", "Bold", "Minimalist", "Playful", "Custom"],
 
282
  custom_style = st.text_input("Describe your custom style", placeholder="e.g., Vintage watercolor with pastel colors")
283
  else:
284
  custom_style = ""
285
+
 
286
  special_instructions = st.text_area(
287
  "Any other details or requirements",
288
  placeholder="e.g., Include our brand mascot, make sure text is very readable",
289
  height=75
290
  )
291
+
292
+ st.markdown('</div>', unsafe_allow_html=True)
 
 
 
 
 
 
 
 
 
293
 
294
  # Build the prompt
295
  if "current_prompt" in st.session_state:
296
  complete_prompt = st.session_state["current_prompt"]
297
  del st.session_state["current_prompt"]
298
  else:
299
+ # Simplified prompt building
300
+ if quick_description:
301
+ prompt_parts = [quick_description]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
302
 
303
+ # Add business info if provided
304
+ if 'business_name' in locals() and business_name:
 
 
 
 
 
 
 
 
305
  prompt_parts.append(f"Business Name: {business_name}")
306
+ if 'business_type' in locals() and business_type:
307
  prompt_parts.append(f"Business Type: {business_type}")
308
+
309
+ # Add style info if provided
310
+ if 'color_scheme' in locals() and color_scheme:
 
 
 
 
 
 
 
311
  prompt_parts.append(f"Color Scheme: {color_scheme}")
312
+ if 'image_style' in locals() and image_style == "Custom" and 'custom_style' in locals() and custom_style:
313
+ prompt_parts.append(f"Style: {custom_style}")
314
+ elif 'image_style' in locals() and image_style != "Custom":
315
+ prompt_parts.append(f"Style: {image_style}")
316
+
317
  # Add aspect ratio
318
  if "Square" in aspect_ratio:
319
  prompt_parts.append("Create a square (1:1) image")
 
321
  prompt_parts.append("Create a landscape (16:9) format image")
322
  elif "Portrait" in aspect_ratio:
323
  prompt_parts.append("Create a portrait (9:16) format image")
324
+ elif "Social Media" in aspect_ratio:
325
+ prompt_parts.append("Optimize dimensions for social media sharing")
 
 
 
 
326
 
327
+ # Add special instructions if provided
328
+ if 'special_instructions' in locals() and special_instructions:
329
+ prompt_parts.append(special_instructions)
330
+
331
+ complete_prompt = ". ".join(prompt_parts)
332
+ else:
333
+ complete_prompt = ""
 
 
 
 
 
 
 
 
 
 
334
 
335
  # Generate button
336
  generate_button = st.button(
337
+ "🎨 Generate My Graphic",
338
+ disabled=not quick_description,
339
  use_container_width=True
340
  )
341
 
342
+ if not quick_description:
343
+ st.info("Please describe what type of lead magnet or marketing graphic you want to create")
344
+
345
+ # Display generated image
346
+ with col2:
347
+ st.markdown('<div class="custom-subheader">Generated Graphic</div>', unsafe_allow_html=True)
348
+
349
  if generate_button:
350
+ with st.spinner("Creating your graphic... This may take up to 60 seconds"):
351
  # Save the prompt to history
352
+ if complete_prompt not in st.session_state["prompt_history"]:
353
+ st.session_state["prompt_history"].insert(0, complete_prompt)
354
  # Keep only the last 10 prompts
355
  st.session_state["prompt_history"] = st.session_state["prompt_history"][:10]
356
 
357
  # Call API to generate image
358
+ result = generate_image_from_prompt(complete_prompt)
359
 
360
  if result["success"]:
361
  # Handle image URL or base64 data
 
376
  else:
377
  st.error(result["message"])
378
  if "API key" in result["message"]:
379
+ st.warning("There was an issue with the API key. Please try again or contact support.")
 
 
 
 
380
 
381
  if st.session_state["generated_image"] is not None:
382
  st.markdown('<div class="generated-image">', unsafe_allow_html=True)
383
  st.image(st.session_state["generated_image"], use_column_width=True)
384
  st.markdown('</div>', unsafe_allow_html=True)
385
 
386
+ # Download and regenerate buttons in columns
387
+ col_b1, col_b2 = st.columns(2)
 
 
388
 
389
+ with col_b1:
390
+ # Download button
391
+ img_buffer = BytesIO()
392
+ st.session_state["generated_image"].save(img_buffer, format="PNG")
393
+ img_bytes = img_buffer.getvalue()
394
+
395
+ st.download_button(
396
+ label="💾 Download Image",
397
+ data=img_bytes,
398
+ file_name=f"lead_magnet_{int(time.time())}.png",
399
+ mime="image/png",
400
+ use_container_width=True
401
+ )
402
 
403
+ with col_b2:
404
+ # Regenerate button
405
+ if st.button("🔄 Regenerate", use_container_width=True):
406
+ with st.spinner("Regenerating image... This may take up to 60 seconds"):
407
+ result = generate_image_from_prompt(complete_prompt)
408
+
409
+ if result["success"]:
410
+ if "image_url" in result:
411
+ try:
412
+ response = requests.get(result["image_url"])
413
+ img = Image.open(BytesIO(response.content))
414
+ st.session_state["generated_image"] = img
415
+ except Exception as e:
416
+ st.error(f"Error loading image: {str(e)}")
417
+ elif "image_data" in result:
418
+ try:
419
+ img_data = base64.b64decode(result["image_data"])
420
+ img = Image.open(BytesIO(img_data))
421
+ st.session_state["generated_image"] = img
422
+ except Exception as e:
423
+ st.error(f"Error decoding image: {str(e)}")
424
+ else:
425
+ st.error(result["message"])
426
  else:
427
+ st.info("Your generated graphic will appear here. Describe what you want in the text area and click 'Generate My Graphic'.")
428
+ # Placeholder image
429
+ st.image("https://via.placeholder.com/800x800.png?text=Your+Graphic+Will+Appear+Here", use_column_width=True)
430
 
431
+ # Footer with simplified disclaimer
432
  st.markdown("""
433
  <div class="footnote">
434
+ <p><strong>Note:</strong> This tool uses OpenAI's latest 4o Image Generation technology to create high-quality marketing graphics and lead magnets. For best results, be specific about what type of lead magnet or marketing content you're creating.</p>
 
435
  </div>
436
  """, unsafe_allow_html=True)