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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +65 -62
app.py CHANGED
@@ -2,111 +2,114 @@ 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()
 
2
  import torch
3
  import cv2
4
  import numpy as np
 
5
  import base64
6
+ from PIL import Image
7
  import io
8
  from realesrgan import RealESRGANer
9
  from basicsr.archs.rrdbnet_arch import RRDBNet
10
 
11
  # === KONFIGURASI MODEL ===
 
 
12
  MODEL_NAME = 'RealESRGAN_x4plus'
13
  MODEL_PATH = 'https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth'
14
 
15
  device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
16
+ print(f"Device: {device}")
17
 
18
+ # Inisialisasi Model
19
  model = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=4)
 
 
20
  upsampler = RealESRGANer(
21
  scale=4,
22
  model_path=MODEL_PATH,
23
  model=model,
24
+ tile=400, # Wajib pakai tile (misal 400) agar tidak OOM (Out Of Memory) di CPU/GPU kecil
25
  tile_pad=10,
26
  pre_pad=0,
27
+ half=True if torch.cuda.is_available() else False,
28
  device=device
29
  )
30
 
31
+ def decode_base64_to_image(base64_string):
32
+ """Decode base64 string to OpenCV Image (numpy array)"""
33
+ try:
34
+ # Bersihkan string dari prefix data URI jika ada
35
+ if "base64," in base64_string:
36
+ base64_string = base64_string.split("base64,")[1]
37
+
38
+ img_data = base64.b64decode(base64_string)
39
+ nparr = np.frombuffer(img_data, np.uint8)
40
+ img_cv2 = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
41
+
42
+ if img_cv2 is None:
43
+ raise ValueError("CV2 failed to decode image. Data might be corrupted.")
44
+
45
+ return img_cv2
46
+ except Exception as e:
47
+ print(f"Error decoding base64: {e}")
48
+ return None
49
 
50
+ def encode_image_to_base64(img_cv2):
51
+ """Encode OpenCV Image to base64 string"""
52
+ try:
53
+ # Gunakan ekstensi .jpg atau .png, .jpg biasanya lebih ringan untuk dikirim balik
54
+ success, buffer = cv2.imencode(".png", img_cv2)
55
+ if not success:
56
+ raise ValueError("CV2 failed to encode image.")
57
+
58
+ b64_str = base64.b64encode(buffer).decode("utf-8")
59
+ return f"data:image/png;base64,{b64_str}"
60
+ except Exception as e:
61
+ print(f"Error encoding image: {e}")
62
+ return None
63
+
64
+ def process_upscale(base64_input, target_res):
65
+ print(f"Menerima request upscale untuk resolusi: {target_res}")
66
+
67
+ img = decode_base64_to_image(base64_input)
68
+ if img is None:
69
+ return "ERROR: Gagal membaca input gambar."
70
 
 
 
 
 
 
71
  try:
72
+ # Upscale x4
 
 
 
 
73
  output_img, _ = upsampler.enhance(img, outscale=4)
74
 
 
 
75
  h, w = output_img.shape[:2]
 
76
  target_w, target_h = w, h
77
+
78
+ # Resize sesuai target
79
  if target_res.lower() == '2k':
 
80
  max_size = 2560
81
  if max(w, h) > max_size:
82
+ scale = max_size / max(w, h)
83
+ target_w, target_h = int(w * scale), int(h * scale)
 
84
  output_img = cv2.resize(output_img, (target_w, target_h), interpolation=cv2.INTER_AREA)
85
  elif target_res.lower() == '4k':
 
86
  max_size = 3840
87
  if max(w, h) > max_size:
88
+ scale = max_size / max(w, h)
89
+ target_w, target_h = int(w * scale), int(h * scale)
 
90
  output_img = cv2.resize(output_img, (target_w, target_h), interpolation=cv2.INTER_AREA)
91
 
92
+ print(f"Upscale berhasil. Resolusi output: {target_w}x{target_h}")
93
+ result_b64 = encode_image_to_base64(output_img)
 
 
 
94
 
95
+ if result_b64 is None:
96
+ return "ERROR: Gagal meng-encode gambar hasil."
97
+
98
+ return result_b64
99
+
100
  except Exception as e:
101
+ import traceback
102
+ traceback.print_exc()
103
+ return f"ERROR: Proses upscale gagal. {str(e)}"
104
 
105
+ # === GRADIO INTERFACE ===
 
106
  with gr.Blocks() as demo:
107
+ input_text = gr.Textbox(label="Base64 Input")
108
+ res_text = gr.Textbox(label="Resolution", value="2k")
109
+ output_text = gr.Textbox(label="Base64 Output")
 
 
110
 
111
  btn = gr.Button("Upscale")
112
+ btn.click(fn=process_upscale, inputs=[input_text, res_text], outputs=output_text, api_name="predict")
113
 
 
114
  if __name__ == "__main__":
115
  demo.queue().launch()