Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -5,37 +5,65 @@ from PIL import Image
|
|
| 5 |
# Connect to the verified IC-Light engine
|
| 6 |
client = Client("lllyasviel/IC-Light")
|
| 7 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 8 |
def dynamic_relight(image_path, prompt, lighting_choice, s1, s2, s3, s4):
|
| 9 |
if image_path is None:
|
| 10 |
return None
|
| 11 |
|
| 12 |
-
# 1.
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
slider_vals = [s1, s2, s3, s4]
|
| 15 |
-
|
|
|
|
| 16 |
for i, word in enumerate(keywords):
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
| 19 |
|
| 20 |
-
#
|
| 21 |
-
#
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
|
|
|
| 26 |
|
| 27 |
-
# 3. THE "CLASSIC" PAYLOAD
|
| 28 |
try:
|
| 29 |
result = client.predict(
|
| 30 |
input_fg=handle_file(safe_path),
|
| 31 |
-
prompt=
|
| 32 |
-
image_width=
|
| 33 |
-
image_height=
|
| 34 |
num_samples=1,
|
| 35 |
-
seed=
|
| 36 |
-
steps=
|
| 37 |
-
a_prompt="best quality",
|
| 38 |
-
n_prompt="lowres, bad anatomy",
|
| 39 |
cfg=2.0,
|
| 40 |
highres_scale=1.5,
|
| 41 |
highres_denoise=0.5,
|
|
@@ -43,29 +71,30 @@ def dynamic_relight(image_path, prompt, lighting_choice, s1, s2, s3, s4):
|
|
| 43 |
bg_source=lighting_choice,
|
| 44 |
api_name="/process_relight"
|
| 45 |
)
|
| 46 |
-
# Extract image from gallery tuple
|
| 47 |
return result[1][0]['image']
|
| 48 |
|
| 49 |
except Exception as e:
|
| 50 |
-
raise gr.Error(f"
|
| 51 |
|
| 52 |
# UI Setup
|
| 53 |
-
with gr.Blocks() as demo:
|
| 54 |
-
gr.Markdown("#
|
|
|
|
|
|
|
| 55 |
with gr.Row():
|
| 56 |
with gr.Column():
|
| 57 |
-
img = gr.Image(type="filepath", label="Input Image")
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
dirs = gr.Radio(["Left Light", "Right Light", "Top Light", "Bottom Light"], label="Light Direction", value="Left Light")
|
| 61 |
|
|
|
|
| 62 |
s1 = gr.Slider(0, 100, value=50, label="Cinematic Intensity")
|
| 63 |
s2 = gr.Slider(0, 100, value=50, label="Detail Level")
|
| 64 |
s3 = gr.Slider(0, 100, value=50, label="Texture Sharpness")
|
| 65 |
s4 = gr.Slider(0, 100, value=50, label="Focus Depth")
|
| 66 |
|
| 67 |
-
btn = gr.Button("Execute
|
| 68 |
-
out = gr.Image(label="Output")
|
| 69 |
|
| 70 |
btn.click(dynamic_relight, [img, txt, dirs, s1, s2, s3, s4], out)
|
| 71 |
|
|
|
|
| 5 |
# Connect to the verified IC-Light engine
|
| 6 |
client = Client("lllyasviel/IC-Light")
|
| 7 |
|
| 8 |
+
def get_smart_resolution(width, height):
|
| 9 |
+
"""
|
| 10 |
+
Intelligently picks the best resolution supported by the model
|
| 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-ish
|
| 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 IMAGE PROCESSING
|
| 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 = "smart_input.png"
|
| 34 |
+
img.save(safe_path)
|
| 35 |
+
|
| 36 |
+
# 2. CALIBRATED SLIDER LOGIC (Safety Rails)
|
| 37 |
+
# We map 0-100 to a safe range (0.0 to 1.6) to prevent "frying" the image
|
| 38 |
+
keywords = ["cinematic", "highly detailed", "sharp texture", "deep focus"]
|
| 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 |
+
# Formula: 100 becomes 1.6 weight (Safe Maximum)
|
| 45 |
+
weight = 0.8 + (slider_vals[i] / 100.0) * 0.8
|
| 46 |
+
user_adjustments += f", ({word}:{weight:.1f})"
|
| 47 |
|
| 48 |
+
# 3. THE "MAGIC" QUALITY BOOSTER
|
| 49 |
+
# We force these keywords onto every request to guarantee professional output
|
| 50 |
+
# irrespective of what the user types.
|
| 51 |
+
quality_guard = ", masterpiece, best quality, ultra-realistic, 8k uhd, dslr, soft lighting, volumetric lighting"
|
| 52 |
+
|
| 53 |
+
# Final robust prompt
|
| 54 |
+
final_prompt = prompt + quality_guard + user_adjustments
|
| 55 |
|
|
|
|
| 56 |
try:
|
| 57 |
result = client.predict(
|
| 58 |
input_fg=handle_file(safe_path),
|
| 59 |
+
prompt=final_prompt,
|
| 60 |
+
image_width=target_w, # Smart Resolution Width
|
| 61 |
+
image_height=target_h, # Smart Resolution Height
|
| 62 |
num_samples=1,
|
| 63 |
+
seed=12345, # Standard stable seed
|
| 64 |
+
steps=30, # Increased steps for better quality
|
| 65 |
+
a_prompt="best quality, masterpiece",
|
| 66 |
+
n_prompt="lowres, bad anatomy, blurry, noisy, grain, distorted",
|
| 67 |
cfg=2.0,
|
| 68 |
highres_scale=1.5,
|
| 69 |
highres_denoise=0.5,
|
|
|
|
| 71 |
bg_source=lighting_choice,
|
| 72 |
api_name="/process_relight"
|
| 73 |
)
|
|
|
|
| 74 |
return result[1][0]['image']
|
| 75 |
|
| 76 |
except Exception as e:
|
| 77 |
+
raise gr.Error(f"System Error: {str(e)}")
|
| 78 |
|
| 79 |
# UI Setup
|
| 80 |
+
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
| 81 |
+
gr.Markdown("# ⚡ Smart Robust Relighter")
|
| 82 |
+
gr.Markdown("Auto-enhances quality regardless of input parameters.")
|
| 83 |
+
|
| 84 |
with gr.Row():
|
| 85 |
with gr.Column():
|
| 86 |
+
img = gr.Image(type="filepath", label="Input Image (Any Size)")
|
| 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 |
+
gr.Markdown("### Enhancement Sliders")
|
| 91 |
s1 = gr.Slider(0, 100, value=50, label="Cinematic Intensity")
|
| 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 |
+
btn = gr.Button("Execute Smart Relight", variant="primary")
|
| 97 |
+
out = gr.Image(label="Enhanced Output")
|
| 98 |
|
| 99 |
btn.click(dynamic_relight, [img, txt, dirs, s1, s2, s3, s4], out)
|
| 100 |
|