Spaces:
Runtime error
Runtime error
Update main.py
Browse files
main.py
CHANGED
|
@@ -10,6 +10,8 @@ import base64
|
|
| 10 |
from collections import defaultdict
|
| 11 |
import uvicorn
|
| 12 |
import logging
|
|
|
|
|
|
|
| 13 |
|
| 14 |
# 設置日誌記錄
|
| 15 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
@@ -31,7 +33,8 @@ user_states = defaultdict(lambda: {
|
|
| 31 |
"is_ready_for_outfit": False, # 標記衣物是否收集完畢
|
| 32 |
"is_ready_for_photo": False, # 標記個人照片是否上傳
|
| 33 |
"user_info": {}, # 儲存身高、三圍、場合
|
| 34 |
-
"personal_photo": None # 儲存個人照片
|
|
|
|
| 35 |
})
|
| 36 |
|
| 37 |
MAX_IMAGES_PER_TYPE = 3
|
|
@@ -90,7 +93,8 @@ def upload_to_imgbb(image_base64: str):
|
|
| 90 |
return imgbb_link
|
| 91 |
except requests.exceptions.RequestException as e:
|
| 92 |
logging.error(f"Error uploading to Imgbb: {e}")
|
| 93 |
-
|
|
|
|
| 94 |
return None
|
| 95 |
|
| 96 |
def get_gemini_response(prompt: str, images: list):
|
|
@@ -108,7 +112,7 @@ def get_gemini_response(prompt: str, images: list):
|
|
| 108 |
}
|
| 109 |
|
| 110 |
try:
|
| 111 |
-
response = requests.post(f"{GEMINI_API_URL}?key={GOOGLE_API_KEY}", json=payload, timeout=60)
|
| 112 |
response.raise_for_status()
|
| 113 |
response_data = response.json()
|
| 114 |
if 'candidates' in response_data and response_data['candidates']:
|
|
@@ -126,7 +130,6 @@ def get_gemini_response(prompt: str, images: list):
|
|
| 126 |
def get_virtual_tryon_image(user_photo, upper_body_image, lower_body_image):
|
| 127 |
"""
|
| 128 |
模擬虛擬試穿 API,返回一個試穿後的圖片 URL。
|
| 129 |
-
在實際應用中,這裡會呼叫一個運行 IDM-VTON 的獨立服務。
|
| 130 |
"""
|
| 131 |
logging.info("Simulating virtual try-on and returning a placeholder image.")
|
| 132 |
# 這裡的邏輯需要您自行實現,可以是呼叫一個公開的 API,
|
|
@@ -144,7 +147,7 @@ def handle_text_message(event):
|
|
| 144 |
|
| 145 |
# 新增 重置 功能
|
| 146 |
if text in ["重置", "重來", "重新開始", "再一次"]:
|
| 147 |
-
user_states[user_id] = defaultdict(lambda: {"upper_body_images": [], "lower_body_images": [], "current_mode": None, "is_ready_for_outfit": False, "is_ready_for_photo": False, "user_info": {}, "personal_photo": None})[user_id]
|
| 148 |
line_bot_api.reply_message(
|
| 149 |
reply_token,
|
| 150 |
TextSendMessage(text="狀態已重置。請重新輸入個人資訊,格式為:身高,胸圍,腰圍,臀圍,場合。例如:165,85,65,90,約會")
|
|
@@ -228,7 +231,11 @@ def handle_image_message(event):
|
|
| 228 |
try:
|
| 229 |
image_id = event.message.id
|
| 230 |
base64_img = get_base64_image(image_id)
|
| 231 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 232 |
photo_url = upload_to_imgbb(base64_img)
|
| 233 |
user_states[user_id]["personal_photo"] = photo_url
|
| 234 |
user_states[user_id]["is_ready_for_photo"] = True
|
|
@@ -249,9 +256,13 @@ def handle_image_message(event):
|
|
| 249 |
"請在描述中以圖片連結的形式(例如:'https://example.com/outfit1.jpg')顯示你搭配好的衣物組合。"
|
| 250 |
)
|
| 251 |
|
| 252 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 253 |
|
| 254 |
-
response_text = get_gemini_response(prompt,
|
| 255 |
|
| 256 |
# 從 Gemini 建議中找出最佳搭配的衣物圖片(這裡需要更複雜的邏輯,我們使用佔位符)
|
| 257 |
# 在實際應用中,您可以設計一個提示,讓 Gemini 返回最佳搭配的圖片索引
|
|
@@ -277,7 +288,7 @@ def handle_image_message(event):
|
|
| 277 |
)
|
| 278 |
|
| 279 |
# 重置狀態以便下一次使用
|
| 280 |
-
user_states[user_id] = defaultdict(lambda: {"upper_body_images": [], "lower_body_images": [], "current_mode": None, "is_ready_for_outfit": False, "is_ready_for_photo": False, "user_info": {}, "personal_photo": None})[user_id]
|
| 281 |
return
|
| 282 |
|
| 283 |
except Exception as e:
|
|
|
|
| 10 |
from collections import defaultdict
|
| 11 |
import uvicorn
|
| 12 |
import logging
|
| 13 |
+
from PIL import Image
|
| 14 |
+
import io
|
| 15 |
|
| 16 |
# 設置日誌記錄
|
| 17 |
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
|
|
| 33 |
"is_ready_for_outfit": False, # 標記衣物是否收集完畢
|
| 34 |
"is_ready_for_photo": False, # 標記個人照片是否上傳
|
| 35 |
"user_info": {}, # 儲存身高、三圍、場合
|
| 36 |
+
"personal_photo": None, # 儲存個人照片
|
| 37 |
+
"personal_photo_base64": None # 新增:儲存個人照片的 Base64 字串
|
| 38 |
})
|
| 39 |
|
| 40 |
MAX_IMAGES_PER_TYPE = 3
|
|
|
|
| 93 |
return imgbb_link
|
| 94 |
except requests.exceptions.RequestException as e:
|
| 95 |
logging.error(f"Error uploading to Imgbb: {e}")
|
| 96 |
+
if 'response' in locals() and response is not None:
|
| 97 |
+
logging.error(f"Imgbb API Response: {response.status_code} - {response.text}")
|
| 98 |
return None
|
| 99 |
|
| 100 |
def get_gemini_response(prompt: str, images: list):
|
|
|
|
| 112 |
}
|
| 113 |
|
| 114 |
try:
|
| 115 |
+
response = requests.post(f"{GEMINI_API_URL}?key={GOOGLE_API_KEY}", json=payload, timeout=60)
|
| 116 |
response.raise_for_status()
|
| 117 |
response_data = response.json()
|
| 118 |
if 'candidates' in response_data and response_data['candidates']:
|
|
|
|
| 130 |
def get_virtual_tryon_image(user_photo, upper_body_image, lower_body_image):
|
| 131 |
"""
|
| 132 |
模擬虛擬試穿 API,返回一個試穿後的圖片 URL。
|
|
|
|
| 133 |
"""
|
| 134 |
logging.info("Simulating virtual try-on and returning a placeholder image.")
|
| 135 |
# 這裡的邏輯需要您自行實現,可以是呼叫一個公開的 API,
|
|
|
|
| 147 |
|
| 148 |
# 新增 重置 功能
|
| 149 |
if text in ["重置", "重來", "重新開始", "再一次"]:
|
| 150 |
+
user_states[user_id] = defaultdict(lambda: {"upper_body_images": [], "lower_body_images": [], "current_mode": None, "is_ready_for_outfit": False, "is_ready_for_photo": False, "user_info": {}, "personal_photo": None, "personal_photo_base64": None})[user_id]
|
| 151 |
line_bot_api.reply_message(
|
| 152 |
reply_token,
|
| 153 |
TextSendMessage(text="狀態已重置。請重新輸入個人資訊,格式為:身高,胸圍,腰圍,臀圍,場合。例如:165,85,65,90,約會")
|
|
|
|
| 231 |
try:
|
| 232 |
image_id = event.message.id
|
| 233 |
base64_img = get_base64_image(image_id)
|
| 234 |
+
|
| 235 |
+
# 先將個人照片的 Base64 儲存起來,用於 Gemini
|
| 236 |
+
user_states[user_id]["personal_photo_base64"] = base64_img
|
| 237 |
+
|
| 238 |
+
# 再將個人照片上傳到 Imgbb,並儲存 URL
|
| 239 |
photo_url = upload_to_imgbb(base64_img)
|
| 240 |
user_states[user_id]["personal_photo"] = photo_url
|
| 241 |
user_states[user_id]["is_ready_for_photo"] = True
|
|
|
|
| 256 |
"請在描述中以圖片連結的形式(例如:'https://example.com/outfit1.jpg')顯示你搭配好的衣物組合。"
|
| 257 |
)
|
| 258 |
|
| 259 |
+
all_images_base64 = (
|
| 260 |
+
[get_base64_from_url(url) for url in user_states[user_id]["upper_body_images"]] +
|
| 261 |
+
[get_base64_from_url(url) for url in user_states[user_id]["lower_body_images"]] +
|
| 262 |
+
[user_states[user_id]["personal_photo_base64"]]
|
| 263 |
+
)
|
| 264 |
|
| 265 |
+
response_text = get_gemini_response(prompt, all_images_base64)
|
| 266 |
|
| 267 |
# 從 Gemini 建議中找出最佳搭配的衣物圖片(這裡需要更複雜的邏輯,我們使用佔位符)
|
| 268 |
# 在實際應用中,您可以設計一個提示,讓 Gemini 返回最佳搭配的圖片索引
|
|
|
|
| 288 |
)
|
| 289 |
|
| 290 |
# 重置狀態以便下一次使用
|
| 291 |
+
user_states[user_id] = defaultdict(lambda: {"upper_body_images": [], "lower_body_images": [], "current_mode": None, "is_ready_for_outfit": False, "is_ready_for_photo": False, "user_info": {}, "personal_photo": None, "personal_photo_base64": None})[user_id]
|
| 292 |
return
|
| 293 |
|
| 294 |
except Exception as e:
|