Why not login to Qiita and try out its useful features?

We'll deliver articles that match you.

You can read useful information later.

10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

streamlitのst.markdown()に画像を埋め込みたい

Last updated at Posted at 2023-06-20

目次

1. はじめに
2. やりたいこと
3. [失敗]普通のHTMLの記述方法で試してみる
4. [成功]streamlitのバージョンが1.18以上の場合
5. [成功]streamlitのバージョンが1.18未満の場合
6. おわりに

1. はじめに

streamlitというライブラリを利用するとPythonで簡単にWebアプリが開発できます。

streamlitについてはこちらの記事で説明しています。
streamlitを使ったお手軽Webアプリ開発

streamlitで作成したWebアプリのデザインを変更し、ページの見栄えを良くしたい場合、st.markdown()というモジュールを利用してHTMLを埋め込み、CSSスタイルを適用するという方法があります。

例えば、通常のstreamlitで"Hello World!"を出力する場合は以下のようなコードを書きます。

app.py
import streamlit as st

# "Hello World!"を表示
st.text("Hello World!")

このコードを実行して表示されるページは以下の画像のようになります。
image.png

次に、以下のコードのようにst.markdown()を利用してCSSスタイルを適用します。

app.py
import streamlit as st

# HTML埋め込み
st.markdown("""
    <style>
    .my-text {
        color: white;
        font-size: 24px;
        background-color: #008080;
        padding: 10px;
        border-radius: 10px;
    }
    </style>
    <p class='my-text'>Hello World!</p>
    """, unsafe_allow_html=True)

すると表示されるページは以下のようになります。
image.png

2. やりたいこと

CSSが適用できるといってもテキストだけだと味気ないので、st.markdown()の中に画像を埋め込もうと思います。
上の画像の"Hello World!"の下に画像を表示させます。
image.png

3. [失敗]普通のHTMLの記述方法で試してみる

今回はstreamlitのst.markdown()にstyleタグを埋め込んでスタイルを変更しています。
まずは、イメージの指定<img src="PATH_TO_IMAGE">を入れてみます。

app.py
import streamlit as st

# HTML埋め込み
st.markdown("""
    <style>
    .my-text {
        color: white;
        font-size: 24px;
        background-color: #008080;
        padding: 10px;
        border-radius: 10px;
    }
    </style>
    <p class='my-text'>Hello World!<br>
    <img src="image.png" height="150" width="150" style="vertical-align:middle;"></p>
    """, unsafe_allow_html=True)

修正後、アプリケーションを実行してみますが、画像は表示されませんでした。
image.png

どうやら普通のHTMLの記述では表示できないようです。

4. [成功]streamlitのバージョンが1.18以上の場合

streamlitのバージョン1.18以降に静的コンテンツを表示する機能が追加されているみたいです。
以下の手順で画像を表示することができます。

4.1. staticディレクトリを作成

streamlitのアプリケーションが動いているディレクトリの中にstaticディレクトリを作成します。

4.2. 画像ファイルの配置

作成したstaticディレクトリの中に画像ファイル(image.png)を入れます。
srcディレクトリの構成は以下のようになります。

src
├── app.py
└── static
    └── image.png

4.3. 実行コマンドに--server.enableStaticServing=trueをつける

  • 変更前
    $ streamlit run app.py --server.port=8501
    
  • 変更後
    $ streamlit run app.py --server.port=8501 --server.enableStaticServing=true
    

4.4. ファイルの呼び出しパスの変更

4.3で変更したコマンドでstreamlitを実行すると、staticディレクトリ内のディレクトリやファイルを./app/staticから呼び出すことができるようになります。

  • 変更前
    <img src="image.png" height="150" width="150" style="vertical-align:middle;">
    
  • 変更後
    <img src="./app/static/image.png" height="150" width="150" style="vertical-align:middle;">
    

変更後、無事画像を表示させることができました。
image.png

コード全体はこちらです。

app.py
import streamlit as st

# HTML埋め込み
st.markdown("""
    <style>
    .my-text {
        color: white;
        font-size: 24px;
        background-color: #008080;
        padding: 10px;
        border-radius: 10px;
    }
    </style>
    <p class='my-text'>Hello World!<br>
    <img src=".app/static/image.png" height="150" width="150" style="vertical-align:middle;"></p>
    """, unsafe_allow_html=True)

5. [成功]streamlitのバージョンが1.18未満の場合

streamlitのバージョンが1.18未満の場合、上記の方法では画像を表示させることができません。
その場合、以下の方法で表示させることができます。

5.1. 事前に画像を読み込む

streamlitで画像を表示させる前に画像を読み込みます。
読み込んだ画像はBase64でエンコードし、バイナリデータをテキストデータに変換します。

import base64
from pathlib import Path

image = "image.png"
image_bytes = Path(image).read_bytes()
image_encoded = base64.b64encode(image_bytes).decode()

5.2. 変換したテキストデータを埋め込む

変換したテキストデータをHTML記述の中に埋め込みます。

  • 変更前
    <img src="image.png" height="150" width="150" style="vertical-align:middle;">
    
  • 変更後
    # f-stringsで埋め込んでいます
    <img src="data:image/png;base64,{image_encoded}" height="150" width="150" style="vertical-align:middle;">
    

変更後、こちらの方法でも画像を表示させることができました。
image.png

コード全体はこちらです。

app.py
import streamlit as st
import base64
from pathlib import Path

image = "image.png"
image_bytes = Path(image).read_bytes()
image_encoded = base64.b64encode(image_bytes).decode()

# HTML埋め込み
st.markdown("""
    <style>
    .my-text {
        color: white;
        font-size: 24px;
        background-color: #008080;
        padding: 10px;
        border-radius: 10px;
    }
    </style>
    """
    + f"""
    <p class='my-text'>Hello World!<br>
    <img src="data:image/png;base64,{image_encoded}" height="150" width="150" style="vertical-align:middle;"></p>
    """, unsafe_allow_html=True)

6. おわりに

streamlitを使った画像の表示はst.image()で簡単にできますが、st.markdown()の中に画像を入れたい場合は本記事で紹介したような方法で実現することができます。

参考文献

10
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?