|
""" |
|
Image Enhancer App |
|
------------------ |
|
Aplikasi berbasis Gradio untuk meningkatkan kualitas gambar dengan berbagai teknik pemrosesan citra |
|
seperti perbaikan resolusi, penajaman, dan penghilangan noise. |
|
Dapat digunakan secara lokal maupun sebagai web-app AI image enhancement. |
|
|
|
Created by _drat | 2025 |
|
""" |
|
|
|
|
|
import os |
|
import subprocess |
|
import spaces |
|
import torch |
|
import cv2 |
|
import uuid |
|
import gradio as gr |
|
import numpy as np |
|
|
|
from PIL import Image |
|
|
|
from basicsr.archs.srvgg_arch import SRVGGNetCompact |
|
from gfpgan.utils import GFPGANer |
|
from realesrgan.utils import RealESRGANer |
|
|
|
import warnings |
|
warnings.filterwarnings("ignore") |
|
|
|
|
|
def runcmd(cmd, verbose = False): |
|
process = subprocess.Popen( |
|
cmd, |
|
stdout = subprocess.PIPE, |
|
stderr = subprocess.PIPE, |
|
text = True, |
|
shell = True |
|
) |
|
std_out, std_err = process.communicate() |
|
if verbose: |
|
print(std_out.strip(), std_err) |
|
pass |
|
|
|
|
|
if not os.path.exists('GFPGANv1.4.pth'): |
|
runcmd("wget https://github.com/TencentARC/GFPGAN/releases/download/v1.3.0/GFPGANv1.4.pth -P .") |
|
if not os.path.exists('realesr-general-x4v3.pth'): |
|
runcmd("wget https://github.com/xinntao/Real-ESRGAN/releases/download/v0.2.5.0/realesr-general-x4v3.pth -P .") |
|
|
|
|
|
model = SRVGGNetCompact(num_in_ch=3, num_out_ch=3, num_feat=64, num_conv=32, upscale=4, act_type='prelu') |
|
model_path = 'realesr-general-x4v3.pth' |
|
half = True if torch.cuda.is_available() else False |
|
upsampler = RealESRGANer( |
|
scale=4, model_path=model_path, model=model, |
|
tile=0, tile_pad=10, pre_pad=0, half=half |
|
) |
|
|
|
|
|
@spaces.GPU(duration=15) |
|
def enhance_image( |
|
input_image: Image, |
|
scale: int, |
|
enhance_mode: str, |
|
): |
|
only_face = enhance_mode == "Only Face Enhance" |
|
|
|
|
|
if enhance_mode == "Only Face Enhance": |
|
face_enhancer = GFPGANer( |
|
model_path='GFPGANv1.4.pth', upscale=scale, |
|
arch='clean', channel_multiplier=2 |
|
) |
|
elif enhance_mode == "Only Image Enhance": |
|
face_enhancer = None |
|
else: |
|
face_enhancer = GFPGANer( |
|
model_path='GFPGANv1.4.pth', upscale=scale, |
|
arch='clean', channel_multiplier=2, bg_upsampler=upsampler |
|
) |
|
|
|
|
|
img = cv2.cvtColor(np.array(input_image), cv2.COLOR_RGB2BGR) |
|
h, w = img.shape[0:2] |
|
|
|
|
|
if h < 300: |
|
img = cv2.resize(img, (w * 2, h * 2), interpolation=cv2.INTER_LANCZOS4) |
|
|
|
|
|
if face_enhancer is not None: |
|
|
|
_, _, output = face_enhancer.enhance( |
|
img, has_aligned=False, only_center_face=only_face, paste_back=True |
|
) |
|
else: |
|
|
|
output, _ = upsampler.enhance(img, outscale=scale) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
h, w = output.shape[0:2] |
|
max_size = 3480 |
|
if h > max_size: |
|
w = int(w * max_size / h) |
|
h = max_size |
|
if w > max_size: |
|
h = int(h * max_size / w) |
|
w = max_size |
|
|
|
|
|
output = cv2.resize(output, (w, h), interpolation=cv2.INTER_LANCZOS4) |
|
|
|
|
|
enhanced_image = Image.fromarray(cv2.cvtColor(output, cv2.COLOR_BGR2RGB)) |
|
|
|
|
|
tmpPrefix = "/tmp/gradio/" |
|
extension = 'png' |
|
|
|
targetDir = "output/" |
|
if not os.path.exists(targetDir): |
|
os.makedirs(targetDir) |
|
|
|
enhanced_path = f"{targetDir}{uuid.uuid4()}.{extension}" |
|
enhanced_image.save(enhanced_path, quality=100) |
|
|
|
return enhanced_image, enhanced_path |
|
|
|
|
|
|
|
|
|
|
|
|
|
def create_demo() -> gr.Blocks: |
|
with gr.Blocks() as demo: |
|
|
|
gr.HTML( |
|
""" |
|
<div style='display:flex; justify-content:center;'> |
|
<img src='https://i.ibb.co/jkkT7MZQ/feature-image-enhancer.jpg' |
|
alt='Feature Image' |
|
style='height:200px; width:auto; border-radius:24px; box-shadow:0 4px 18px #ffa07430; border:2.5px solid #ffe0b3;' |
|
id='feature-image'/> |
|
</div> |
|
""" |
|
) |
|
|
|
gr.Markdown(""" |
|
<div style="text-align:center; margin-top: -10px; margin-bottom: 14px;"> |
|
<span style="font-size:2.1rem; font-family:'Quicksand',sans-serif; font-weight:800; background: linear-gradient(90deg,#d84040,#ff914d 60%); -webkit-background-clip: text; color:transparent; display:inline-block;"> |
|
<span style="vertical-align:middle;">๐ธ</span> Image Enhancer <b>Pro</b> <span style="font-size:1.1em;vertical-align:middle;">โจ</span> |
|
</span><br> |
|
<span style="font-size:1.12rem; color:#d84040; font-family:'Inter',sans-serif;"> |
|
<span style="vertical-align:middle;">๐ค</span> Foto blur? Jadikan jernih & tajam pakai AI! |
|
</span> |
|
</div> |
|
""") |
|
|
|
|
|
with gr.Row(): |
|
with gr.Column(scale=1): |
|
with gr.Group(elem_id="input-card"): |
|
gr.Markdown("<div class='card-title'><span style='font-size:1.3em;vertical-align:middle;'>๐ผ๏ธ</span> <b>Gambar Asli</b></div>") |
|
input_image = gr.Image(label="", type="pil", elem_id="input-image", show_label=False) |
|
gr.Markdown("<div class='hint'><span style='font-size:1.1em;'>โฌ๏ธ</span> Upload foto format <b>JPG/PNG</b>, max 5MB</div>") |
|
with gr.Column(scale=1): |
|
with gr.Group(elem_id="output-card"): |
|
gr.Markdown("<div class='card-title'><span style='font-size:1.3em;vertical-align:middle;'>๐</span> <b>Hasil AI Enhance</b></div>") |
|
output_image = gr.Image(label="", type="pil", interactive=False, elem_id="output-image", show_label=False) |
|
enhance_image_path = gr.File(label="โฌ๏ธ Download (.png)", interactive=False, elem_id="download-btn") |
|
gr.Markdown(""" |
|
<div class='hint' style="color:#ff914d;"><span style='font-size:1.2em;'>๐ก</span> Klik untuk download hasilnya!</div> |
|
""") |
|
|
|
|
|
with gr.Group(elem_id="control-card"): |
|
with gr.Row(): |
|
scale = gr.Slider( |
|
minimum=1, |
|
maximum=4, |
|
value=2, |
|
step=1, |
|
label="๐ Upscale x", |
|
elem_id="scale-slider" |
|
) |
|
enhance_mode = gr.Dropdown( |
|
label="๐ ๏ธ Mode Enhance", |
|
choices=[ |
|
"Only Face Enhance", |
|
"Only Image Enhance", |
|
"Face Enhance + Image Enhance", |
|
], |
|
value="Face Enhance + Image Enhance", |
|
elem_id="mode-dropdown" |
|
) |
|
g_btn = gr.Button("๐ Enhance Sekarang!", elem_id="enhance-btn", size="lg") |
|
|
|
g_btn.click( |
|
fn=enhance_image, |
|
inputs=[input_image, scale, enhance_mode], |
|
outputs=[output_image, enhance_image_path], |
|
) |
|
|
|
|
|
gr.HTML(""" |
|
<footer id="footer"> |
|
Transfer Energi Semesta Digital ยฉ 2024 | ๐ฎ๐ฉ Untuk Indonesia Jaya! |
|
</footer> |
|
""") |
|
|
|
return demo |
|
|
|
|
|
|
|
|
|
|