Spaces:
Runtime error
Runtime error
update app
Browse files
app.py
CHANGED
|
@@ -103,6 +103,31 @@ def update_dimensions_on_upload(image):
|
|
| 103 |
|
| 104 |
return new_width, new_height
|
| 105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
def update_style_selection(evt: gr.SelectData):
|
| 107 |
"""Update selected style based on gallery click"""
|
| 108 |
selected_style = LORA_STYLES[evt.index]
|
|
@@ -116,7 +141,7 @@ def update_style_selection(evt: gr.SelectData):
|
|
| 116 |
|
| 117 |
@spaces.GPU
|
| 118 |
def infer(
|
| 119 |
-
|
| 120 |
prompt,
|
| 121 |
selected_style_index,
|
| 122 |
seed=42,
|
|
@@ -128,8 +153,14 @@ def infer(
|
|
| 128 |
gc.collect()
|
| 129 |
torch.cuda.empty_cache()
|
| 130 |
|
| 131 |
-
if not
|
| 132 |
-
raise gr.Error("Please upload
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
|
| 134 |
if selected_style_index is None:
|
| 135 |
selected_style_index = 0
|
|
@@ -162,12 +193,21 @@ def infer(
|
|
| 162 |
if randomize_seed:
|
| 163 |
seed = random.randint(0, MAX_SEED)
|
| 164 |
|
| 165 |
-
|
| 166 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 167 |
|
| 168 |
try:
|
|
|
|
|
|
|
|
|
|
| 169 |
image = pipe(
|
| 170 |
-
image=
|
| 171 |
prompt=prompt,
|
| 172 |
guidance_scale=guidance_scale,
|
| 173 |
width=width,
|
|
@@ -185,12 +225,21 @@ def infer(
|
|
| 185 |
torch.cuda.empty_cache()
|
| 186 |
|
| 187 |
@spaces.GPU
|
| 188 |
-
def infer_example(
|
| 189 |
-
if
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 190 |
return None, 0
|
| 191 |
|
| 192 |
image, seed = infer(
|
| 193 |
-
|
| 194 |
prompt=prompt,
|
| 195 |
selected_style_index=style_index,
|
| 196 |
seed=0,
|
|
@@ -200,26 +249,30 @@ def infer_example(input_image, prompt, style_index):
|
|
| 200 |
)
|
| 201 |
return image, seed
|
| 202 |
|
| 203 |
-
css="""
|
| 204 |
#col-container { margin: 0 auto; max-width: 960px; }
|
| 205 |
#main-title h1 { font-size: 2.2em !important; }
|
| 206 |
-
#style_gallery .grid-wrap{height: 10vh}
|
|
|
|
| 207 |
"""
|
| 208 |
|
| 209 |
with gr.Blocks() as demo:
|
| 210 |
with gr.Column(elem_id="col-container"):
|
| 211 |
gr.Markdown("# **FLUX.2-Klein-LoRA-Studio**", elem_id="main-title")
|
| 212 |
-
gr.Markdown("Perform diverse image edits using specialized [LoRAs](https://huggingface.co/models?other=base_model:adapter:black-forest-labs/FLUX.2-klein-9B) adapters for the [FLUX.2-Klein-Distilled](https://huggingface.co/black-forest-labs/FLUX.2-klein-9B) model.")
|
| 213 |
|
| 214 |
selected_style_index = gr.State(0)
|
| 215 |
|
| 216 |
with gr.Row(equal_height=True):
|
| 217 |
with gr.Column():
|
| 218 |
-
|
| 219 |
-
label="Upload
|
| 220 |
-
type="
|
| 221 |
-
|
| 222 |
-
|
|
|
|
|
|
|
|
|
|
| 223 |
)
|
| 224 |
with gr.Row():
|
| 225 |
prompt = gr.Text(
|
|
@@ -253,13 +306,15 @@ with gr.Blocks() as demo:
|
|
| 253 |
|
| 254 |
gr.Examples(
|
| 255 |
examples=[
|
| 256 |
-
["examples/2.jpg", "Relight the image to remove all existing lighting conditions and replace them with neutral, uniform illumination. Apply soft, evenly distributed lighting with no directional shadows, no harsh highlights, and no dramatic contrast. Maintain the original identity of all subjects exactly—preserve facial structure, skin tone, proportions, expressions, hair, clothing, and textures. Do not alter pose, camera angle, background geometry, or image composition. Lighting should appear balanced, and studio-neutral, similar to diffuse overcast or a soft lightbox setup. Ensure consistent exposure across the entire image with realistic depth and subtle shading only where necessary for form."],
|
| 257 |
-
["examples/1.jpg", "cinematic polaroid with soft grain subtle vignette gentle lighting white frame handwritten photographed by prithivMLmods preserving realistic texture and details"],
|
|
|
|
| 258 |
],
|
| 259 |
-
inputs=[
|
| 260 |
outputs=[output_image, used_seed],
|
| 261 |
fn=infer_example,
|
| 262 |
cache_examples=False,
|
|
|
|
| 263 |
)
|
| 264 |
|
| 265 |
gr.Markdown("[*](https://huggingface.co/black-forest-labs/FLUX.2-klein-9B)This is still an experimental Space for FLUX.2-Klein-9B. More adapters will be added soon.")
|
|
@@ -271,7 +326,7 @@ with gr.Blocks() as demo:
|
|
| 271 |
|
| 272 |
run_button.click(
|
| 273 |
fn=infer,
|
| 274 |
-
inputs=[
|
| 275 |
outputs=[output_image, used_seed]
|
| 276 |
)
|
| 277 |
|
|
|
|
| 103 |
|
| 104 |
return new_width, new_height
|
| 105 |
|
| 106 |
+
def process_gallery_images(images):
|
| 107 |
+
"""Process images from gallery input and return list of PIL images."""
|
| 108 |
+
if not images:
|
| 109 |
+
return []
|
| 110 |
+
|
| 111 |
+
pil_images = []
|
| 112 |
+
for item in images:
|
| 113 |
+
try:
|
| 114 |
+
if isinstance(item, tuple) or isinstance(item, list):
|
| 115 |
+
path_or_img = item[0]
|
| 116 |
+
else:
|
| 117 |
+
path_or_img = item
|
| 118 |
+
|
| 119 |
+
if isinstance(path_or_img, str):
|
| 120 |
+
pil_images.append(Image.open(path_or_img).convert("RGB"))
|
| 121 |
+
elif isinstance(path_or_img, Image.Image):
|
| 122 |
+
pil_images.append(path_or_img.convert("RGB"))
|
| 123 |
+
else:
|
| 124 |
+
pil_images.append(Image.open(path_or_img.name).convert("RGB"))
|
| 125 |
+
except Exception as e:
|
| 126 |
+
print(f"Skipping invalid image item: {e}")
|
| 127 |
+
continue
|
| 128 |
+
|
| 129 |
+
return pil_images
|
| 130 |
+
|
| 131 |
def update_style_selection(evt: gr.SelectData):
|
| 132 |
"""Update selected style based on gallery click"""
|
| 133 |
selected_style = LORA_STYLES[evt.index]
|
|
|
|
| 141 |
|
| 142 |
@spaces.GPU
|
| 143 |
def infer(
|
| 144 |
+
input_images,
|
| 145 |
prompt,
|
| 146 |
selected_style_index,
|
| 147 |
seed=42,
|
|
|
|
| 153 |
gc.collect()
|
| 154 |
torch.cuda.empty_cache()
|
| 155 |
|
| 156 |
+
if not input_images:
|
| 157 |
+
raise gr.Error("Please upload at least one image to apply a style to.")
|
| 158 |
+
|
| 159 |
+
# Process gallery images
|
| 160 |
+
pil_images = process_gallery_images(input_images)
|
| 161 |
+
|
| 162 |
+
if not pil_images:
|
| 163 |
+
raise gr.Error("Could not process uploaded images.")
|
| 164 |
|
| 165 |
if selected_style_index is None:
|
| 166 |
selected_style_index = 0
|
|
|
|
| 193 |
if randomize_seed:
|
| 194 |
seed = random.randint(0, MAX_SEED)
|
| 195 |
|
| 196 |
+
# Get dimensions from first image
|
| 197 |
+
width, height = update_dimensions_on_upload(pil_images[0])
|
| 198 |
+
|
| 199 |
+
# Process all images to the same dimensions
|
| 200 |
+
processed_images = [
|
| 201 |
+
img.resize((width, height), Image.LANCZOS).convert("RGB")
|
| 202 |
+
for img in pil_images
|
| 203 |
+
]
|
| 204 |
|
| 205 |
try:
|
| 206 |
+
# Pass single image or list based on count
|
| 207 |
+
image_input = processed_images if len(processed_images) > 1 else processed_images[0]
|
| 208 |
+
|
| 209 |
image = pipe(
|
| 210 |
+
image=image_input,
|
| 211 |
prompt=prompt,
|
| 212 |
guidance_scale=guidance_scale,
|
| 213 |
width=width,
|
|
|
|
| 225 |
torch.cuda.empty_cache()
|
| 226 |
|
| 227 |
@spaces.GPU
|
| 228 |
+
def infer_example(input_images, prompt, style_index):
|
| 229 |
+
if not input_images:
|
| 230 |
+
return None, 0
|
| 231 |
+
|
| 232 |
+
# Handle both single image path and list of paths for examples
|
| 233 |
+
if isinstance(input_images, str):
|
| 234 |
+
input_images = [input_images]
|
| 235 |
+
elif isinstance(input_images, list) and len(input_images) > 0:
|
| 236 |
+
# If it's already a list, keep it as is
|
| 237 |
+
pass
|
| 238 |
+
else:
|
| 239 |
return None, 0
|
| 240 |
|
| 241 |
image, seed = infer(
|
| 242 |
+
input_images=input_images,
|
| 243 |
prompt=prompt,
|
| 244 |
selected_style_index=style_index,
|
| 245 |
seed=0,
|
|
|
|
| 249 |
)
|
| 250 |
return image, seed
|
| 251 |
|
| 252 |
+
css = """
|
| 253 |
#col-container { margin: 0 auto; max-width: 960px; }
|
| 254 |
#main-title h1 { font-size: 2.2em !important; }
|
| 255 |
+
#style_gallery .grid-wrap { height: 10vh }
|
| 256 |
+
#input_gallery .grid-wrap { min-height: 200px }
|
| 257 |
"""
|
| 258 |
|
| 259 |
with gr.Blocks() as demo:
|
| 260 |
with gr.Column(elem_id="col-container"):
|
| 261 |
gr.Markdown("# **FLUX.2-Klein-LoRA-Studio**", elem_id="main-title")
|
| 262 |
+
gr.Markdown("Perform diverse image edits using specialized [LoRAs](https://huggingface.co/models?other=base_model:adapter:black-forest-labs/FLUX.2-klein-9B) adapters for the [FLUX.2-Klein-Distilled](https://huggingface.co/black-forest-labs/FLUX.2-klein-9B) model. Supports multiple image inputs for style transfer and reference-based editing.")
|
| 263 |
|
| 264 |
selected_style_index = gr.State(0)
|
| 265 |
|
| 266 |
with gr.Row(equal_height=True):
|
| 267 |
with gr.Column():
|
| 268 |
+
input_images = gr.Gallery(
|
| 269 |
+
label="Upload Images",
|
| 270 |
+
type="filepath",
|
| 271 |
+
columns=2,
|
| 272 |
+
rows=1,
|
| 273 |
+
height=290,
|
| 274 |
+
allow_preview=True,
|
| 275 |
+
elem_id="input_gallery"
|
| 276 |
)
|
| 277 |
with gr.Row():
|
| 278 |
prompt = gr.Text(
|
|
|
|
| 306 |
|
| 307 |
gr.Examples(
|
| 308 |
examples=[
|
| 309 |
+
[["examples/2.jpg"], "Relight the image to remove all existing lighting conditions and replace them with neutral, uniform illumination. Apply soft, evenly distributed lighting with no directional shadows, no harsh highlights, and no dramatic contrast. Maintain the original identity of all subjects exactly—preserve facial structure, skin tone, proportions, expressions, hair, clothing, and textures. Do not alter pose, camera angle, background geometry, or image composition. Lighting should appear balanced, and studio-neutral, similar to diffuse overcast or a soft lightbox setup. Ensure consistent exposure across the entire image with realistic depth and subtle shading only where necessary for form."],
|
| 310 |
+
[["examples/1.jpg"], "cinematic polaroid with soft grain subtle vignette gentle lighting white frame handwritten photographed by prithivMLmods preserving realistic texture and details"],
|
| 311 |
+
[["examples/1.jpg", "examples/2.jpg"], "Apply the style from image 2 to image 1, preserving the subject's identity."],
|
| 312 |
],
|
| 313 |
+
inputs=[input_images, prompt],
|
| 314 |
outputs=[output_image, used_seed],
|
| 315 |
fn=infer_example,
|
| 316 |
cache_examples=False,
|
| 317 |
+
label="Examples"
|
| 318 |
)
|
| 319 |
|
| 320 |
gr.Markdown("[*](https://huggingface.co/black-forest-labs/FLUX.2-klein-9B)This is still an experimental Space for FLUX.2-Klein-9B. More adapters will be added soon.")
|
|
|
|
| 326 |
|
| 327 |
run_button.click(
|
| 328 |
fn=infer,
|
| 329 |
+
inputs=[input_images, prompt, selected_style_index, seed, randomize_seed, guidance_scale, steps],
|
| 330 |
outputs=[output_image, used_seed]
|
| 331 |
)
|
| 332 |
|