ffxbot commited on
Commit
f7f7335
·
verified ·
1 Parent(s): 0a905b7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -287
app.py CHANGED
@@ -2,304 +2,68 @@ import gradio as gr
2
  import numpy as np
3
  import cv2
4
  import os
5
- import time
6
  import requests
7
  import sys
8
  from PIL import Image
9
- # ─── FIX FOR BASICSR & TORCHVISION ────────────────────────────────────────────
 
10
  import torchvision.transforms.functional
11
  sys.modules['torchvision.transforms.functional_tensor'] = torchvision.transforms.functional
12
- # ──────────────────────────────────────────────────────────────────────────────
13
- # ─── Model Download ───────────────────────────────────────────────────────────
14
- MODEL_DIR = "weights"
15
- MODEL_PATH = os.path.join(MODEL_DIR, "RealESRGAN_x4plus.pth")
16
- MODEL_URL = "https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth"
17
- def download_model():
18
- os.makedirs(MODEL_DIR, exist_ok=True)
19
- if not os.path.exists(MODEL_PATH):
20
- print("📥 মডেল ডাউনলোড হচ্ছে...")
21
- r = requests.get(MODEL_URL, stream=True)
22
- with open(MODEL_PATH, "wb") as f:
23
- for chunk in r.iter_content(chunk_size=8192):
24
- f.write(chunk)
25
- print("✅ মডেল ডাউনলোড সম্পন্ন!")
26
- download_model()
27
- # ─── Real-ESRGAN Setup ────────────────────────────────────────────────────────
28
  from basicsr.archs.rrdbnet_arch import RRDBNet
29
  from realesrgan import RealESRGANer
30
- def load_upsampler():
31
- model = RRDBNet(
32
- num_in_ch=3, num_out_ch=3,
33
- num_feat=64, num_block=23, num_grow_ch=32, scale=4
34
- )
35
- upsampler = RealESRGANer(
36
- scale=4,
37
- model_path=MODEL_PATH,
38
- model=model,
39
- tile=128,
40
- tile_pad=10,
41
- pre_pad=0,
42
- half=False
43
- )
44
- return upsampler
45
- print("🔄 মডেল লোড হচ্ছে...")
46
- upsampler = load_upsampler()
47
- print("✅ মডেল রেডি!")
48
- # ─── Image Analysis ───────────────────────────────────────────────────────────
49
- def analyze_image(img: Image.Image) -> dict:
50
- w, h = img.size
51
- mp = (w * h) / 1_000_000
52
- if w >= 3840 or h >= 2160:
53
- quality_label = "4K বা তার বেশি (Ultra HD)"
54
- quality_icon = "🟣"
55
- elif w >= 1920 or h >= 1080:
56
- quality_label = "1080p Full HD"
57
- quality_icon = "🟢"
58
- elif w >= 1280 or h >= 720:
59
- quality_label = "720p HD"
60
- quality_icon = "🟡"
61
- elif w >= 854 or h >= 480:
62
- quality_label = "480p SD"
63
- quality_icon = "🟠"
64
- else:
65
- quality_label = "লো রেজোলিউশন"
66
- quality_icon = "🔴"
67
- mode_label = {"RGB": "রঙিন (RGB)", "RGBA": "রঙিন + Transparency", "L": "কালো-সাদা"}.get(img.mode, img.mode)
68
- return {
69
- "width": w, "height": h,
70
- "megapixels": round(mp, 2),
71
- "quality_label": quality_label,
72
- "quality_icon": quality_icon,
73
- "mode": mode_label,
74
- "target_w": 3840, "target_h": 2160
75
- }
76
- # ─── Main Processing ──────────────────────────────────────────────────────────
77
- def upscale_to_4k(pil_img):
78
- if pil_img is None:
79
- yield None, "❌ কোনো ছবি আপলোড করা হয়নি।", None, ""
80
- return
81
- t_start = time.time()
82
- yield None, "🔍 **ছবি বিশ্লেষণ হচ্ছে...**", None, "⏳ প্রসেসিং শুরু হয়েছে"
83
- time.sleep(0.3)
84
- pil_img = pil_img.convert("RGB")
85
- info = analyze_image(pil_img)
86
- analysis_text = f"""
87
- ## 📊 ছবি বিশ্লেষণ ফলাফল
88
 
89
- | তথ���য | মান |
90
- | :--- | :--- |
91
- | {info['quality_icon']} বর্তমান কোয়ালিটি | **{info['quality_label']}** |
92
- | 📐 বর্তমান রেজোলিউশন | **{info['width']} × {info['height']} px** |
93
- | 📷 মেগাপিক্সেল | **{info['megapixels']} MP** |
94
- | 🎯 টার্গেট রেজোলিউশন | **3840 × 2160 (4K)** |
95
 
96
- ---
97
- **AI Upscaling শুরু হচ্ছে (১-২ মিনিট সময় দিন)...**
98
- """
99
- yield None, analysis_text, None, "🔄 AI প্রসেসিং চলছে..."
100
- img_np = np.array(pil_img)
 
 
101
  img_bgr = cv2.cvtColor(img_np, cv2.COLOR_RGB2BGR)
