Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| from groq import Groq | |
| from twilio.rest import Client | |
| import base64 | |
| import io | |
| from PIL import Image | |
| # Groq API 設定 | |
| GROQ_API_KEY = "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" | |
| # Twilio 設定 | |
| TWILIO_ACCOUNT_SID = "ACd7f840e0ea441d49885b4ab7a8828c46" | |
| TWILIO_AUTH_TOKEN = "b3f7af530024eb7bf68e3576f5fe3ad7" | |
| TWILIO_FROM_NUMBER = "+17623355728" | |
| def encode_image(image): | |
| """將 PIL Image 轉換為 base64 編碼""" | |
| buffered = io.BytesIO() | |
| image.save(buffered, format="JPEG") | |
| return base64.b64encode(buffered.getvalue()).decode("utf-8") | |
| def analyze_image(image): | |
| """使用 Groq API 分析圖片""" | |
| try: | |
| # 初始化 Groq 客戶端 | |
| client = Groq(api_key=GROQ_API_KEY) | |
| # 編碼圖片 | |
| base64_image = encode_image(image) | |
| image_content = { | |
| "type": "image_url", | |
| "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"} | |
| } | |
| # 發送請求到 Groq | |
| completion = client.chat.completions.create( | |
| model="meta-llama/llama-4-scout-17b-16e-instruct", | |
| messages=[{ | |
| "role": "user", | |
| "content": [ | |
| { | |
| "type": "text", | |
| "text": "解釋圖片的內容,10個字說明,使用繁體中文。" | |
| }, | |
| image_content | |
| ] | |
| }], | |
| temperature=1, | |
| max_completion_tokens=512, | |
| top_p=1, | |
| stream=False, | |
| stop=None, | |
| ) | |
| return completion.choices[0].message.content | |
| except Exception as e: | |
| return f"圖片分析失敗:{str(e)}" | |
| def send_sms(phone_number, message_body): | |
| """使用 Twilio 發送 SMS""" | |
| try: | |
| # 初始化 Twilio 客戶端 | |
| client = Client(TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN) | |
| # 發送訊息 | |
| message = client.messages.create( | |
| from_=TWILIO_FROM_NUMBER, | |
| to=phone_number, | |
| body=message_body | |
| ) | |
| return f"訊息發送成功!訊息 ID: {message.sid}" | |
| except Exception as e: | |
| return f"訊息發送失敗:{str(e)}" | |
| def process_image_and_sms(image, phone_number, custom_message): | |
| """主要處理函數:分析圖片並發送 SMS""" | |
| if image is None: | |
| return "請上傳圖片", "" | |
| if not phone_number: | |
| return "請輸入手機號碼", "" | |
| # 分析圖片 | |
| analysis_result = analyze_image(image) | |
| # 準備要發送的訊息 | |
| if custom_message: | |
| # 如果有自訂訊息,使用自訂訊息 | |
| sms_body = custom_message | |
| else: | |
| # 如果沒有自訂訊息,使用圖片分析結果 | |
| sms_body = f"圖片分析結果:{analysis_result}" | |
| # 發送 SMS | |
| sms_result = send_sms(phone_number, sms_body) | |
| return analysis_result, sms_result | |
| # 創建 Gradio 介面 | |
| with gr.Blocks(title="圖片分析與SMS發送應用") as demo: | |
| gr.Markdown("# 圖片分析與SMS發送應用") | |
| gr.Markdown("上傳圖片進行AI分析,並可選擇發送結果或自訂訊息到指定手機號碼") | |
| with gr.Row(): | |
| with gr.Column(): | |
| # 輸入區域 | |
| image_input = gr.Image( | |
| type="pil", | |
| label="上傳圖片" | |
| ) | |
| phone_input = gr.Textbox( | |
| label="手機號碼", | |
| placeholder="例如:+886919017732", | |
| info="請輸入完整的國際格式手機號碼" | |
| ) | |
| message_input = gr.Textbox( | |
| label="自訂訊息(選填)", | |
| placeholder="如果留空,將發送圖片分析結果", | |
| lines=3 | |
| ) | |
| # 按鈕 | |
| analyze_btn = gr.Button("分析圖片", variant="secondary") | |
| send_btn = gr.Button("分析並發送SMS", variant="primary") | |
| with gr.Column(): | |
| # 輸出區域 | |
| analysis_output = gr.Textbox( | |
| label="圖片分析結果", | |
| lines=4, | |
| interactive=False | |
| ) | |
| sms_output = gr.Textbox( | |
| label="SMS發送狀態", | |
| lines=2, | |
| interactive=False | |
| ) | |
| # 只分析圖片(不發送SMS) | |
| analyze_btn.click( | |
| fn=lambda img: analyze_image(img) if img else "請上傳圖片", | |
| inputs=[image_input], | |
| outputs=[analysis_output] | |
| ) | |
| # 分析圖片並發送SMS | |
| send_btn.click( | |
| fn=process_image_and_sms, | |
| inputs=[image_input, phone_input, message_input], | |
| outputs=[analysis_output, sms_output] | |
| ) | |
| # 使用範例 | |
| gr.Markdown(""" | |
| ## 使用說明: | |
| 1. **上傳圖片**:點擊圖片區域上傳要分析的圖片 | |
| 2. **輸入手機號碼**:輸入接收SMS的手機號碼(國際格式,如 +886919017732) | |
| 3. **選擇操作**: | |
| - 點擊「分析圖片」只進行圖片分析 | |
| - 點擊「分析並發送SMS」會分析圖片並發送結果到指定手機 | |
| 4. **自訂訊息**:如果想發送自訂內容而非圖片分析結果,可在自訂訊息欄位輸入 | |
| ## 注意事項: | |
| - 請確保手機號碼格式正確(包含國碼) | |
| - 圖片分析使用 Groq 的 Llama 模型 | |
| - SMS 發送使用 Twilio 服務 | |
| """) | |
| # 啟動應用 | |
| if __name__ == "__main__": | |
| demo.launch( | |
| share=True, # 設為 True 可獲得公開連結 | |
| server_name="0.0.0.0", # 允許外部連接 | |
| server_port=7860 # 指定端口 | |
| ) |