Isasatu commited on
Commit
fbbef9a
·
verified ·
1 Parent(s): c6f9c38

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +112 -0
app.py ADDED
@@ -0,0 +1,112 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import cv2
4
+ import numpy as np
5
+ from PIL import Image
6
+ import base64
7
+ import io
8
+ from realesrgan import RealESRGANer
9
+ from basicsr.archs.rrdbnet_arch import RRDBNet
10
+
11
+ # === KONFIGURASI MODEL ===
12
+ # Kita menggunakan RealESRGAN_x4plus (bagus untuk general image/realistis)
13
+ # Jika kamu lebih fokus ke anime, bisa ganti ke RealESRGAN_x4plus_anime_6B
14
+ MODEL_NAME = 'RealESRGAN_x4plus'
15
+ MODEL_PATH = 'https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth'
16
+
17
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
18
+ print(f"Menggunakan device: {device}")
19
+
20
+ # Inisialisasi arsitektur model
21
+ model = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=4)
22
+
23
+ # Inisialisasi RealESRGANer
24
+ upsampler = RealESRGANer(
25
+ scale=4,
26
+ model_path=MODEL_PATH,
27
+ model=model,
28
+ tile=0, # Atur > 0 jika kehabisan memori (misal: 400), 0 berarti tidak di-tile (lebih cepat tapi butuh VRAM besar)
29
+ tile_pad=10,
30
+ pre_pad=0,
31
+ half=True if torch.cuda.is_available() else False, # Gunakan presisi half jika pakai GPU agar lebih cepat
32
+ device=device
33
+ )
34
+
35
+ # === FUNGSI UTAMA ===
36
+ def decode_base64_to_cv2(base64_string):
37
+ """Mengubah base64 dari web menjadi format gambar OpenCV (numpy array)"""
38
+ # Pisahkan header "data:image/png;base64," jika ada
39
+ if "," in base64_string:
40
+ base64_string = base64_string.split(",")[1]
41
+
42
+ img_data = base64.b64decode(base64_string)
43
+ nparr = np.frombuffer(img_data, np.uint8)
44
+ img_cv2 = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
45
+ return img_cv2
46
+
47
+ def encode_cv2_to_base64(img_cv2, ext=".png"):
48
+ """Mengubah format gambar OpenCV kembali ke base64 untuk dikirim ke web"""
49
+ _, buffer = cv2.imencode(ext, img_cv2)
50
+ b64_str = base64.b64encode(buffer).decode("utf-8")
51
+ return f"data:image/png;base64,{b64_str}"
52
+
53
+ def upscale_image(base64_image, target_res):
54
+ """
55
+ Fungsi utama yang akan dipanggil oleh API.
56
+ target_res: '2k' atau '4k'
57
+ """
58
+ try:
59
+ # 1. Decode gambar
60
+ img = decode_base64_to_cv2(base64_image)
61
+
62
+ # 2. Lakukan Upscale (default model ini menaikkan 4x lipat)
63
+ print("Memulai proses upscaling...")
64
+ output_img, _ = upsampler.enhance(img, outscale=4)
65
+
66
+ # 3. Resize cerdas (Opsional)
67
+ # RealESRGAN otomatis x4. Jika hasilnya kebesaran, kita resize manual ke target yang diinginkan.
68
+ h, w = output_img.shape[:2]
69
+
70
+ target_w, target_h = w, h
71
+ if target_res.lower() == '2k':
72
+ # Asumsi 2K lebar maksimal ~2560px
73
+ max_size = 2560
74
+ if max(w, h) > max_size:
75
+ scale_ratio = max_size / max(w, h)
76
+ target_w = int(w * scale_ratio)
77
+ target_h = int(h * scale_ratio)
78
+ output_img = cv2.resize(output_img, (target_w, target_h), interpolation=cv2.INTER_AREA)
79
+ elif target_res.lower() == '4k':
80
+ # Asumsi 4K lebar maksimal ~3840px
81
+ max_size = 3840
82
+ if max(w, h) > max_size:
83
+ scale_ratio = max_size / max(w, h)
84
+ target_w = int(w * scale_ratio)
85
+ target_h = int(h * scale_ratio)
86
+ output_img = cv2.resize(output_img, (target_w, target_h), interpolation=cv2.INTER_AREA)
87
+
88
+ print(f"Upscale selesai. Resolusi akhir: {target_w}x{target_h}")
89
+
90
+ # 4. Encode kembali ke base64
91
+ result_base64 = encode_cv2_to_base64(output_img)
92
+ return result_base64
93
+
94
+ except Exception as e:
95
+ print(f"Error saat upscaling: {e}")
96
+ return str(e)
97
+
98
+ # === ANTARMUKA API GRADIO ===
99
+ # Kita definisikan interface tanpa UI web yang rumit karena kita hanya butuh API-nya
100
+ with gr.Blocks() as demo:
101
+ with gr.Row():
102
+ input_b64 = gr.Textbox(label="Input Base64 Image")
103
+ input_res = gr.Textbox(label="Target Resolution (2k/4k)", value="2k")
104
+
105
+ output_b64 = gr.Textbox(label="Output Base64 Image")
106
+
107
+ btn = gr.Button("Upscale")
108
+ btn.click(fn=upscale_image, inputs=[input_b64, input_res], outputs=output_b64, api_name="predict")
109
+
110
+ # Jalankan server
111
+ if __name__ == "__main__":
112
+ demo.queue().launch()