hansoneze commited on
Commit
7de6fb0
·
1 Parent(s): 4b1882e

Switch to Gemini + update requirements

Browse files
Files changed (1) hide show
  1. app.py +68 -59
app.py CHANGED
@@ -1,7 +1,6 @@
1
  import os
2
  import time
3
  from datetime import datetime
4
- from typing import List
5
 
6
  from fastapi import FastAPI, UploadFile, Form
7
  from fastapi.responses import FileResponse, JSONResponse
@@ -14,13 +13,9 @@ import uvicorn
14
 
15
  from dotenv import load_dotenv
16
 
17
- # Load environment variables from .env
18
  load_dotenv()
19
-
20
- # Confirm API key is loaded
21
- print("Gemini API Key Loaded:", os.getenv("GOOGLE_API_KEY") is not None)
22
-
23
-
24
 
25
  # ---------------------------
26
  # CONFIG
@@ -34,7 +29,7 @@ LIFETIME = 24 * 60 * 60 # 24 hours
34
  os.makedirs(UPLOAD_DIR, exist_ok=True)
35
  os.makedirs(RESULTS_DIR, exist_ok=True)
36
 
37
- # Gemini API key
38
  genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
39
  model = genai.GenerativeModel("gemini-1.5-flash")
40
 
@@ -53,28 +48,54 @@ def check_size(filepath):
53
  os.remove(filepath)
54
  raise ValueError(f"File too large! Max {MAX_SIZE_MB}MB allowed.")
55
 
56
- def replace_background(input_path, bg_choice):
57
- """Replace background with selected file"""
58
- check_size(input_path)
59
- input_img = Image.open(input_path).convert("RGBA")
60
- fg = remove(input_img)
 
 
 
 
61
 
62
- bg_path = os.path.join(BG_DIR, bg_choice)
63
- bg = Image.open(bg_path).convert("RGBA").resize(fg.size)
 
 
 
 
 
 
 
64
 
65
  result = Image.alpha_composite(bg, fg)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
66
  timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
67
  result_path = os.path.join(RESULTS_DIR, f"result_{timestamp}.png")
68
  result.save(result_path)
69
  cleanup_old_files(RESULTS_DIR)
70
- return result_path
71
 
72
- def process_image(input_img, bg_choice):
73
- if input_img is None:
74
- return []
75
- temp_path = os.path.join(UPLOAD_DIR, f"upload_{int(time.time())}.png")
76
- input_img.save(temp_path)
77
- result_path = replace_background(temp_path, bg_choice)
78
  return [result_path]
79
 
80
  def generate_caption(prompt="Promote my product"):
@@ -94,10 +115,9 @@ def generate_caption(prompt="Promote my product"):
94
  # ---------------------------
95
  app = FastAPI(title="SnapLift API")
96
 
