Upload image to drive from numpy.ndarray

Hi @Laszlo_Sebestyen, if u use st.image(gray) it works because you are taking the input from st.file_uploader() or st.camera_input(), and displaying it through st.image.

It works perfectly fine, because st.file_uploader() converts files into bytes stream(BytesIO) and st.image() expects bytesIO/ndarray, etc. Refer this docs.

But uploading image to a deta drive(by drive.put()) require two things mainly:

  1. name of the image
  2. path of the image

But unfortunately streamlit doesn’t provide these both. So this approach of mine might help you,
First we need one of the deprecated features, We need to enable automatic decoding of files which is deprecated in the release Version 0.64.0

st.set_option('deprecation.showfileUploaderEncoding', False)

Next step is to store the uploaded data in a variable by using st.file_uploader(), then read the file using .read() and write the file locally with the name you want. The file will be saved to the root folder. So finally we can access the file using its name and path. So after uploading it to deta base, You can use os.delete(filename) to delete the file.

Here’s the final code for multi file/image upload:

# Imports
import streamlit as st
from deta import Deta

DETA_KEY = "XXXX...." # Secret key to connect to deta drive
deta = Deta(DETA_KEY) # Initialize deta object with a project key

drive = deta.Drive("drive_name") # Connecting to the Deta drive

# Here i'm taking the input from `st.file_uploader`, same principle can be  applied.
uploaded_files = st.file_uploader("Choose photos to upload", accept_multiple_files=True, type=['png', 'jpeg', 'jpg'])
    st.set_option('deprecation.showfileUploaderEncoding', False) # Enabling the automatic file decoder
    submit_button = st.button(label='Upload Photos') # Submit button
pic_names = [] # Later used for deleting the local files after being uploaded
    for uploaded_file in uploaded_files: # Iterating over each file uploaded
        file = uploaded_file.read() # Read the data
        image_result = open(uploaded_file.name, 'wb') # creates a writable image and later we can write the decoded result
        image_result.write(file) # Saves the file with the name uploaded_file.name to the root path('./')
        pic_names.append(uploaded_file.name) # Append the name of image to the list
        image_result.close() # Close the file pointer
if submit_button:
        for i in range(len(pic_names)): # Iterating over each file name
            name = pic_names[i] # Getting the name of current file
            path ='./'+pic_names[i] # Creating path string which is basically ["./image.jpg"]
            drive.put(name, path=path) # so, we have our file name and path, so uploading images to the drive
            os.remove(pic_names[i]) # Finally deleting it from root folder
        st.success('Thanks for uploading!') # Success message

This will work perfectly fine, but it has its limitations. As the processing of converitng and deleting the files takes some work upfront. It may have limitations but works fast! :rocket: and it’s the only way upto my Knowledge.

You can checkout my actual implementation in my repo here.

Happy Coding! :wink:

Thanks&Regards,
Srinivas Menta