VirtualTryonFR1 / app.py
RojaKatta's picture
Update app.py
a0e0dac verified
raw
history blame
3.4 kB
import os
import time
import uuid
from typing import Optional
import gradio as gr
from PIL import Image
# ------------------------------------------------------------
# Pick a writable save directory automatically.
# Order:
# 1) SAVE_DIR env var (if supplied)
# 2) /data/uploads (when Persistent Storage is enabled)
# 3) /home/user/app/uploads (always writable in Spaces)
# 4) /tmp/uploads (always writable, ephemeral)
# ------------------------------------------------------------
def pick_writable_dir() -> str:
candidates = []
env_dir = os.getenv("SAVE_DIR")
if env_dir:
candidates.append(env_dir)
candidates += ["/data/uploads", "/home/user/app/uploads", "/tmp/uploads"]
for path in candidates:
try:
os.makedirs(path, exist_ok=True)
# double-check we can create files here
testfile = os.path.join(path, f".write_test_{uuid.uuid4().hex}")
with open(testfile, "w") as f:
f.write("ok")
os.remove(testfile)
return path
except Exception:
continue
# last resort: current directory
fallback = "./uploads"
os.makedirs(fallback, exist_ok=True)
return fallback
SAVE_DIR = pick_writable_dir()
ALLOWED_FORMATS = {"JPEG", "PNG"} # strict type enforcement
def handle_upload(file_path: Optional[str]):
if not file_path:
return "Please choose an image.", None
try:
with Image.open(file_path) as im:
fmt = (im.format or "").upper()
if fmt not in ALLOWED_FORMATS:
return f"Only JPEG/PNG allowed. Detected: {fmt or 'unknown'}.", None
# Normalize to RGB so we can always save safely
if im.mode not in ("RGB", "RGBA"):
im = im.convert("RGB")
# Choose extension from the detected format
ext = ".jpg" if fmt == "JPEG" else ".png"
filename = f"{int(time.time())}_{uuid.uuid4().hex}{ext}"
save_path = os.path.join(SAVE_DIR, filename)
# Reasonable defaults for each format
if fmt == "JPEG":
im.save(save_path, quality=90, optimize=True)
else:
im.save(save_path, optimize=True)
info = (
f"βœ… Saved to **{save_path}**\n\n"
f"- File: **{filename}**\n"
f"- Size: **{im.width}Γ—{im.height}px**\n"
f"- Format: **{fmt}**"
)
return info, im.copy()
except Exception as e:
return f"Failed to read/save image: {e}", None
with gr.Blocks(title="Image Upload (JPEG/PNG)") as demo:
gr.Markdown("### Upload a JPEG or PNG. The file will be validated and saved.")
with gr.Row():
inp = gr.Image(
label="Drop or click to upload",
type="filepath", # keep original temp filepath
image_mode="RGB",
sources=["upload", "clipboard"]
)
preview = gr.Image(label="Preview", interactive=False)
msg = gr.Markdown()
# Auto-save when the image changes; also allow manual click.
inp.change(handle_upload, inputs=inp, outputs=[msg, preview])
gr.Button("Save").click(handle_upload, inputs=inp, outputs=[msg, preview])
gr.Markdown(f"**Save directory:** `{SAVE_DIR}`")
if __name__ == "__main__":
demo.launch()