Spaces:
Running
Running
| 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) |