File size: 5,063 Bytes
f88f928
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import os
import cv2
import torch
import glob
import requests
import numpy as np
import gradio as gr
from basicsr.archs.rrdbnet_arch import RRDBNet
from realesrgan import RealESRGANer

# ==========================================
# 1. AUTO-PATCHER (Bedah Kode Otomatis)
# ==========================================
# Mengatasi error 'torchvision' yang sering terjadi di server baru
def patch_basicsr():
    try:
        import basicsr
        pkg_path = os.path.dirname(basicsr.__file__)
        target_file = os.path.join(pkg_path, 'data', 'degradations.py')
        
        if os.path.exists(target_file):
            with open(target_file, 'r') as f: data = f.read()
            
            old_str = 'from torchvision.transforms.functional_tensor import rgb_to_grayscale'
            new_str = 'from torchvision.transforms.functional import rgb_to_grayscale'
            
            if old_str in data:
                data = data.replace(old_str, new_str)
                with open(target_file, 'w') as f: f.write(data)
                print("✅ Auto-Patch: Library basicsr berhasil diperbaiki.")
    except Exception as e:
        print(f"⚠️ Auto-Patch Warning: {e}")

patch_basicsr()

# ==========================================
# 2. PERSIAPAN MODEL
# ==========================================
# Cek ketersediaan GPU (Hugging Face Free Tier biasanya CPU, Paid dapat GPU)
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
print(f"🚀 Running on: {device}")

# Download Model Pre-trained jika belum ada
model_url = 'https://github.com/xinntao/Real-ESRGAN/releases/download/v0.1.0/RealESRGAN_x4plus.pth'
model_path = 'RealESRGAN_x4plus.pth'

if not os.path.exists(model_path):
    print("⏳ Mendownload model AI...")
    response = requests.get(model_url)
    with open(model_path, 'wb') as f:
        f.write(response.content)
    print("✅ Model siap!")

# Load Model ke Memory
def load_model():
    model = RRDBNet(num_in_ch=3, num_out_ch=3, num_feat=64, num_block=23, num_grow_ch=32, scale=4)
    netscale = 4
    
    upsampler = RealESRGANer(
        scale=netscale,
        model_path=model_path,
        dni_weight=None,
        model=model,
        tile=200,       # Tile kecil agar aman untuk CPU/RAM kecil
        tile_pad=10,
        pre_pad=0,
        half=False,     # False agar aman di CPU (fp32)
        device=device
    )
    return upsampler

# Inisialisasi Upsampler Global
upsampler = load_model()

# ==========================================
# 3. LOGIKA UTAMA (PIPELINE)
# ==========================================
def process_image(img, scale, face_enhance):
    if img is None:
        return None

    # --- MODE DOWNSCALE (MENGECILKAN) ---
    if scale < 1.0:
        h, w = img.shape[:2]
        new_w, new_h = int(w * scale), int(h * scale)
        # Gunakan INTER_AREA untuk hasil pengecilan terbaik (tajam)
        output = cv2.resize(img, (new_w, new_h), interpolation=cv2.INTER_AREA)
        return output

    # --- MODE UPSCALE (MEMBESARKAN) ---
    else:
        try:
            # Upscale menggunakan Real-ESRGAN
            # outscale=scale akan otomatis resize hasil akhir sesuai keinginan user
            output, _ = upsampler.enhance(img, outscale=scale)
            
            # Fitur Perbaikan Wajah (Optional)
            if face_enhance:
                from gfpgan import GFPGANer
                face_enhancer = GFPGANer(
                    model_path='https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.3.pth',
                    upscale=scale,
                    arch='clean',
                    channel_multiplier=2,
                    bg_upsampler=upsampler
                )
                _, _, output = face_enhancer.enhance(output, has_aligned=False, only_center_face=False, paste_back=True)
            
            return output
            
        except RuntimeError as e:
            # Tangani error jika RAM tidak cukup
            if 'out of memory' in str(e):
                return None
            raise e

# ==========================================
# 4. ANTARMUKA GRADIO
# ==========================================
title = "Smart Image Resizer & Upscaler"
description = """
**Fitur Utama:**
1. **Upscale Cerdas:** Menggunakan Real-ESRGAN untuk memperbesar gambar tanpa pecah.
2. **Downscale Tajam:** Menggunakan algoritma resampling area untuk memperkecil gambar dengan detail tinggi.
3. **Face Restore:** Memperbaiki wajah yang buram (opsional).

*Catatan: Jika berjalan di CPU (HF Free Tier), proses upscale gambar besar mungkin memakan waktu 30-60 detik.*
"""

iface = gr.Interface(
    fn=process_image,
    inputs=[
        gr.Image(label="Upload Gambar", type="numpy"),
        gr.Slider(0.1, 4.0, value=2.0, step=0.1, label="Skala Resolusi (0.5 = Kecil, 2.0 = Besar)"),
        gr.Checkbox(label="Perbaiki Wajah (Face Restoration)", value=False)
    ],
    outputs=gr.Image(label="Hasil Proses"),
    title=title,
    description=description,
    allow_flagging="never"
)

if __name__ == "__main__":
    iface.launch()