この記事はこんな方にオススメ
  • 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は以下になります。

gen_title

実装内容

GitHubにて、コードを公開してます。

GitHub - zawato/groq_streamlit
Contribute to zawato/groq_streamlit development by creating an account on 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 モデル  |  Gemini API  |  Google AI for Developers
Gemini 2.5 Pro など、Google の最先端の AI モデルについて学ぶ

システムメッセージ(”画像にふさわしいタイトルだけを出力してください。#出力例:画像のタイトル”)は、目的に合わせて自由に変更してください。適切に設定することで回答精度を高めることができます。

※上記のコードは、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画面が表示されます。

gen_title

サイドバーに、APIキーを入力し、モデル・最大トークン数・Temperatureを設定しておきます。

次に、サイドバーのカスタムフィールドから、画像をアップロードしてします。 

すると、メイン画面に画像とボタンが表示されるので、「タイトル生成」ボタンを押すと、

gen_title

それっぽいタイトルが得られました。

何度か使ってみた感想ですが、画像によって回答精度は高かったり低かったりしました。

温度を変化させることで、バリエーションのあるタイトルが生成できるかなと思います。

無料で利用できますので、試しにアプリケーションを作る際には使い勝手が良いのではないかと思います。

※回答精度の感想は記事作成時点のモデル(Gemini 1.5 Flash)で試したものです。無料枠の対象モデルや条件は変わることがあるため、最新はGemini APIの料金ページで確認してください。

おわりに

今回は、Streamlitで画像からタイトルを生成する簡易的なWebアプリケーションを実装してみました。

LLM APIは、他にもいろいろな使い方ができると思うので、ぜひ一度実装してみてください。

実装してみた感想や改善点などがありましたら、是非コメントしてください!

また、チャットツールを実装した記事もあわせてみてみてください。

お問い合わせは、こちら!