LoginSignup
2
2

More than 1 year has passed since last update.

【Dash(python)】table に画像を挿入する

Last updated at Posted at 2021-06-03

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. 結果

スクリーンショット 2021-06-03 23.08.08.png

参考

2
2
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
2
2