1. 概要
Dash のテーブルに画像を挿入したいときありますよね!
Dash に関する記事があまりなく、かつテーブルに画像を挿入する方法もググってもなかったので記事にしておきます。
2. 実装
紹介する方法では、テーブルの元となる pd.DataFrame を作成し、そこへ html.IMG を挿入するという方法です。この際、画像はbase64でエンコードをする必要があります。少々乱暴ではありますが、一番手っ取り早くできました。
"百聞は一見に如かず" ということでサンプルコードを載せておきます(※画像へのパスを変更すれば動作することを確認していますので試してみてください)。
# __feture__
from __future__ import annotations
# 組み込み
import os
import base64
# サードパーティ
import dash
import pandas as pd
import dash_html_components as html
import dash_bootstrap_components as dbc
def get_media_type(ext: str) -> str:
"""拡張子からメディアタイプを取得する
Args:
ext (str): 画像の拡張子。ex) ".xxx"
"""
media_type_dict = {
".jpeg": "data:image/jpeg;base64",
".jpg": "data:image/jpeg;base64",
".gif": "data:image/gif;base64",
".png": "data:image/png;base64",
".svg": "data:image/svg+xml;base64",
}
try:
return media_type_dict[ext]
except KeyError:
raise KeyError(f"Not Support Extention → '{ext}'")
def local_img_to_base64(path: str) -> bytes:
"""ローカルの画像をbase64にエンコード"""
with open(path, "rb") as f:
img_base64 = base64.b64encode(f.read())
return img_base64
def base64_to_img_tag(img_base64: bytes, ext: str, height: str = "100px", width: str = "200px") -> html.Img:
"""base64からimg_tagを生成する
Args:
img_base64 (bytes): base64。
ext (str): 拡張子. ec) .png
height (str, optional): 画像の縦幅. Defaults to "100px".
width (str, optional): 画像の横幅. Defaults to "200px".
Returns:
html.IMG.IMG: 生成したimg_tag.
"""
img_binary = img_base64.decode()
media_type = get_media_type(ext)
img_tag = html.Img(
src=f"{media_type},{img_binary}",
height=height,
width=width,
)
return img_tag
def local_img_to_tag(path: str, height: str = "30vh", width: str = "30vh") -> html.Img:
"""ローカルにある画像
Args:
path (str): img_tagに変換する画像へのpath
height (str, optional): 変換後のheight. Defaults to "30vh".
width (str, optional): 変換後のwidth. Defaults to "30vh".
Returns:
html.IMG.IMG: 作成したIMGタグ。
"""
_, ext = os.path.splitext(path.split("/")[-1])
img_base64 = local_img_to_base64(path)
img_tag = base64_to_img_tag(img_base64, ext, height=height, width=width)
return img_tag
def make_table():
path = "the_carp_boy.jpeg"
df = pd.DataFrame({'広島': ["梵", "東出", "栗原", "新井", "嶋", "緒方", "廣瀬", "倉", "黒田"],
"巨人": ["高橋由", "谷", "小笠原", "李承燁", "ゴンザレス", "阿部", "小坂", "鈴木尚", "内海"]})
img_list = [local_img_to_tag(path) for _ in range(df.shape[0])]
df.insert(0, "img", img_list)
table = dbc.Table.from_dataframe(
df,
className='table-scroll',
striped=True,
bordered=True,
hover=True,
)
return table
app = dash.Dash(__name__)
app.layout = make_table()
app.run_server(debug=True)
3. 結果
参考