Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -7,64 +7,61 @@ client = Client("lllyasviel/IC-Light")
|
|
| 7 |
|
| 8 |
def get_smart_resolution(width, height):
|
| 9 |
"""
|
| 10 |
-
|
| 11 |
-
based on the input image's shape (Landscape vs Portrait).
|
| 12 |
-
This prevents the 'blurry/stretched' look.
|
| 13 |
"""
|
| 14 |
aspect_ratio = width / height
|
| 15 |
-
if aspect_ratio > 1.2: # Landscape
|
| 16 |
return 768, 512
|
| 17 |
elif aspect_ratio < 0.8: # Portrait
|
| 18 |
return 512, 768
|
| 19 |
-
else: # Square
|
| 20 |
return 640, 640
|
| 21 |
|
| 22 |
def dynamic_relight(image_path, prompt, lighting_choice, s1, s2, s3, s4):
|
| 23 |
if image_path is None:
|
| 24 |
return None
|
| 25 |
|
| 26 |
-
# 1. SMART
|
| 27 |
-
# Detect the shape of the uploaded image and resize correctly
|
| 28 |
img = Image.open(image_path)
|
| 29 |
orig_w, orig_h = img.size
|
| 30 |
target_w, target_h = get_smart_resolution(orig_w, orig_h)
|
| 31 |
|
| 32 |
img.thumbnail((target_w, target_h))
|
| 33 |
-
safe_path = "
|
| 34 |
img.save(safe_path)
|
| 35 |
|
| 36 |
-
# 2. CALIBRATED
|
| 37 |
-
# We
|
| 38 |
-
|
|
|
|
| 39 |
slider_vals = [s1, s2, s3, s4]
|
| 40 |
|
| 41 |
user_adjustments = ""
|
| 42 |
for i, word in enumerate(keywords):
|
| 43 |
if slider_vals[i] > 0:
|
| 44 |
-
|
| 45 |
-
weight = 0.8 + (slider_vals[i] / 100.0) * 0.8
|
| 46 |
user_adjustments += f", ({word}:{weight:.1f})"
|
| 47 |
|
| 48 |
-
# 3. THE "
|
| 49 |
-
#
|
| 50 |
-
#
|
| 51 |
-
|
| 52 |
|
| 53 |
-
#
|
| 54 |
-
final_prompt = prompt +
|
| 55 |
|
| 56 |
try:
|
| 57 |
result = client.predict(
|
| 58 |
input_fg=handle_file(safe_path),
|
| 59 |
prompt=final_prompt,
|
| 60 |
-
image_width=target_w,
|
| 61 |
-
image_height=target_h,
|
| 62 |
num_samples=1,
|
| 63 |
-
seed=12345,
|
| 64 |
-
steps=30,
|
| 65 |
-
a_prompt="best quality, masterpiece",
|
| 66 |
-
n_prompt="lowres, bad anatomy,
|
| 67 |
-
cfg=
|
| 68 |
highres_scale=1.5,
|
| 69 |
highres_denoise=0.5,
|
| 70 |
lowres_denoise=0.9,
|
|
@@ -78,22 +75,26 @@ def dynamic_relight(image_path, prompt, lighting_choice, s1, s2, s3, s4):
|
|
| 78 |
|
| 79 |
# UI Setup
|
| 80 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
| 81 |
-
gr.Markdown("#
|
| 82 |
-
gr.Markdown("
|
| 83 |
|
| 84 |
with gr.Row():
|
| 85 |
with gr.Column():
|
| 86 |
-
img = gr.Image(type="filepath", label="Input Image
|
| 87 |
-
txt = gr.Textbox(label="Base Prompt", value="beautiful woman, detailed face")
|
| 88 |
-
dirs = gr.Radio(["Left Light", "Right Light", "Top Light", "Bottom Light"], label="Light Direction", value="Right Light")
|
| 89 |
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
s2 = gr.Slider(0, 100, value=50, label="Detail Level")
|
| 93 |
-
s3 = gr.Slider(0, 100, value=50, label="Texture Sharpness")
|
| 94 |
-
s4 = gr.Slider(0, 100, value=50, label="Focus Depth")
|
| 95 |
|
| 96 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 97 |
out = gr.Image(label="Enhanced Output")
|
| 98 |
|
| 99 |
btn.click(dynamic_relight, [img, txt, dirs, s1, s2, s3, s4], out)
|
|
|
|
| 7 |
|
| 8 |
def get_smart_resolution(width, height):
|
| 9 |
"""
|
| 10 |
+
Auto-detects Landscape/Portrait to prevent stretching.
|
|
|
|
|
|
|
| 11 |
"""
|
| 12 |
aspect_ratio = width / height
|
| 13 |
+
if aspect_ratio > 1.2: # Landscape (Like your new photo)
|
| 14 |
return 768, 512
|
| 15 |
elif aspect_ratio < 0.8: # Portrait
|
| 16 |
return 512, 768
|
| 17 |
+
else: # Square
|
| 18 |
return 640, 640
|
| 19 |
|
| 20 |
def dynamic_relight(image_path, prompt, lighting_choice, s1, s2, s3, s4):
|
| 21 |
if image_path is None:
|
| 22 |
return None
|
| 23 |
|
| 24 |
+
# 1. SMART RESOLUTION
|
|
|
|
| 25 |
img = Image.open(image_path)
|
| 26 |
orig_w, orig_h = img.size
|
| 27 |
target_w, target_h = get_smart_resolution(orig_w, orig_h)
|
| 28 |
|
| 29 |
img.thumbnail((target_w, target_h))
|
| 30 |
+
safe_path = "robust_input.png"
|
| 31 |
img.save(safe_path)
|
| 32 |
|
| 33 |
+
# 2. CALIBRATED SLIDERS (Visual Enhancement ONLY)
|
| 34 |
+
# We removed "Cinematic" from the hidden logic to prevent darkness.
|
| 35 |
+
# Now sliders only add QUALITY (Sharpness, Texture), not Darkness.
|
| 36 |
+
keywords = ["ultra detailed", "sharp texture", "realistic skin", "perfect focus"]
|
| 37 |
slider_vals = [s1, s2, s3, s4]
|
| 38 |
|
| 39 |
user_adjustments = ""
|
| 40 |
for i, word in enumerate(keywords):
|
| 41 |
if slider_vals[i] > 0:
|
| 42 |
+
weight = 0.5 + (slider_vals[i] / 100.0) * 0.7 # Gentle range (0.5 to 1.2)
|
|
|
|
| 43 |
user_adjustments += f", ({word}:{weight:.1f})"
|
| 44 |
|
| 45 |
+
# 3. THE "DAYLIGHT PROTECTION" GUARD
|
| 46 |
+
# This acts as a firewall. It blocks the model from making the image dark.
|
| 47 |
+
# It forces 'global illumination' so the background stays visible.
|
| 48 |
+
lighting_guard = ", natural lighting, ambient light, global illumination, balanced exposure, detailed background, raw photo"
|
| 49 |
|
| 50 |
+
# We combine your prompt + The Guard + The Sliders
|
| 51 |
+
final_prompt = prompt + lighting_guard + user_adjustments
|
| 52 |
|
| 53 |
try:
|
| 54 |
result = client.predict(
|
| 55 |
input_fg=handle_file(safe_path),
|
| 56 |
prompt=final_prompt,
|
| 57 |
+
image_width=target_w,
|
| 58 |
+
image_height=target_h,
|
| 59 |
num_samples=1,
|
| 60 |
+
seed=12345,
|
| 61 |
+
steps=30,
|
| 62 |
+
a_prompt="best quality, masterpiece, 8k uhd", # Pure Quality boosters
|
| 63 |
+
n_prompt="lowres, bad anatomy, dark, moody, shadow, silhouette, black background", # ANTI-DARKNESS Negative Prompts
|
| 64 |
+
cfg=1.8, # Slightly lower CFG prevents "hallucinating" new backgrounds
|
| 65 |
highres_scale=1.5,
|
| 66 |
highres_denoise=0.5,
|
| 67 |
lowres_denoise=0.9,
|
|
|
|
| 75 |
|
| 76 |
# UI Setup
|
| 77 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
| 78 |
+
gr.Markdown("# ☀️ Robust Daylight Relighter")
|
| 79 |
+
gr.Markdown("Guarantees bright, high-quality results for any input image.")
|
| 80 |
|
| 81 |
with gr.Row():
|
| 82 |
with gr.Column():
|
| 83 |
+
img = gr.Image(type="filepath", label="Input Image")
|
|
|
|
|
|
|
| 84 |
|
| 85 |
+
# DEFAULT PROMPT is now generic and safe
|
| 86 |
+
txt = gr.Textbox(label="Prompt (Optional)", value="beautiful woman, detailed face")
|
|
|
|
|
|
|
|
|
|
| 87 |
|
| 88 |
+
dirs = gr.Radio(["Left Light", "Right Light", "Top Light", "Bottom Light"], label="Light Direction", value="Top Light")
|
| 89 |
+
|
| 90 |
+
gr.Markdown("### Enhancement (Safe Range)")
|
| 91 |
+
# Renamed 'Cinematic' to 'Contrast' to be accurate
|
| 92 |
+
s1 = gr.Slider(0, 100, value=20, label="Contrast Boost")
|
| 93 |
+
s2 = gr.Slider(0, 100, value=80, label="Detail Level")
|
| 94 |
+
s3 = gr.Slider(0, 100, value=70, label="Texture Sharpness")
|
| 95 |
+
s4 = gr.Slider(0, 100, value=60, label="Focus Depth")
|
| 96 |
+
|
| 97 |
+
btn = gr.Button("Execute Robust Relight", variant="primary")
|
| 98 |
out = gr.Image(label="Enhanced Output")
|
| 99 |
|
| 100 |
btn.click(dynamic_relight, [img, txt, dirs, s1, s2, s3, s4], out)
|