2025年5月23日 星期五

Streamlit 學習筆記 : 使用者輸入元件 (十四) 檔案上傳器

本篇旨在測試 Streamlit 的檔案上傳器函式 st.file_uploader().

本系列所有測試文章參考 :


呼叫 st.file_uploader 函式並傳入必要參數 label 會建立一個檔案上傳按鈕, 按下按鈕會開啟檔按選取視窗選擇要上傳的檔案, 其參數結構如下 : 

st.file_uploader(label, type=None, accept_multiple_files=False, key=None, help=None, on_change=None, args=None, kwargs=None, disabled=False, label_visibility="visible")

st.file_uploader 傳回值是 UploadedFile 物件 (單檔) 或 UploadedFile 物件串列 (多檔), 若未上船任何檔案則傳回 None (單檔) 或空串列(多檔). UploadedFile 物件是 ByteIO 的子類別, 可以傳給任何處理圖檔的函式做進一步處理. 
 
參數說明如下表 :


st.file_uploader() 之參數 說明
label 元件的標籤文字。
type 允許上傳的檔案副檔名列表,例如 ["jpg", "png"],預設為 None(接受所有類型)。
accept_multiple_files 是否允許多檔上傳,布林值,預設為 False。
key 為此元件指定唯一識別字串,以便使用 st.session_state 存取。
help 顯示於元件旁邊的說明提示,滑鼠懸停時可見。
on_change 使用者與元件互動後要執行的函式。
args 傳入 on_change 回呼函式的位置參數 (tuple)。
kwargs 傳入 on_change 回呼函式的關鍵字參數 (dict)。
disabled 是否停用元件,預設為 False。
label_visibility 標籤是否顯示,可設為 "visible"、"hidden" 或 "collapsed"。


檔案上傳按鈕預設是上傳單一檔案, 但可以傳入 accept_multiple_files=True 設定為可上傳多個檔案, 例如 : 


測試 1 : 上傳單一檔案 [看原始碼]       

# st-file_uploader-test-1.py
import streamlit as st
from PIL import Image

st.subheader('上傳單一檔案 (圖片)')
file=st.file_uploader('請上傳圖片', type=['jpg', 'png', 'jpeg'])
if file:
    image=Image.open(uploaded_file)
    st.image(image, caption=file.name)

此例使用 Pillow (PIL) 套件的 Image.read() 函式來開啟上傳之 UploadedFile 物件, 然後用 st.image() 來顯示此圖片. 按 "Browse files" 鈕選擇要上傳的檔案 :




type 參數會限制僅顯示副檔名為 .jpg, .png, .jpeg 的檔案 :





可見上傳完成後會在按鈕下方顯示所上傳之檔案檔名與大小. 如果再次按 "Browse files" 鈕選擇要另一個圖檔上傳, 它將取代之前上傳的檔案 :




下面範例將 accept_multiple_files 設為 True 以便能上傳多個檔案 :


測試 2 : 上傳多個檔案 [看原始碼]       

# st-file_uploader-test-2.py
import streamlit as st
from PIL import Image

st.subheader('上傳多個檔案 (圖片)')
files=st.file_uploader(
    '請上傳圖片',
    type=['jpg', 'png', 'jpeg'],
    accept_multiple_files=True
    )
if files:
    for file in files:
        image=Image.open(file)
        st.image(file, caption=file.name)

此例 file_uploader() 傳回一個串列, 所以用一個迴圈走訪每一個 UploadedFile 物件並用 st.image() 來顯示圖片 :




可以按住 Ctrl 或 Shift 鍵選擇多個檔案同時上傳 :




可見按鈕下方會顯示已上傳檔案清單 :




下面是 on_change 與 args 參數測試範例 :


測試 3 : 參數 on_change 與 args 用法 [看原始碼] 

# st-file_uploader-test-3.py
import streamlit as st

def on_upload_change(label):
    st.success(f'{label}檔案已上傳!')
    file=st.session_state['file']
    if file:
        st.write(f'檔名:{file.name}')
        st.write(f'大小:{file.size} bytes')

st.file_uploader(
    '請上傳檔案',
    type=['txt', 'pdf', 'docx'],
    key='file',
    on_change=on_upload_change,
    args=('機密',)
    )

此例利用 args 傳送引數給 on_change 事件處理函式的 label 參數, st.file_uploader() 的傳回值 (UploadedFile 物件) 會以 'file' 為鍵儲存在 st.session_state 字典裡, 結果如下 :






也可以用 kwargs 參數來傳遞引數, 例如 : 


測試 4 : 參數 on_change 與 kwargs 用法 [看原始碼] 

# st-file_uploader-test-4.py
import streamlit as st

def on_upload_change(label):
    st.success(f'{label}檔案已上傳!')
    file=st.session_state['file']
    if file:
        st.write(f'檔名:{file.name}')
        st.write(f'大小:{file.size} bytes')

st.file_uploader(
    '請上傳檔案',
    type=['txt', 'pdf', 'docx'],
    key='file',
    on_change=on_upload_change,
    kwargs={'label': '機密'}
    )

結果與上面範例相同.

沒有留言 :