File size: 4,246 Bytes
67b1c08
 
936cd53
67b1c08
 
939b39a
 
6b1ddf6
 
34290a0
6b1ddf6
 
34290a0
6b1ddf6
 
 
34290a0
6b1ddf6
 
936cd53
 
 
 
34290a0
6b1ddf6
 
 
 
 
34290a0
6b1ddf6
 
34290a0
 
 
 
936cd53
6b1ddf6
 
aab5ea1
6b1ddf6
34290a0
6b1ddf6
67b1c08
34290a0
 
 
 
6b1ddf6
34290a0
 
4f5bbed
936cd53
d8f140f
b75a3f6
6b1ddf6
34290a0
 
b75a3f6
34290a0
 
 
 
 
b75a3f6
 
 
 
 
936cd53
4f5bbed
 
8b18861
6b1ddf6
67b1c08
936cd53
6b1ddf6
34290a0
 
6b1ddf6
67b1c08
 
34290a0
67b1c08
34290a0
 
67b1c08
34290a0
 
 
 
 
 
 
 
 
 
6b1ddf6
67b1c08
936cd53
67b1c08
4f5bbed
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
import gradio as gr
from gradio_client import Client, handle_file
from PIL import Image

# Connect to the verified IC-Light engine
client = Client("lllyasviel/IC-Light")

def get_smart_resolution(width, height):
    """
    Auto-detects Landscape/Portrait to prevent stretching.
    """
    aspect_ratio = width / height
    if aspect_ratio > 1.2:  # Landscape (Like your new photo)
        return 768, 512
    elif aspect_ratio < 0.8: # Portrait
        return 512, 768
    else: # Square
        return 640, 640

def dynamic_relight(image_path, prompt, lighting_choice, s1, s2, s3, s4):
    if image_path is None:
        return None

    # 1. SMART RESOLUTION
    img = Image.open(image_path)
    orig_w, orig_h = img.size
    target_w, target_h = get_smart_resolution(orig_w, orig_h)
    
    img.thumbnail((target_w, target_h)) 
    safe_path = "robust_input.png"
    img.save(safe_path)

    # 2. CALIBRATED SLIDERS (Visual Enhancement ONLY)
    # We removed "Cinematic" from the hidden logic to prevent darkness.
    # Now sliders only add QUALITY (Sharpness, Texture), not Darkness.
    keywords = ["ultra detailed", "sharp texture", "realistic skin", "perfect focus"]
    slider_vals = [s1, s2, s3, s4]
    
    user_adjustments = ""
    for i, word in enumerate(keywords):
        if slider_vals[i] > 0:
            weight = 0.5 + (slider_vals[i] / 100.0) * 0.7  # Gentle range (0.5 to 1.2)
            user_adjustments += f", ({word}:{weight:.1f})"
    
    # 3. THE "DAYLIGHT PROTECTION" GUARD
    # This acts as a firewall. It blocks the model from making the image dark.
    # It forces 'global illumination' so the background stays visible.
    lighting_guard = ", natural lighting, ambient light, global illumination, balanced exposure, detailed background, raw photo"
    
    # We combine your prompt + The Guard + The Sliders
    final_prompt = prompt + lighting_guard + user_adjustments

    try:
        result = client.predict(
            input_fg=handle_file(safe_path),   
            prompt=final_prompt,               
            image_width=target_w,              
            image_height=target_h,             
            num_samples=1,                     
            seed=12345,                        
            steps=30,                          
            a_prompt="best quality, masterpiece, 8k uhd", # Pure Quality boosters           
            n_prompt="lowres, bad anatomy, dark, moody, shadow, silhouette, black background", # ANTI-DARKNESS Negative Prompts
            cfg=1.8,                           # Slightly lower CFG prevents "hallucinating" new backgrounds
            highres_scale=1.5,                 
            highres_denoise=0.5,               
            lowres_denoise=0.9,                
            bg_source=lighting_choice,         
            api_name="/process_relight"        
        )
        return result[1][0]['image']
        
    except Exception as e:
        raise gr.Error(f"System Error: {str(e)}")

# UI Setup
with gr.Blocks(theme=gr.themes.Soft()) as demo:
    gr.Markdown("# ☀️ Robust Daylight Relighter")
    gr.Markdown("Guarantees bright, high-quality results for any input image.")
    
    with gr.Row():
        with gr.Column():
            img = gr.Image(type="filepath", label="Input Image")
            
            # DEFAULT PROMPT is now generic and safe
            txt = gr.Textbox(label="Prompt (Optional)", value="beautiful woman, detailed face")
            
            dirs = gr.Radio(["Left Light", "Right Light", "Top Light", "Bottom Light"], label="Light Direction", value="Top Light")
            
            gr.Markdown("### Enhancement (Safe Range)")
            # Renamed 'Cinematic' to 'Contrast' to be accurate
            s1 = gr.Slider(0, 100, value=20, label="Contrast Boost") 
            s2 = gr.Slider(0, 100, value=80, label="Detail Level")
            s3 = gr.Slider(0, 100, value=70, label="Texture Sharpness")
            s4 = gr.Slider(0, 100, value=60, label="Focus Depth")
            
            btn = gr.Button("Execute Robust Relight", variant="primary")
        out = gr.Image(label="Enhanced Output")

    btn.click(dynamic_relight, [img, txt, dirs, s1, s2, s3, s4], out)

demo.launch(show_error=True)