urnotwen commited on
Commit
5ff4dd4
·
verified ·
1 Parent(s): ca520cb

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -0
app.py ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ from transformers import AutoModelForImageSegmentation
4
+ import torch
5
+ from torchvision import transforms
6
+ from PIL import Image
7
+ import timm
8
+
9
+ # --- 1. 初始化模型 ---
10
+ model_id = "briaai/RMBG-2.0"
11
+ print(f"正在載入模型: {model_id} ...")
12
+
13
+ hf_token = os.getenv("HF_TOKEN")
14
+ if not hf_token:
15
+ print("⚠️ 警告: 未偵測到 HF_TOKEN")
16
+
17
+ try:
18
+ model = AutoModelForImageSegmentation.from_pretrained(
19
+ model_id, trust_remote_code=True, token=hf_token
20
+ )
21
+ device = torch.device("cpu")
22
+ model.to(device)
23
+ model.eval()
24
+ print("✅ 模型載入成功!")
25
+ except Exception as e:
26
+ print(f"❌ 模型載入失敗: {e}")
27
+
28
+ # --- 2. 圖像處理 ---
29
+ def process_image(input_image):
30
+ if input_image is None:
31
+ return None
32
+
33
+ image_size = (1024, 1024)
34
+ transform_image = transforms.Compose([
35
+ transforms.Resize(image_size),
36
+ transforms.ToTensor(),
37
+ transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
38
+ ])
39
+
40
+ input_images = transform_image(input_image).unsqueeze(0).to(device)
41
+
42
+ with torch.no_grad():
43
+ preds = model(input_images)[-1].sigmoid().cpu()
44
+
45
+ pred = preds[0].squeeze()
46
+ pred_pil = transforms.ToPILImage()(pred)
47
+ mask = pred_pil.resize(input_image.size)
48
+ image = input_image.convert("RGBA")
49
+ image.putalpha(mask)
50
+ return image
51
+
52
+ # --- 3. 手動 CSS 美化 (這是重點!) ---
53
+ # 我們不依賴 theme 參數,直接用 CSS 寫樣式
54
+ custom_css = """
55
+ /* 全域字體與背景 */
56
+ .gradio-container {
57
+ font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif !important;
58
+ background-color: #f7f9fc !important; /* 淡淡的藍灰色背景 */
59
+ }
60
+
61
+ /* 隱藏預設的頁腳 */
62
+ footer {display: none !important;}
63
+
64
+ /* 按鈕美化 */
65
+ button.primary {
66
+ background: linear-gradient(90deg, #6366f1 0%, #a855f7 100%) !important; /* 紫色漸層 */
67
+ border: none !important;
68
+ color: white !important;
69
+ font-weight: bold !important;
70
+ border-radius: 25px !important; /* 圓角按鈕 */
71
+ transition: transform 0.2s;
72
+ box-shadow: 0 4px 6px rgba(0,0,0,0.1);
73
+ }
74
+ button.primary:hover {
75
+ transform: scale(1.02); /* 滑鼠移過去會放大一點 */
76
+ box-shadow: 0 6px 8px rgba(0,0,0,0.15);
77
+ }
78
+
79
+ /* 圖片框美化 */
80
+ .image-container {
81
+ border-radius: 15px !important;
82
+ overflow: hidden;
83
+ border: 2px solid #e2e8f0;
84
+ background-color: white;
85
+ }
86
+
87
+ /* 標題樣式 */
88
+ h1 {
89
+ text-align: center;
90
+ color: #1e293b;
91
+ font-weight: 800 !important;
92
+ }
93
+ """
94
+
95
+ # --- 4. 建立介面 ---
96
+ with gr.Blocks(css=custom_css) as app:
97
+
98
+ # 偷渡 HTML Meta Tags (嘗試觸發 PWA)
99
+ gr.HTML("""
100
+ <div style="display: none;">
101
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
102
+ <meta name="apple-mobile-web-app-capable" content="yes">
103
+ <meta name="theme-color" content="#f7f9fc">
104
+ </div>
105
+ """)
106
+
107
+ with gr.Column():
108
+ gr.Markdown("# ✨ AI 智能去背")
109
+ gr.Markdown("上傳圖片,一鍵移除背景 (RMBG-2.0)")
110
+
111
+ with gr.Row():
112
+ # 左邊:輸入區
113
+ with gr.Column():
114
+ input_img = gr.Image(type="pil", label="📸 上傳或拍照", elem_classes="image-container")
115
+ # 這裡把 variant="primary" 加上去,讓 CSS 抓到它變成紫色按鈕
116
+ btn = gr.Button("🚀 開始去背", variant="primary", size="lg")
117
+
118
+ # 右邊:輸出區
119
+ with gr.Column():
120
+ output_img = gr.Image(type="pil", label="✨ 去背完成 (長按儲存)", elem_classes="image-container")
121
+
122
+ btn.click(fn=process_image, inputs=input_img, outputs=output_img)
123
+
124
+ if __name__ == "__main__":
125
+ app.launch()