在前一篇測試裡, 我們使用 Gradio 作為 WebUI 工具, 在頁面中輸入金鑰與提示詞呼叫 OpenAI Image API 來生成圖像, 本篇則是要改用 Streamlit 來實作功能相同的 Web app.
關於 Streamlit 套件用法參考 :
本篇要改寫的對象是前一篇測試中, 模型選單與尺寸選單有連動功能的 gradio-openai-image-api-test-2.py 這個 web app :
import gradio as gr
from openai import OpenAI
# 圖片尺寸選項
size_options={
'dall-e-2': ['256x256', '512x512', '1024x1024'],
'dall-e-3': ['1024x1024', '1024x1792', '1792x1024']
}
# 呼叫 OpenAI API 生圖
def generate_images(prompt, api_key, **kwargs):
client=OpenAI(api_key=api_key)
replies=client.images.generate(prompt=prompt, **kwargs)
urls=[item.url for item in replies.data]
return urls # Gallery 只能接收串列
# 執行按鈕時處理函式
def handler(api_key, prompt, model_sel, size_sel, image_count):
if not api_key.strip(): # 處理使用者未輸入金鑰問題
return [], '請輸入 OpenAI API Key'
if not prompt.strip(): # 處理使用者未輸入提示詞問題
return [], '請輸入提示詞 (prompt)'
if model_sel == 'dall-e-2':
size=size_sel
n=image_count # dall-e-2 允許生 1~10 張圖
else:
size=size_sel
n=1 # dall-e-3 只允許生 1 張圖
urls=generate_images(prompt, api_key, model=model_sel, n=n, size=size)
msg=f'模型: {model_sel}\n尺寸: {size}\n張數: {n}' # 輸出設定值
return urls, msg # 傳回生圖之網址串列給 Gallery, 設定值給狀態訊息
# 模型選單連動圖片尺寸選單 : 動態更新圖片尺寸選單
def update_size_options(selected_model):
return gr.update(
choices=size_options[selected_model],
value=size_options[selected_model][0]
)
# 使用 Blocks 語法 (才有元件連動功能)
with gr.Blocks(title='OpenAI Image API 測試') as blocks:
gr.Markdown('## 🎨 使用 DALL·E 2 / 3 生圖')
api_key=gr.Textbox(label='請輸入金鑰 (API key)', type='password')
prompt=gr.TextArea(label='請輸入提示詞 (Prompt)', max_lines=10)
model_sel=gr.Radio(
label='選擇模型',
choices=['dall-e-2', 'dall-e-3'],
value='dall-e-3'
)
size_sel=gr.Radio(
label='選擇圖片尺寸',
choices=size_options['dall-e-3'],
value=size_options['dall-e-3'][0]
)
image_count=gr.Slider(
label='圖片張數 (DALL·E 2 專用)',
minimum=1,
maximum=10,
step=1,
value=1
)
submit_btn=gr.Button('開始生成')
gallery=gr.Gallery(label='生成的圖片')
status=gr.Textbox(label='狀態訊息', interactive=False) # 僅輸出
# 連動更新圖片尺寸選單
model_sel.change(
fn=update_size_options, # 呼叫自訂函式更新尺寸選單內容
inputs=model_sel, # 模型選單值
outputs=size_sel # 尺寸選單值
)
# 點擊按鈕觸發 handler
submit_btn.click(
fn=handler,
inputs=[api_key, prompt, model_sel, size_sel, image_count],
outputs=[gallery, status]
)
blocks.launch()
此 Gradio 應用程式中利用 gr.update() 函式來動態更新 gr.Radio 元件的選項內容, 當選擇模型時會改變尺寸選擇器的選項. 在 Streamlit 並無類似的函式, 但可以利用 st.session_state 紀錄即時的選項狀態, 當主選單之選擇變化時重新渲染副選單之選項, 作法參考下面這篇的範例 7 :
Streamlit 版的 OpenAI Image API 生圖網頁介面程式如下 :
# streamlit_openai_image_api_test_1.py
import streamlit as st
from openai import OpenAI
# 生圖主函式
def generate_images(prompt, api_key, **kwargs):
client=OpenAI(api_key=api_key)
replies=client.images.generate(prompt=prompt, **kwargs)
return [item.url for item in replies.data]
# UI 開始
st.set_page_config(page_title='OpenAI Image API 測試', layout='wide')
st.markdown('## 🎨 使用 DALL·E 2 / 3 生圖')
# 輸入金鑰與提示詞
api_key=st.text_input('請輸入金鑰 (API key)', type='password')
prompt=st.text_area('請輸入提示詞 (Prompt)', height=100)
# 圖片尺寸選項
size_options={
'dall-e-2': ['256x256', '512x512', '1024x1024'],
'dall-e-3': ['1024x1024', '1024x1792', '1792x1024']
}
# 初始化 session 狀態
if 'model_sel' not in st.session_state:
st.session_state.model_sel='dall-e-3'
if 'size_sel' not in st.session_state:
st.session_state.size_sel=size_options['dall-e-3'][0]
# 模型選單(更新尺寸選單)
model=st.radio(
'選擇模型',
['dall-e-2', 'dall-e-3'],
index=['dall-e-2', 'dall-e-3'].index(st.session_state.model_sel)
)
if model != st.session_state.model_sel:
st.session_state.model_sel=model
st.session_state.size_sel=size_options[model][0]
# 尺寸選單(依模型變化)
size_sel=st.radio(
'選擇圖片尺寸',
size_options[st.session_state.model_sel],
index=size_options[st.session_state.model_sel].index(st.session_state.size_sel)
)
st.session_state.size_sel=size_sel
# 圖片張數(僅限 dall-e-2)
image_count=1
if st.session_state.model_sel == 'dall-e-2':
image_count=st.slider('圖片張數 (DALL·E 2 專用)', 1, 10, value=1)
sel_msg=f'模型: {st.session_state.model_sel} 尺寸: {st.session_state.size_sel}'
st.write(sel_msg)
# 按送出按鈕開始生成圖片
if st.button('開始生成', type='primary'):
if not api_key.strip(): # 提醒必須輸入金鑰
st.warning('⚠ 請輸入 OpenAI API Key')
elif not prompt.strip(): # 提醒必須輸入提示詞
st.warning('⚠️ 請輸入提示詞 (Prompt)')
else:
n=image_count if st.session_state.model_sel == 'dall-e-2' else 1
with st.spinner('生成圖片中...'):
try:
urls=generate_images(prompt, api_key, model=st.session_state.model_sel, size=st.session_state.size_sel, n=n)
st.success(f'✅ 成功產生 {len(urls)} 張圖片。')
st.markdown(f'**模型**: {st.session_state.model_sel} **尺寸**: {st.session_state.size_sel} **張數**: {n}')
cols=st.columns(min(len(urls), 3))
for i, url in enumerate(urls):
with cols[i % len(cols)]:
st.image(url)
except Exception as e:
st.error(f'❌ 發生錯誤:{e}')
結果如下, 如果沒有輸入金鑰會出現提示訊息 :
輸入金鑰與下列提示詞 :
美麗的亞洲女性,優雅且高貴,柔和的自然光,細緻的五官,富有表情的雙眼配上自然的睫毛,光滑如瓷的肌膚,精緻的骨骼結構,自然的妝容,黑色亮麗的頭髮帶有柔和的波浪,神情寧靜,寫實風格,高解析度,專業人像攝影,淺景深,溫暖的色調,電影感燈光,傑作級品質,極致細緻。
用預設的 dall-e-3 模型生成 1024x1024 一張, 按生成鈕後 st.spinner 元件會在頁面顯示一個旋轉小圖表示正在生成圖片 :
當生成完畢時 st.spinner 元件會消失並展示生成之圖片 :
改選 dall-e-2 模型要求生成兩張 512x512 圖像 :
此 web app 我已佈署於 Hugging Face Spaces 平台 :






沒有留言 :
張貼留言