How can I pass image file from file_uploader()
to opencv’s imread()
?
file_uploader does not store the uploaded file on the webserver but keeps it in memory. It returns a ‘stream’ class variable to access it. I came across this situation as well but honestly I dont have THE answer yet. Fact seems to be that some python modules dont care whether you throw a pathname or a stream at them , but many other do. To me the python ‘stream’ classes appear as a relatively relatively complex matter. You may try to give imread the stream but if this doesnt work you may save the stream to a file and then read like usual. However it might be difficult with streamlit to find the right point in time to delete the quasi temporary file. I dont know if the webserver does this by it itself, does it? Same issue with files you create for downloading. AT the moment I am completely ignoring this issue on my streamlit apps because there are only very few users that work with them.
code fragment to save the file:
fs = st.file_uploader('upload a file')
if fs is not None:
with open(fs.name,'wb') as f:
f.write(fs.read())
Thanks a lot.
@ksxx you are my knight in shining armor.
I attempted to read file_uploader from memory using these two functions
def create_opencv_image_from_stringio(img_stream, cv2_img_flag=0):
img_stream.seek(0)
img_array = np.asarray(bytearray(img_stream.read()), dtype=np.uint8)
return cv2.imdecode(img_array, cv2_img_flag)
def get_opencv_img_from_buffer(buffer, flags):
bytes_as_np_array = np.frombuffer(buffer.read(), dtype=np.uint8)
return cv2.imdecode(bytes_as_np_array, flags)
but they didn’t work and I would say don’t waste your time trying to get them to work.
The main problem with this is that it would create endless image files in the server-side application if each image name is different right?
Turns out you can just save all images as ‘img.jpg’ and it won’t create endless files with different names.
from PIL import Image
# Saves
img = Image.open(img)
img = img.save("img.jpg")
# OpenCv Read
img = cv2.imread("img.jpg")