- Streamlitで何か作ってみたい方
- LLM APIを使ったWebアプリケーションを実装してみたい方
こんにちは、zawato(@zawato7)です!
今回は、Streamlitで画像にタイトルをつけるWebアプリケーションを実装してみたので、コードを解説したいと思います。
StreamlitでLLM APIを使ったWebアプリケーションを実装したいと考えている方は、是非参考にしてみてください。
2026年11月時点の主な変更点
- コードで使っている旧ライブラリ
google-generativeaiは2025年11月30日に非推奨となり、新しいgoogle-genaiへの移行が案内されています - モデル
gemini-1.5-flashは現在の公式モデル一覧にありません。gemini-3.8-flashなどに置き換えてください(書き換え例はコードの直後に補足しています) - Gemini APIは現在も無料枠で使えます。無料枠では、送信した内容がGoogleのサービス改善に使われます
Webアプリケーションの画面
今回、実装したWebアプリケーションのGUIは以下になります。

実装内容
GitHubにて、コードを公開してます。
環境
- Python 3.11.7
プログラムの全体像
今回、作成したコード(app.py)は以下になります。
import google.generativeai as genai
import requests
import streamlit as st
from PIL import Image
# Gemini APIを使用して画像のタイトルを取得する関数
def get_image_title(img):
"""
Gemini APIを使用して画像のタイトルを取得する関数
"""
try:
# Gemini APIの設定
genai.configure(api_key=API_KEY)
# モデルを選択
model = genai.GenerativeModel('gemini-1.5-flash')
# 画像を送信してタイトルを取得
response = model.generate_content([
"画像にふさわしいタイトルだけを出力してください。#出力例:画像のタイトル",
img
],
generation_config=genai.types.GenerationConfig(
# 温度パラメータの設定
temperature=temperature
),
stream=True)
response.resolve()
return response.text
except requests.exceptions.RequestException as e:
return f"エラーが発生しました: {e}"
# カスタムCSSを適用する関数
def load_css(file_name):
with open(file_name, "r") as f:
css = f.read()
st.markdown(f"<style>{css}</style>", unsafe_allow_html=True)
st.markdown('<h1 style="color: #022563">画像タイトル生成アプリ</h1>', unsafe_allow_html=True)
st.write("Gemini APIを使用して、アップロードされた画像のタイトルを生成します。")
# CSSを読み込む
load_css("styles.css")
# サイドバー
with st.sidebar.container():
### Gemini APIキーの入力
API_KEY = st.text_input('APIキー', placeholder='APIキーを入力してください', type="password")
### Tempperature
temperature = st.slider('Temperature', 0.0, 2.0, 1.0)
st.divider()
# タイトル
st.title("画像をアップロードしてください")
# 画像アップロード
uploaded_file = st.file_uploader("", type=["jpg", "jpeg", "png"])
if uploaded_file is not None:
# アップロードされた画像を表示
image = Image.open(uploaded_file)
st.image(image, caption="アップロードされた画像", width=400)
# タイトルの初回生成(セッションに保存)
if st.button("タイトル生成"):
with st.spinner("タイトルを生成中..."):
st.session_state.title = get_image_title(image)
# タイトルを表示
st.subheader("生成されたタイトル")
st.success(st.session_state.title)
※上のコードは記事作成時点の書き方(旧ライブラリ google-generativeai と gemini-1.5-flash)です。現在の書き方は、下の「画像からタイトルを生成する関数」の解説の後に補足しています。
プログラムの詳細
ここからは、プログラムの処理について詳しく紹介していきます。
今回は、Streamlitと呼ばれるPythonでWebアプリを簡単に作れるフレームワークを利用します。
また、今回は生成AIとして「Gemini」を利用します。こちら、無料でLLM APIを利用することができるので採用しました。
以下の記事にて、Geminiの概要とAPIの利用方法についてまとめていますので、APIキーを事前に取得しておいてください!
APIキーを取得できましたら、新規でpyファイルを作成します。
以下、コードの解説になります。
import google.generativeai as genai
import requests
import streamlit as st
from PIL import Image
まずは、必要なライブラリをインポートします。もし無い場合は、事前にインストールしてください。
※現在は、旧ライブラリ google-generativeai の代わりに pip install google-genai で新しいSDKを入れ、import google.generativeai as genai を from google import genai と from google.genai import types の2行に置き換えてください(公式のライブラリ案内)。
# Gemini APIを使用して画像のタイトルを取得する関数
def get_image_title(img):
"""
Gemini APIを使用して画像のタイトルを取得する関数
"""
try:
# Gemini APIの設定
genai.configure(api_key=API_KEY)
# モデルを選択
model = genai.GenerativeModel('gemini-1.5-flash')
# 画像を送信してタイトルを取得
response = model.generate_content([
"画像にふさわしいタイトルだけを出力してください。#出力例:画像のタイトル",
img
],
generation_config=genai.types.GenerationConfig(
# 温度パラメータの設定
temperature=temperature
),
stream=True)
response.resolve()
return response.text
except requests.exceptions.RequestException as e:
return f"エラーが発生しました: {e}"
こちらは、画像からタイトルを生成する関数です。
今回は画像を扱うため、マルチモーダルに対応した「Gemini-1.5-flash」モデルを採用しています。
※gemini-1.5-flash は現在の公式のモデル一覧にも廃止予定の一覧にも載っておらず、後の世代の gemini-2.0-flash も提供終了日が2026年6月1日とされています。現在は、画像入力に対応した安定版の gemini-3.8-flash などに置き換えてください。
Geminiのモデルについては以下の公式サイトを参照してみてください。
システムメッセージ(”画像にふさわしいタイトルだけを出力してください。#出力例:画像のタイトル”)は、目的に合わせて自由に変更してください。適切に設定することで回答精度を高めることができます。
※上記のコードは、GeminiのAPIとモデルを利用する想定のものですので、他の生成AIモデルやAPIを利用される方は適宜変更してください。おそらく、似たような書き方になるかと思います。
※新しいSDK(google-genai)では、関数の中身を次のように置き換えてください(公式の移行ガイド)。genai.configure(api_key=API_KEY) と genai.GenerativeModel('gemini-1.5-flash') の代わりに client = genai.Client(api_key=API_KEY) でクライアントを作ります。生成は response = client.models.generate_content(model="gemini-3.8-flash", contents=["画像にふさわしいタイトルだけを出力してください。#出力例:画像のタイトル", img], config=types.GenerateContentConfig(temperature=temperature)) と書き、return response.text で結果を返します。stream=True と response.resolve() は不要です(ストリーミングしたい場合は client.models.generate_content_stream を使います)。PILの画像はそのまま contents に渡せます。
# サイドバー
with st.sidebar.container():
### Gemini APIキーの入力
API_KEY = st.text_input('APIキー', placeholder='APIキーを入力してください', type="password")
### Tempperature
temperature = st.slider('Temperature', 0.0, 2.0, 1.0)
st.divider()
# タイトル
st.title("画像をアップロードしてください")
# 画像アップロード
uploaded_file = st.file_uploader("", type=["jpg", "jpeg", "png"])
Streamlitのサイドバーにて、APIキーを入力します。
type=”password”とすることで、入力ボックスがパスワードフィールドとなり、APIキーが隠れる仕様にしています。
また、Temperature(温度)と呼ばれる生成AIモデルの出力をコントロールするためのパラメータをスライドバーで設定します。温度が高いほどランダム性の高い出力結果が得られます。
そして、画像アップロード用のカスタムフィールドを配置します。
※st.file_uploader("", ...) のような空のラベルについて、Streamlitの公式ドキュメント(v1.66.0)は、アクセシビリティのため避けるよう案内しており、将来は例外にする可能性があるとしています。ラベルを表示したくない場合は st.file_uploader("画像ファイル", type=["jpg", "jpeg", "png"], label_visibility="collapsed") のように書いてください。
if uploaded_file is not None:
# アップロードされた画像を表示
image = Image.open(uploaded_file)
st.image(image, caption="アップロードされた画像", width=400)
# タイトルの初回生成(セッションに保存)
if st.button("タイトル生成"):
with st.spinner("タイトルを生成中..."):
st.session_state.title = get_image_title(image)
# タイトルを表示
st.subheader("生成されたタイトル")
st.success(st.session_state.title)
こちらでは、画像がアップロードされると、画面に画像と「タイトル生成」ボタンを表示します。
※st.image(image, caption="アップロードされた画像", width=400) は、現行のStreamlit(v1.66.0)でもそのまま使えます。画像を列の幅に合わせたい場合は、非推奨の use_container_width=True・use_column_width ではなく width="stretch" を指定します(st.imageの公式ドキュメント)。
ボタンが押されたら、実行メッセージを表示し、タイトルが生成されます。
もう一度ボタンを押すことで、再度タイトルを生成することができます。
動作確認
コンソール上で、streamlitを実行させます。
streamlit run app.py
すると、ブラウザに新しいタブが開かれ、Web画面が表示されます。

サイドバーに、APIキーを入力し、モデル・最大トークン数・Temperatureを設定しておきます。
次に、サイドバーのカスタムフィールドから、画像をアップロードしてします。
すると、メイン画面に画像とボタンが表示されるので、「タイトル生成」ボタンを押すと、

それっぽいタイトルが得られました。
何度か使ってみた感想ですが、画像によって回答精度は高かったり低かったりしました。
温度を変化させることで、バリエーションのあるタイトルが生成できるかなと思います。
無料で利用できますので、試しにアプリケーションを作る際には使い勝手が良いのではないかと思います。
※回答精度の感想は記事作成時点のモデル(Gemini 1.5 Flash)で試したものです。無料枠の対象モデルや条件は変わることがあるため、最新はGemini APIの料金ページで確認してください。
おわりに
今回は、Streamlitで画像からタイトルを生成する簡易的なWebアプリケーションを実装してみました。
LLM APIは、他にもいろいろな使い方ができると思うので、ぜひ一度実装してみてください。
実装してみた感想や改善点などがありましたら、是非コメントしてください!
また、チャットツールを実装した記事もあわせてみてみてください。
お問い合わせは、こちら!




コメント