File size: 3,488 Bytes
2bdc266
e2d1a9c
5136b76
6f4567a
5136b76
ed15a45
5136b76
 
 
 
 
 
 
 
 
 
 
 
2b757ac
5136b76
2b757ac
5136b76
 
b2059c7
5136b76
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6f4567a
 
 
ed15a45
6f4567a
 
e2d1a9c
6f4567a
 
e2d1a9c
5136b76
ed15a45
6f4567a
5136b76
6f4567a
5136b76
6f4567a
 
5136b76
 
 
6f4567a
5136b76
 
e2d1a9c
ed15a45
6f4567a
 
 
 
5136b76
6f4567a
ed15a45
6f4567a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ed15a45
6f4567a
c237f2a
da18c25
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
import gradio as gr
import numpy as np
import torch
from PIL import Image, ImageFilter
from huggingface_hub import hf_hub_download

# ========== تحميل الموديل ==========
_model = None
_device = None

def get_model():
    global _model, _device
    if _model is not None:
        return _model, _device

    _device = "cuda" if torch.cuda.is_available() else "cpu"
    print(f"[LaMa] Loading on {_device}...")

    # جديد ✅
    model_path = hf_hub_download(
        repo_id="fashn-ai/LaMa",
        filename="big-lama.pt",
    )
    

    _model = torch.jit.load(model_path, map_location=_device)
    _model.eval()
    print("[LaMa] Ready.")
    return _model, _device


def _pad(tensor, multiple=8):
    h, w = tensor.shape[-2:]
    ph = (multiple - h % multiple) % multiple
    pw = (multiple - w % multiple) % multiple
    if ph or pw:
        tensor = torch.nn.functional.pad(tensor, (0, pw, 0, ph), mode="reflect")
    return tensor, h, w


def lama_inpaint(image_np, mask_np):
    model, device = get_model()

    img  = image_np.astype(np.float32) / 255.0
    mask = (mask_np > 127).astype(np.float32)

    img_t  = torch.from_numpy(img).permute(2,0,1).unsqueeze(0).to(device)
    mask_t = torch.from_numpy(mask).unsqueeze(0).unsqueeze(0).to(device)

    masked = img_t * (1 - mask_t)

    masked_p, h, w = _pad(masked)
    mask_p,   _,  _ = _pad(mask_t)

    with torch.no_grad():
        try:
            out = model(masked_p, mask_p)
        except Exception:
            inp = torch.cat([masked_p, mask_p], dim=1)
            out = model(inp)

    out = out[:, :, :h, :w]
    result = img_t[:, :, :h, :w] * (1 - mask_t) + out * mask_t
    result = result.squeeze(0).permute(1,2,0).cpu().numpy()
    return (result * 255).clip(0, 255).astype(np.uint8)


# ========== الواجهة ==========
def process(editor_data, feather):
    if editor_data is None:
        return None

    bg     = editor_data.get("background")
    layers = editor_data.get("layers", [])

    if bg is None:
        return None

    image_np = np.array(bg.convert("RGB"))

    if not layers or layers[0] is None:
        return bg.convert("RGB")

    alpha = np.array(layers[0].convert("RGBA"))[:, :, 3]

    if feather > 0:
        alpha = np.array(
            Image.fromarray(alpha).filter(ImageFilter.GaussianBlur(radius=feather))
        )

    result = lama_inpaint(image_np, alpha)
    return Image.fromarray(result)


with gr.Blocks(title="SFX Cleaner - LaMa") as demo:
    gr.Markdown("""
    # 🧹 SFX Cleaner — big-lama
    **الطريقة:** ارفع الصورة ← ارسم بالفرشاة البيضاء على النص/SFX ← اضغط **تبييض**
    > أول تشغيل يحمل الموديل تلقائياً (~200MB)
    """)

    with gr.Row():
        with gr.Column(scale=2):
            editor = gr.ImageEditor(
                label="📌 ارسم على النص",
                brush=gr.Brush(colors=["#ffffff"], color_mode="fixed", default_size=20),
                eraser=gr.Eraser(default_size=20),
                type="pil",
                height=650,
            )
        with gr.Column(scale=1):
            output = gr.Image(label="✅ النتيجة", type="pil", height=650)

    with gr.Row():
        feather = gr.Slider(0, 8, value=2, step=1, label="نعومة الحواف")
        btn = gr.Button("🧹 تبييض", variant="primary", size="lg")

    btn.click(fn=process, inputs=[editor, feather], outputs=output)

demo.launch()