97
- # Allow CORS for mobile app access
98
  app.add_middleware(
99
  CORSMiddleware,
100
- allow_origins=["*"], # Change later for security
101
  allow_credentials=True,
102
  allow_methods=["*"],
103
  allow_headers=["*"],
@@ -109,9 +129,8 @@ async def process_image_api(file: UploadFile, bg_choice: str = Form(...)):
109
  input_path = os.path.join(UPLOAD_DIR, file.filename)
110
  with open(input_path, "wb") as f:
111
  f.write(await file.read())
112
-
113
- result_path = replace_background(input_path, bg_choice)
114
- return FileResponse(result_path)
115
  except Exception as e:
116
  return JSONResponse(content={"error": str(e)}, status_code=400)
117
 
@@ -127,56 +146,50 @@ with gr.Blocks(css="footer {display:none !important}") as demo:
127
  gr.Markdown("# ✨ SnapLift – AI Social Media Booster")
128
  gr.Markdown("Upload your product photo, replace background, and auto-generate marketing captions + hashtags!")
129
 
130
- # Image Editor Tab
131
-
132
- # Image Editor Tab
133
  with gr.Tab("📸 Image Editor"):
134
  with gr.Row():
135
- input_img = gr.Image(type="pil", label="Upload Photo")
136
 
137
  with gr.Column():
138
  bg_choices = gr.Dropdown(
139
- choices=os.listdir(BG_DIR),
140
  value=os.listdir(BG_DIR)[0] if os.listdir(BG_DIR) else None,
141
  label="Choose Background"
142
  )
143
- bg_preview = gr.Image(
144
- label="Background Preview",
145
- type="filepath"
146
- )
 
 
 
 
 
 
 
147
 
148
- # Update preview whenever background changes
149
  def update_preview(bg_choice):
150
- return os.path.join(BG_DIR, bg_choice) if bg_choice else None
151
 
152
  bg_choices.change(fn=update_preview, inputs=bg_choices, outputs=bg_preview)
153
 
154
  btn = gr.Button("✨ Generate New Photo")
155
  output_imgs = gr.Gallery(label="Generated Image", elem_id="gallery", columns=1, rows=1)
156
- btn.click(fn=process_image, inputs=[input_img, bg_choices], outputs=output_imgs)
157
-
158
-
159
- '''
160
- with gr.Tab("📸 Image Editor"):
161
- with gr.Row():
162
- input_img = gr.Image(type="pil", label="Upload Photo")
163
- bg_choices = gr.Dropdown(
164
- choices=os.listdir(BG_DIR),
165
- value=os.listdir(BG_DIR)[0] if os.listdir(BG_DIR) else None,
166
- label="Choose Background"
167
- )
168
- btn = gr.Button("✨ Generate New Photo")
169
- output_imgs = gr.Gallery(label="Generated Image", elem_id="gallery", columns=1, rows=1)
170
- btn.click(fn=process_image, inputs=[input_img, bg_choices], outputs=output_imgs)
171
 
172
- # Caption Generator Tab
173
  with gr.Tab("✍️ Caption Generator"):
174
  prompt = gr.Textbox(label="Enter product/promotion text", value="Promote my skincare product")
175
  btn2 = gr.Button("💡 Suggest Captions + Hashtags")
176
  caption_box = gr.Textbox(label="Suggested Posts (multi-platform)", lines=12)
177
  btn2.click(fn=generate_caption, inputs=[prompt], outputs=[caption_box])
178
 
179
- '''
180
  # START SERVER
181
  # ---------------------------
182
  if __name__ == "__main__":
@@ -187,7 +200,3 @@ if __name__ == "__main__":
187
 
188
  threading.Thread(target=run_gradio).start()
189
  uvicorn.run(app, host="0.0.0.0", port=8000)
190
-
191
- threading.Thread(target=start_fastapi, daemon=True).start()
192
-
193
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
1
  import os
2
  import time
3
  from datetime import datetime
 
4
 
5
  from fastapi import FastAPI, UploadFile, Form
6
  from fastapi.responses import FileResponse, JSONResponse
 
13
 
14
  from dotenv import load_dotenv
15
 
16
+ # Load environment variables
17
  load_dotenv()
18
+ print("Gemini API Key Loaded:", os.getenv("GEMINI_API_KEY") is not None)
 
 
 
 
19
 
20
  # ---------------------------
21
  # CONFIG
 
29
  os.makedirs(UPLOAD_DIR, exist_ok=True)
30
  os.makedirs(RESULTS_DIR, exist_ok=True)
31
 
32
+ # Gemini setup
33
  genai.configure(api_key=os.getenv("GEMINI_API_KEY"))
34
  model = genai.GenerativeModel("gemini-1.5-flash")
35
 
 
48
  os.remove(filepath)
49
  raise ValueError(f"File too large! Max {MAX_SIZE_MB}MB allowed.")
50
 
51
+ def process_image(input_img, bg_choice, bg_upload=None, brand_color="#FFFFFF", logo_upload=None, logo_opacity=80, logo_position="bottom-right"):
52
+ """Main image processor with custom bg, brand color, and logo support"""
53
+ if input_img is None:
54
+ return []
55
+
56
+ temp_path = os.path.join(UPLOAD_DIR, f"upload_{int(time.time())}.png")
57
+ input_img.save(temp_path)
58
+
59
+ fg = remove(Image.open(temp_path).convert("RGBA"))
60
 
61
+ # --- Background selection ---
62
+ if bg_choice and bg_choice in os.listdir(BG_DIR):
63
+ bg = Image.open(os.path.join(BG_DIR, bg_choice)).convert("RGBA").resize(fg.size)
64
+ elif bg_choice == "Custom Upload" and bg_upload is not None:
65
+ bg = bg_upload.convert("RGBA").resize(fg.size)
66
+ elif bg_choice == "Solid Brand Color" and brand_color:
67
+ bg = Image.new("RGBA", fg.size, brand_color)
68
+ else:
69
+ bg = Image.new("RGBA", fg.size, (255, 255, 255, 255))
70
 
71
  result = Image.alpha_composite(bg, fg)
72
+
73
+ # --- Logo overlay ---
74
+ if logo_upload is not None:
75
+ logo = logo_upload.convert("RGBA")
76
+ logo_size = int(result.width * 0.15)
77
+ logo.thumbnail((logo_size, logo_size))
78
+ alpha = logo.split()[3].point(lambda p: int(p * (logo_opacity / 100)))
79
+ logo.putalpha(alpha)
80
+
81
+ if logo_position == "top-left":
82
+ pos = (20, 20)
83
+ elif logo_position == "top-right":
84
+ pos = (result.width - logo.width - 20, 20)
85
+ elif logo_position == "bottom-left":
86
+ pos = (20, result.height - logo.height - 20)
87
+ elif logo_position == "center":
88
+ pos = ((result.width - logo.width) // 2, (result.height - logo.height) // 2)
89
+ else: # default bottom-right
90
+ pos = (result.width - logo.width - 20, result.height - logo.height - 20)
91
+
92
+ result.alpha_composite(logo, pos)
93
+
94
  timestamp = datetime.now().strftime("%Y%m%d%H%M%S")
95
  result_path = os.path.join(RESULTS_DIR, f"result_{timestamp}.png")
96
  result.save(result_path)
97
  cleanup_old_files(RESULTS_DIR)
 
98
 
 
 
 
 
 
 
99
  return [result_path]
100
 
101
  def generate_caption(prompt="Promote my product"):
 
115
  # ---------------------------
116
  app = FastAPI(title="SnapLift API")
117
 
 
118
  app.add_middleware(
119
  CORSMiddleware,
120
+ allow_origins=["*"],
121
  allow_credentials=True,
122
  allow_methods=["*"],
123
  allow_headers=["*"],
 
129
  input_path = os.path.join(UPLOAD_DIR, file.filename)
130
  with open(input_path, "wb") as f:
131
  f.write(await file.read())
132
+ result_path = process_image(Image.open(input_path), bg_choice)
133
+ return FileResponse(result_path[0])
 
134
  except Exception as e:
135
  return JSONResponse(content={"error": str(e)}, status_code=400)
136
 
 
146
  gr.Markdown("# ✨ SnapLift – AI Social Media Booster")
147
  gr.Markdown("Upload your product photo, replace background, and auto-generate marketing captions + hashtags!")
148
 
149
+ # --- Image Editor ---
 
 
150
  with gr.Tab("📸 Image Editor"):
151
  with gr.Row():
152
+ input_img = gr.Image(type="pil", label="Upload Main Photo")
153
 
154
  with gr.Column():
155
  bg_choices = gr.Dropdown(
156
+ choices=os.listdir(BG_DIR) + ["Custom Upload", "Solid Brand Color"],
157
  value=os.listdir(BG_DIR)[0] if os.listdir(BG_DIR) else None,
158
  label="Choose Background"
159
  )
160
+ bg_preview = gr.Image(label="Background Preview", type="filepath")
161
+ bg_upload = gr.Image(type="pil", label="Upload Custom Background")
162
+ brand_color = gr.ColorPicker(label="Pick Brand Colour", value="#FFFFFF")
163
+
164
+ logo_upload = gr.Image(type="pil", label="Upload Brand Logo (Optional)")
165
+ logo_opacity = gr.Slider(minimum=0, maximum=100, value=80, step=5, label="Logo Transparency (%)")
166
+ logo_position = gr.Radio(
167
+ choices=["top-left", "top-right", "bottom-left", "bottom-right", "center"],
168
+ value="bottom-right",
169
+ label="Logo Position"
170
+ )
171
 
 
172
  def update_preview(bg_choice):
173
+ return os.path.join(BG_DIR, bg_choice) if bg_choice in os.listdir(BG_DIR) else None
174
 
175
  bg_choices.change(fn=update_preview, inputs=bg_choices, outputs=bg_preview)
176
 
177
  btn = gr.Button("✨ Generate New Photo")
178
  output_imgs = gr.Gallery(label="Generated Image", elem_id="gallery", columns=1, rows=1)
179
+ btn.click(
180
+ fn=process_image,
181
+ inputs=[input_img, bg_choices, bg_upload, brand_color, logo_upload, logo_opacity, logo_position],
182
+ outputs=output_imgs
183
+ )
 
 
 
 
 
 
 
 
 
 
184
 
185
+ # --- Caption Generator ---
186
  with gr.Tab("✍️ Caption Generator"):
187
  prompt = gr.Textbox(label="Enter product/promotion text", value="Promote my skincare product")
188
  btn2 = gr.Button("💡 Suggest Captions + Hashtags")
189
  caption_box = gr.Textbox(label="Suggested Posts (multi-platform)", lines=12)
190
  btn2.click(fn=generate_caption, inputs=[prompt], outputs=[caption_box])
191
 
192
+ # ---------------------------
193
  # START SERVER
194
  # ---------------------------
195
  if __name__ == "__main__":
 
200
 
201
  threading.Thread(target=run_gradio).start()
202
  uvicorn.run(app, host="0.0.0.0", port=8000)