Background Image Not Displaying in st_canvas on Streamlit Cloud, Works Locally

In my Streamlit app, users can upload an image (JPG, JPEG, PNG), draw over it, and download that image. The app works perfectly on my local environment (localhost:8501), but when deployed to Streamlit Cloud, the original image does not appear as the background for the st_canvas component during the drawing step. However, the image displays correctly during the initial upload step.

You can find the project on GitHub here: GitHub - meghna-cse/cloakdocs-web-app: A Web App for Masking Information in Images

I explored the forum and tried several suggested approaches, but none resolved the issue. Below is a detailed summary of the approaches I’ve tried so far:

Approaches Tried that didn’t work:

  1. Base64 Encoded String

    Convert the uploaded image into a base64-encoded string and pass it to the background_image parameter of st_canvas. This led to an AttributeError because st_canvas expected an object with a height attribute, not a string.

    Code:

    buffered = io.BytesIO()
    resized_image.save(buffered, format=“PNG”)
    img_str = f"data:image/png;base64,{base64.b64encode(buffered.getvalue()).decode()}"

  2. Numpy Array

    Tried converting the PIL image to a NumPy array and passed it to background_image. This resulted in a ValueError since the NumPy array wasn’t correctly interpreted by st_canvas.

    Code:

    img_array = np.array(original_image)

  3. PIL Image Directly

    Passed the uploaded image directly to the background_image parameter without reprocessing it. This approach worked locally but the image still didn’t appear as the canvas background on Streamlit Cloud.

    Code:

    background_image=resized_image,

  4. In-Memory Image Handling

    Tried to handle images entirely in memory using BytesIO to avoid file handling issues that might be causing the missing image. In the network tab, I noticed that requests for the image were blocked or missing (NS_BINDING_ABORTED). I suspected it might be a cross-origin resource sharing (CORS) issue or a Streamlit Cloud-specific restriction.
    This fixed some issues with file handling, but the image still did not render on the st_canvas in Streamlit Cloud.

    Code:

    def get_image_bytes(image: Image.Image) → BytesIO:
    img_bytes = BytesIO()
    image.save(img_bytes, format=‘PNG’)
    img_bytes.seek(0)
    return img_bytes

    Also tried using the in-memory image (BytesIO) directly as the background image for st_canvas without reopening it, to avoid missing file issues. The image still didn’t render on Streamlit Cloud, though it worked locally.

  5. Using Session

    Stored the encoded and decoded images in Streamlit’s session_state to ensure they persisted across app reruns and were properly passed to the st_canvas component. This still did not solve the issue of the missing background image in Streamlit Cloud.

  6. Downgraded streamlit_drawable_canvas to v0.9.0

    I downgraded the version of the streamlit_drawable_canvas library to see if there was an issue introduced in newer versions. The image still didn’t render on Streamlit Cloud, though it worked locally.

If anyone has encountered a similar issue or can provide additional insights on handling images or working with streamlit_drawable_canvas on Streamlit Cloud, I would appreciate the help!
If any of the above approaches worked for you, I’d love to dig deeper into it and find a solution. Any insights would be greatly appreciated. Thank you in advance!

Hi,
I am now having this issue also, was working fine previously, locally ok.

Andrew