102
- try:
103
- output_bgr, _ = upsampler.enhance(img_bgr, outscale=4)
104
- except Exception as e:
105
- yield None, f"❌ **এরর:** সার্ভার ওভারলোড হয়েছে, আবার চেষ্টা করুন।", None, "❌ ব্যর্থ হয়েছে"
106
- return
107
  output_rgb = cv2.cvtColor(output_bgr, cv2.COLOR_BGR2RGB)
108
- output_pil = Image.fromarray(output_rgb)
109
- out_w, out_h = output_pil.size
110
- if out_w != 3840 or out_h != 2160:
111
- output_pil = output_pil.resize((3840, 2160), Image.LANCZOS)
112
- t_end = time.time()
113
- elapsed = t_end - t_start
114
- mins = int(elapsed // 60)
115
- secs = int(elapsed % 60)
116
- time_str = f"{mins} মিনিট {secs} সেকেন্ড" if mins > 0 else f"{secs} সেকেন্ড"
117
- out_path = "/tmp/4k_output.png"
118
- output_pil.save(out_path, "PNG", optimize=False)
119
- file_size_mb = os.path.getsize(out_path) / (1024 * 1024)
120
- result_text = f"""
121
- ## ✅ 4K Upscaling সম্পন্ন!
122
 
123
- | ফলাফল | মান |
124
- | :--- | :--- |
125
- | 🎯 আউটপুট রেজোলিউশন | **3840 × 2160 (4K Ultra HD)** |
126
- | 📁 ফাই ইজ | **{file_size_mb:.1f} MB** |
127
- | ⏱️ সময় লেগেছে | **{time_str}** |
128
- | ✨ আপস্কেল রেশিও | **অটোম্যাটিক 4K এনালাইসিস** |
129
- | 🧠 মডেল | **Real-ESRGAN x4plus** |
130
-
131
- ---
132
- 💾 নিচের ছবিতে রাইট ক্লিক করে **"Save Image"** দিয়ে ডাউনলোড করুন অথবা ডাউনলোড বাটনে চাপুন।
133
- """
134
- time_display = f"✅ {time_str} এ সম্পন্ন | 3840×2160 (4K)"
135
- yield output_pil, result_text, out_path, time_display
136
- # ─── Custom CSS ───────────────────────────────────────────────────────────────
137
- CSS = """
138
- @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;600;700&display=swap');
139
- * { font-family: 'Inter', sans-serif; box-sizing: border-box; }
140
- body, .gradio-container {
141
- background: #0a0a0f !important;
142
- color: #e8e8f0 !important;
143
- }
144
- .gradio-container {
145
- max-width: 1100px !important;
146
- margin: 0 auto !important;
147
- padding: 20px !important;
148
- }
149
- #header {
150
- text-align: center;
151
- padding: 40px 20px 30px;
152
- background: linear-gradient(135deg, #1a1a2e 0%, #16213e 50%, #0f3460 100%);
153
- border-radius: 20px;
154
- margin-bottom: 24px;
155
- border: 1px solid #2a2a4a;
156
- }
157
- #header h1 {
158
- font-size: 2.8rem;
159
- font-weight: 700;
160
- background: linear-gradient(90deg, #00d4ff, #7b2ff7, #ff6b6b);
161
- -webkit-background-clip: text;
162
- -webkit-text-fill-color: transparent;
163
- margin: 0 0 10px;
164
- }
165
- #header p {
166
- color: #8888aa;
167
- font-size: 1.05rem;
168
- margin: 0;
169
- }
170
- .badge-row {
171
- display: flex;
172
- justify-content: center;
173
- gap: 12px;
174
- flex-wrap: wrap;
175
- margin-top: 16px;
176
- }
177
- .badge {
178
- background: rgba(0,212,255,0.1);
179
- border: 1px solid rgba(0,212,255,0.3);
180
- color: #00d4ff;
181
- padding: 5px 14px;
182
- border-radius: 20px;
183
- font-size: 0.82rem;
184
- font-weight: 600;
185
- }
186
- #timer-box {
187
- background: linear-gradient(135deg, #1a1a2e, #0f1923);
188
- border: 1px solid #2a3a5a;
189
- border-radius: 14px;
190
- padding: 16px 24px;
191
- text-align: center;
192
- font-size: 1.1rem;
193
- font-weight: 600;
194
- color: #00d4ff;
195
- margin-bottom: 16px;
196
- min-height: 54px;
197
- display: flex;
198
- align-items: center;
199
- justify-content: center;
200
- }
201
- .upload-zone label {
202
- font-size: 1rem !important;
203
- font-weight: 600 !important;
204
- color: #aaaacc !important;
205
- }
206
- #upscale-btn {
207
- background: linear-gradient(135deg, #7b2ff7, #00d4ff) !important;
208
- border: none !important;
209
- color: white !important;
210
- font-size: 1.1rem !important;
211
- font-weight: 700 !important;
212
- padding: 14px 32px !important;
213
- border-radius: 12px !important;
214
- cursor: pointer !important;
215
- transition: all 0.3s !important;
216
- width: 100% !important;
217
- letter-spacing: 0.5px !important;
218
- }
219
- #upscale-btn:hover {
220
- transform: translateY(-2px) !important;
221
- box-shadow: 0 8px 30px rgba(123,47,247,0.5) !important;
222
- }
223
- .panel {
224
- background: #111122 !important;
225
- border: 1px solid #2a2a4a !important;
226
- border-radius: 16px !important;
227
- padding: 20px !important;
228
- }
229
- .result-markdown {
230
- background: #0d0d1f !important;
231
- border-radius: 12px;
232
- padding: 16px;
233
- }
234
- footer { display: none !important; }
235
- """
236
- # ─── UI Layout ────────────────────────────────────────────────────────────────
237
- with gr.Blocks(css=CSS, title="4K AI Upscaler") as demo:
238
- gr.HTML("""
239
- <div id="header">
240
- <h1>🚀 4K AI Upscaler</h1>
241
- <p>যেকোনো ছবি আপলোড করুন — AI স্বয়ংক্রিয়ভাবে বিশ্লেষণ করে ৪K Ultra HD তে রূপান্তর করবে</p>
242
- <div class="badge-row">
243
- <span class="badge">⚡ Real-ESRGAN</span>
244
- <span class="badge">🎯 3840×2160 Output</span>
245
- <span class="badge">🧠 AI Powered</span>
246
- <span class="badge">🆓 সম্পূর্ণ বিনামূল্যে</span>
247
- </div>
248
- </div>
249
- """)
250
- timer_display = gr.HTML(
251
- '<div id="timer-box">⏳ ছবি আপলোড করুন এবং বাটন চাপুন</div>',
252
- elem_id="timer-container"
253
- )
254
- with gr.Row():
255
- with gr.Column(scale=1, elem_classes="panel"):
256
- input_img = gr.Image(
257
- label="📤 ছবি আপলোড করুন",
258
- type="pil",
259
- sources=["upload", "clipboard"],
260
- height=320,
261
- elem_classes="upload-zone"
262
- )
263
- upscale_btn = gr.Button(
264
- "✨ 4K তে রূপান্তর করুন",
265
- elem_id="upscale-btn",
266
- variant="primary"
267
- )
268
- with gr.Column(scale=1, elem_classes="panel"):
269
- output_img = gr.Image(
270
- label="📥 4K আউটপুট",
271
- type="pil",
272
- height=320,
273
- interactive=False
274
- )
275
  with gr.Row():
276
- with gr.Column():
277
- result_md = gr.Markdown(
278
- value="*এখানে বিশ্লেষণ ও ফলাফল দেখাবে...*",
279
- elem_classes="result-markdown"
280
- )
281
- with gr.Column():
282
- download_file = gr.File(
283
- label="💾 4K ফাইল ডাউনলোড করুন",
284
- interactive=False
285
- )
286
- gr.HTML("""
287
- <div style="text-align:center; padding: 20px; color: #555577; font-size:0.85rem;">
288
- Powered by Real-ESRGAN • Hosted on Hugging Face Spaces 🤗
289
- </div>
290
- """)
291
- def run(img_pil):
292
- last = None, "", None, ""
293
- gen = upscale_to_4k(img_pil)
294
- for out_img, md, path, timer in gen:
295
- last = (out_img, md, path, timer)
296
- timer_html = f'<div id="timer-box">{timer}</div>'
297
- yield out_img, md, path, timer_html
298
- return
299
- upscale_btn.click(
300
- fn=run,
301
- inputs=[input_img],
302
- outputs=[output_img, result_md, download_file, timer_display]
303
- )
304
  if __name__ == "__main__":
305
- demo.queue().launch()
 
2
  import numpy as np
3
  import cv2
4
  import os
 
5
  import requests
6
  import sys
7
  from PIL import Image
8
+
9
+ # ─── বাগ ফিক্স ────────────────────────────────────────────────────────────────
10
  import torchvision.transforms.functional
11
  sys.modules['torchvision.transforms.functional_tensor'] = torchvision.transforms.functional
12
+
13
+ # ─── মডেল সেটআপ ──────────────────────────────────────────────────────────────
14
+ MODEL_PATH = "RealESRGAN_x4plus.pth"
15
+
16
+ if not os.path.exists(MODEL_PATH):
17
+ r = requests.get("https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth", stream=True)
18
+ with open(MODEL_PATH, "wb") as f:
19
+ for chunk in r.iter_content(chunk_size=8192):
20
+ f.write(chunk)
21
+
 
 
 
 
 
 
22
  from basicsr.archs.rrdbnet_arch import RRDBNet
23
  from realesrgan import RealESRGANer
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
 
25
+ model = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=4)
26
+ upsampler = RealESRGANer(scale=4, model_path=MODEL_PATH, model=model, tile=128, tile_pad=10, pre_pad=0, half=False)
 
 
 
 
27
 
