import os import sys import subprocess import tempfile import base64 from io import BytesIO import streamlit as st from PIL import Image # Set Streamlit page configuration (centered content via CSS) st.set_page_config( page_title="Metamorph: DiffMorpher + LCM-LoRA + FILM", layout="wide", page_icon="🌀" ) def save_uploaded_file(uploaded_file, dst_path): with open(dst_path, "wb") as f: f.write(uploaded_file.getbuffer()) def get_img_as_base64(img): buffered = BytesIO() img.save(buffered, format="PNG") return base64.b64encode(buffered.getvalue()).decode("utf-8") def main(): # ---------------- CUSTOM CSS FOR A PROFESSIONAL, DARK THEME ---------------- st.markdown( """ """, unsafe_allow_html=True ) # ---------------- HEADER & LOGO ---------------- logo_path = os.path.join("lcm-lora", "metamorphLogo_nobg.png") if os.path.exists(logo_path): try: logo = Image.open(logo_path) logo_base64 = get_img_as_base64(logo) st.markdown( f"""
DiffMorpher is used for keyframe generation by default, with FILM for interpolation. Optionally, you can enable LCM-LoRA for accelerated inference (with slight decrease in quality). Upload two images, optionally provide textual prompts, and fine-tune the settings to create a smooth, high-quality morphing video.
Select a preset below to automatically adjust quality and inference time. If you choose Custom ⚙️, the advanced settings will automatically expand so you can fine-tune the configuration.
""", unsafe_allow_html=True ) # Preset Options (Dropdown) st.markdown("**Preset Options**") preset_option = st.selectbox( "Select a preset for quality and inference time", options=[ "Maximum quality, highest inference time 🏆", "Medium quality, medium inference time ⚖️", "Low quality, lowest inference time ⚡", "Creative morph 🎨", "Custom ⚙️" ], index=0, label_visibility="collapsed" # Hide the label in the UI but keep it for accessibility ) # Determine preset defaults based on selection if preset_option.startswith("Maximum quality"): # "Maximum quality, highest inference time 🏆" preset_model = "Base Stable Diffusion V2-1 (No LCM-LoRA support)" preset_film = True preset_lcm = False elif preset_option.startswith("Medium quality"): # "Medium quality, medium inference time ⚖️" preset_model = "Base Stable Diffusion V2-1 (No LCM-LoRA support)" preset_film = False preset_lcm = False elif preset_option.startswith("Low quality"): # "Low quality, lowest inference time ⚡" preset_model = "Base Stable Diffusion V1-5" preset_film = False preset_lcm = True elif preset_option.startswith("Creative morph"): # "Creative morph 🎨" preset_model = "Dreamshaper-7 (fine-tuned SD V1-5)" preset_film = True preset_lcm = True else: # "Custom ⚙️" preset_model = None preset_film = None preset_lcm = None # Auto-expand advanced options if "Custom ⚙️" is chosen advanced_expanded = True if preset_option.endswith("⚙️") else False # Advanced Options for fine-tuning with st.expander("Advanced Options", expanded=advanced_expanded): options_list = [ "Base Stable Diffusion V1-5", "Dreamshaper-7 (fine-tuned SD V1-5)", "Base Stable Diffusion V2-1 (No LCM-LoRA support)" ] default_model = preset_model if preset_model is not None else "Base Stable Diffusion V1-5" default_index = options_list.index(default_model) model_option = st.selectbox("Select Model Card", options=options_list, index=default_index) col_left, col_right = st.columns(2) # Left Column: Keyframe Generator Parameters with col_left: st.markdown("##### Keyframe Generator Parameters") num_frames = st.number_input("Number of keyframes (2–200)", min_value=2, max_value=200, value=20) if model_option == "Base Stable Diffusion V2-1 (No LCM-LoRA support)": enable_lcm_lora = st.checkbox( "Enable LCM-LoRA (accelerated inference, slight decrease in quality)", value=False, disabled=True, help="LCM-LoRA is not available for the selected model card." ) else: lcm_default = preset_lcm if preset_lcm is not None else False enable_lcm_lora = st.checkbox( "Enable LCM-LoRA (accelerated inference, slight decrease in quality)", value=lcm_default ) use_adain = st.checkbox("Use AdaIN", value=True) use_reschedule = st.checkbox("Use reschedule sampling", value=True) keyframe_duration = st.number_input("Keyframe Duration (seconds, only if not using FILM)", min_value=0.01, max_value=5.0, value=0.1, step=0.01) # Right Column: Inter-frame Interpolator Parameters (FILM) with col_right: st.markdown("