Spaces:
Runtime error
Runtime error
moose Claude commited on
Commit ·
2525dc6
1
Parent(s): 4e2578a
Remove demo files and fix image serving for proper download support
Browse files- Remove demo images (disaster_girl.jpg, grumpy.png, wednesday.png)
- Remove hardcoded examples from UI
- Change gallery type from 'pil' to 'filepath' for proper image serving
- Save generated images to outputs/ directory with unique filenames
- Fix image download issues on mobile devices and right-click functionality
- Add .gitignore to exclude IDE configs and generated outputs
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- .gitignore +46 -0
- app.py +39 -26
.gitignore
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# IDE configuration files
|
| 2 |
+
pyrightconfig.json
|
| 3 |
+
.vscode/
|
| 4 |
+
|
| 5 |
+
# Generated outputs
|
| 6 |
+
outputs/
|
| 7 |
+
|
| 8 |
+
# Python
|
| 9 |
+
__pycache__/
|
| 10 |
+
*.py[cod]
|
| 11 |
+
*$py.class
|
| 12 |
+
*.so
|
| 13 |
+
.Python
|
| 14 |
+
env/
|
| 15 |
+
venv/
|
| 16 |
+
ENV/
|
| 17 |
+
build/
|
| 18 |
+
develop-eggs/
|
| 19 |
+
dist/
|
| 20 |
+
downloads/
|
| 21 |
+
eggs/
|
| 22 |
+
.eggs/
|
| 23 |
+
lib/
|
| 24 |
+
lib64/
|
| 25 |
+
parts/
|
| 26 |
+
sdist/
|
| 27 |
+
var/
|
| 28 |
+
wheels/
|
| 29 |
+
*.egg-info/
|
| 30 |
+
.installed.cfg
|
| 31 |
+
*.egg
|
| 32 |
+
|
| 33 |
+
# Model files (if you don't want to track large files)
|
| 34 |
+
*.pt
|
| 35 |
+
*.pth
|
| 36 |
+
*.bin
|
| 37 |
+
*.safetensors
|
| 38 |
+
|
| 39 |
+
# OS files
|
| 40 |
+
.DS_Store
|
| 41 |
+
Thumbs.db
|
| 42 |
+
|
| 43 |
+
# Testing
|
| 44 |
+
.pytest_cache/
|
| 45 |
+
.coverage
|
| 46 |
+
htmlcov/
|
app.py
CHANGED
|
@@ -368,7 +368,8 @@ def update_history(new_images, history):
|
|
| 368 |
def use_history_as_input(evt: gr.SelectData):
|
| 369 |
"""Sets the selected history image as the new input image."""
|
| 370 |
if evt.value is not None:
|
| 371 |
-
|
|
|
|
| 372 |
return gr.update()
|
| 373 |
|
| 374 |
def encode_image(pil_image):
|
|
@@ -417,10 +418,17 @@ def suggest_next_scene_prompt(images):
|
|
| 417 |
if images is not None:
|
| 418 |
for item in images:
|
| 419 |
try:
|
| 420 |
-
if isinstance(item
|
| 421 |
-
|
| 422 |
-
|
| 423 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 424 |
elif hasattr(item, "name"):
|
| 425 |
pil_images.append(Image.open(item.name).convert("RGB"))
|
| 426 |
except Exception:
|
|
@@ -464,10 +472,17 @@ def infer(
|
|
| 464 |
if images is not None:
|
| 465 |
for item in images:
|
| 466 |
try:
|
| 467 |
-
if isinstance(item
|
| 468 |
-
|
| 469 |
-
|
| 470 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 471 |
elif hasattr(item, "name"):
|
| 472 |
pil_images.append(Image.open(item.name).convert("RGB"))
|
| 473 |
except Exception:
|
|
@@ -484,7 +499,7 @@ def infer(
|
|
| 484 |
|
| 485 |
|
| 486 |
# Generate the image
|
| 487 |
-
|
| 488 |
image=pil_images if len(pil_images) > 0 else None,
|
| 489 |
prompt=prompt,
|
| 490 |
height=height,
|
|
@@ -496,13 +511,19 @@ def infer(
|
|
| 496 |
num_images_per_prompt=num_images_per_prompt,
|
| 497 |
).images
|
| 498 |
|
| 499 |
-
#
|
| 500 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 501 |
|
|
|
|
|
|
|
| 502 |
|
| 503 |
-
# --- Examples and UI Layout ---
|
| 504 |
-
examples = []
|
| 505 |
|
|
|
|
| 506 |
css = """
|
| 507 |
#col-container {
|
| 508 |
margin: 0 auto;
|
|
@@ -531,9 +552,9 @@ with gr.Blocks(css=css) as demo:
|
|
| 531 |
""")
|
| 532 |
with gr.Row():
|
| 533 |
with gr.Column():
|
| 534 |
-
input_images = gr.Gallery(label="Input Images",
|
| 535 |
-
show_label=False,
|
| 536 |
-
type="
|
| 537 |
interactive=True)
|
| 538 |
|
| 539 |
prompt = gr.Text(
|
|
@@ -596,7 +617,7 @@ with gr.Blocks(css=css) as demo:
|
|
| 596 |
|
| 597 |
|
| 598 |
with gr.Column():
|
| 599 |
-
result = gr.Gallery(label="Result", show_label=False, type="
|
| 600 |
with gr.Row():
|
| 601 |
use_output_btn = gr.Button("↗️ Use as input", variant="secondary", size="sm", visible=False)
|
| 602 |
turn_video_btn = gr.Button("🎬 Turn into Video", variant="secondary", size="sm", visible=False)
|
|
@@ -613,14 +634,6 @@ with gr.Blocks(css=css) as demo:
|
|
| 613 |
visible=False
|
| 614 |
)
|
| 615 |
|
| 616 |
-
gr.Examples(examples=[
|
| 617 |
-
[["disaster_girl.jpg", "grumpy.png"], "Next Scene: the camera zooms in, showing the cat walking away from the fire"],
|
| 618 |
-
[["wednesday.png"], "Next Scene: The camera pulls back and rises to an elevated angle, revealing the full dance floor with the choreographed movements of all dancers as the central figure becomes part of the larger ensemble."],
|
| 619 |
-
],
|
| 620 |
-
inputs=[input_images, prompt],
|
| 621 |
-
outputs=[result, seed],
|
| 622 |
-
fn=infer,
|
| 623 |
-
cache_examples="lazy")
|
| 624 |
|
| 625 |
|
| 626 |
|
|
|
|
| 368 |
def use_history_as_input(evt: gr.SelectData):
|
| 369 |
"""Sets the selected history image as the new input image."""
|
| 370 |
if evt.value is not None:
|
| 371 |
+
# For filepath gallery, return the path directly in a list
|
| 372 |
+
return gr.update(value=[evt.value])
|
| 373 |
return gr.update()
|
| 374 |
|
| 375 |
def encode_image(pil_image):
|
|
|
|
| 418 |
if images is not None:
|
| 419 |
for item in images:
|
| 420 |
try:
|
| 421 |
+
if isinstance(item, str):
|
| 422 |
+
# Direct file path from filepath gallery
|
| 423 |
+
pil_images.append(Image.open(item).convert("RGB"))
|
| 424 |
+
elif isinstance(item, tuple) and len(item) > 0:
|
| 425 |
+
# Tuple format (legacy support)
|
| 426 |
+
if isinstance(item[0], Image.Image):
|
| 427 |
+
pil_images.append(item[0].convert("RGB"))
|
| 428 |
+
elif isinstance(item[0], str):
|
| 429 |
+
pil_images.append(Image.open(item[0]).convert("RGB"))
|
| 430 |
+
elif isinstance(item, Image.Image):
|
| 431 |
+
pil_images.append(item.convert("RGB"))
|
| 432 |
elif hasattr(item, "name"):
|
| 433 |
pil_images.append(Image.open(item.name).convert("RGB"))
|
| 434 |
except Exception:
|
|
|
|
| 472 |
if images is not None:
|
| 473 |
for item in images:
|
| 474 |
try:
|
| 475 |
+
if isinstance(item, str):
|
| 476 |
+
# Direct file path from filepath gallery
|
| 477 |
+
pil_images.append(Image.open(item).convert("RGB"))
|
| 478 |
+
elif isinstance(item, tuple) and len(item) > 0:
|
| 479 |
+
# Tuple format (legacy support)
|
| 480 |
+
if isinstance(item[0], Image.Image):
|
| 481 |
+
pil_images.append(item[0].convert("RGB"))
|
| 482 |
+
elif isinstance(item[0], str):
|
| 483 |
+
pil_images.append(Image.open(item[0]).convert("RGB"))
|
| 484 |
+
elif isinstance(item, Image.Image):
|
| 485 |
+
pil_images.append(item.convert("RGB"))
|
| 486 |
elif hasattr(item, "name"):
|
| 487 |
pil_images.append(Image.open(item.name).convert("RGB"))
|
| 488 |
except Exception:
|
|
|
|
| 499 |
|
| 500 |
|
| 501 |
# Generate the image
|
| 502 |
+
images_pil = pipe(
|
| 503 |
image=pil_images if len(pil_images) > 0 else None,
|
| 504 |
prompt=prompt,
|
| 505 |
height=height,
|
|
|
|
| 511 |
num_images_per_prompt=num_images_per_prompt,
|
| 512 |
).images
|
| 513 |
|
| 514 |
+
# Save images to temporary files for proper serving
|
| 515 |
+
output_paths = []
|
| 516 |
+
os.makedirs("outputs", exist_ok=True)
|
| 517 |
+
for idx, img in enumerate(images_pil):
|
| 518 |
+
output_path = f"outputs/output_{seed}_{idx}_{int(time.time()*1000)}.png"
|
| 519 |
+
img.save(output_path)
|
| 520 |
+
output_paths.append(output_path)
|
| 521 |
|
| 522 |
+
# Return image paths, seed, and make button visible
|
| 523 |
+
return output_paths, seed, gr.update(visible=True), gr.update(visible=True)
|
| 524 |
|
|
|
|
|
|
|
| 525 |
|
| 526 |
+
# --- UI Layout ---
|
| 527 |
css = """
|
| 528 |
#col-container {
|
| 529 |
margin: 0 auto;
|
|
|
|
| 552 |
""")
|
| 553 |
with gr.Row():
|
| 554 |
with gr.Column():
|
| 555 |
+
input_images = gr.Gallery(label="Input Images",
|
| 556 |
+
show_label=False,
|
| 557 |
+
type="filepath",
|
| 558 |
interactive=True)
|
| 559 |
|
| 560 |
prompt = gr.Text(
|
|
|
|
| 617 |
|
| 618 |
|
| 619 |
with gr.Column():
|
| 620 |
+
result = gr.Gallery(label="Result", show_label=False, type="filepath")
|
| 621 |
with gr.Row():
|
| 622 |
use_output_btn = gr.Button("↗️ Use as input", variant="secondary", size="sm", visible=False)
|
| 623 |
turn_video_btn = gr.Button("🎬 Turn into Video", variant="secondary", size="sm", visible=False)
|
|
|
|
| 634 |
visible=False
|
| 635 |
)
|
| 636 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 637 |
|
| 638 |
|
| 639 |
|