28
+ # ─── মূল কাজ (কোনো ফ্যান্সি ডিজাইন ছাড়া) ──────────────────────────────────────
29
+ def process_image(img):
30
+ if img is None:
31
+ return None, None
32
+
33
+ # RGB থেকে BGR
34
+ img_np = np.array(img.convert("RGB"))
35
  img_bgr = cv2.cvtColor(img_np, cv2.COLOR_RGB2BGR)
36
+
37
+ # 4K আপস্কেল
38
+ output_bgr, _ = upsampler.enhance(img_bgr, outscale=4)
39
+
40
+ # BGR থেকে RGB
41
  output_rgb = cv2.cvtColor(output_bgr, cv2.COLOR_BGR2RGB)
42
+ out_img = Image.fromarray(output_rgb)
43
+
44
+ # 4K সাইজ নিশ্চিত করা
45
+ if out_img.size != (3840, 2160):
46
+ out_img = out_img.resize((3840, 2160), Image.LANCZOS)
47
+
48
+ # সেভ করা
49
+ out_path = "/tmp/output.png"
50
+ out_img.save(out_path, "PNG")
51
+
52
+ return out_img, out_path
 
 
 
53
 
54
+ # ─── সি্পল ইউজর ই্টারফেস ──────────────────────────────────────────────────
55
+ with gr.Blocks() as demo:
56
+ gr.Markdown("# 🚀 4K AI Upscaler (Basic Version)")
57
+ gr.Markdown("সব ডিজাই দেওয়া হয়েছে। শুধু ছবি আপলোড করুন এবং রেজাল্ট নিন।")
58
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  with gr.Row():
60
+ inp = gr.Image(type="pil", label="ছবি আপলোড করুন")
61
+ out = gr.Image(type="pil", label="4K আউটপুট")
62
+
63
+ btn = gr.Button("✨ 4K তে রূপান্তর করুন", variant="primary")
64
+ file_out = gr.File(label="4K ছবি ডাউনলোড করুন")
65
+
66
+ btn.click(fn=process_image, inputs=inp, outputs=[out, file_out])
67
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  if __name__ == "__main__":
69
+ demo.launch()