My streamlit app is running locally streamlit==1.30.0 on python==3.11.7
I am currently building a Streamlit App that leverages different StableDiffusion APIs. For ComfyUIs Controlnet to work I need to serve an image at an URL.
From my understanding streamlits MediaFileManager does just that. → Right click and copy image url will provide me with an url to my image on localhost.
→ My fallback solution would be to save the generated image to a folder and use Streamlits ability for static file serving Static file serving - Streamlit Docs. But then I would have to worry about cleaning up the files after a session ends.
You could implement your fallback solution in a Streamlit app, along with a simple cleanup mechanism:
import streamlit as st
import os
import shutil
from PIL import Image
import uuid
# Directory where images will be saved
IMAGES_DIR = "served_images"
# Create the directory if it does not exist
if not os.path.exists(IMAGES_DIR):
os.makedirs(IMAGES_DIR)
# Function to save an image and return its URL
def save_image(image_data):
image_id = str(uuid.uuid4())
image_path = os.path.join(IMAGES_DIR, f"{image_id}.png")
image_data.save(image_path)
return st.experimental_get_server_url() + image_path
# Example usage
uploaded_file = st.file_uploader("Upload an image", type=["png", "jpg", "jpeg"])
if uploaded_file:
image = Image.open(uploaded_file)
image_url = save_image(image)
st.write(f"Image URL: {image_url}")
# Display the image using the URL
st.image(image_url)
# Optional: Cleanup images directory upon session end
# This can be more complex depending on your app's logic and needs
@st.experimental_singleton
def cleanup_images_dir():
def cleanup():
if os.path.exists(IMAGES_DIR):
shutil.rmtree(IMAGES_DIR)
return cleanup
st.experimental_on_session_end(cleanup_images_dir())
Kind Regards,
Sahir Maharaj
Data Scientist | AI Engineer
I also needed a solution to generate external URL for images available in bytes array or local path.
I came up with this quick and dirty solution based on image_to_url, the function used by st.image() to share images :
import streamlit.elements.image as st_image
BASE_URL="www.mywebsite.com"
def image_to_url(image: st_image.AtomicImage) -> str:
"""Generate a URL for an image
Args:
image (image.AtomicImage): URL, path, buffer, PIL, ...
Returns:
str: URL to image
"""
# generate an ID
image_id = str(hash(image)) # only tested on path
image_url = st_image.image_to_url(
image=image,
width=st_image.WidthBehaviour.AUTO,
clamp=False,
channels="RGB",
output_format="auto",
image_id=image_id,
)
image_full_url = BASE_URL + image_url
return image_full_url
Why it’s dirty :
I don’t think it’s part of the streamlit API, streamlit upgrade might brake it
If you also use st.image() to display the image, the image is probably cached 2x times (one for the html, one to generate your link)