Retrieve url where image is served / Image ID

Hello dear community,

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.

I could not find a way to access neither this image url or the image id to build this url:
http://localhost:8501/media/87af0b27e083a7ab10e58a185c8ea600697a7.png

Maybe someone is able to help me with that :smile:

β†’ 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.

Thanks for the help!

Hello @haasan,

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

P.S. Lets connect on LinkedIn!

➀ Website: https://sahirmaharaj.com
➀ Email: sahir@sahirmaharaj.com
➀ Want me to build your solution? Lets chat about how I can assist!
➀ Join my Medium community of 30k readers! Sharing my knowledge about data science and AI
➀ 100+ FREE Power BI Themes: Download Now

2 Likes

You need to use your publicly accesible address. locahost is accesible only from the same machine.

Hi,

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)