Eel を使うと Python から HTML を呼んだり、その逆で HTML から Python を呼び出すことができます。
今回はその Eel を使って、Python で読み込んだ画像データを HTMLに送って画面に表示したり、表示してある画像を Python に送って OpenCV でグレースケール化して戻すってことをやってみたいと思います。

環境
- Windows 10 Home 21H1
- Python 3.8.10
- Eel 0.14.0
- opencv-python 4.5.2.54
- vue 1.0.2
ソースコード
実際に動くソースコードは GitHub に上げてあるので、ここでは要点だけ説明します。
Python 実行時に HTML を表示する処理
Python
import asyncio
import eel
async def main():
eel.init('web')
eel.start('index.html', port=0, size=(450, 560))
pass
if __name__ == '__main__':
try:
asyncio.run(main())
except Exception:
pass
「web」フォルダ内の「index.html」を開くように設定しています。
画像読み込み時の処理
Javascript
async get_img() {
// Pythonから画像データ(Base64文字列)を読み込む
const img_base64 = await eel.get_img()();
// 画面に表示
this.img_src = 'data:image/png;base64,' + img_base64;
},
「eel.get_img」でPython を呼び出しています。
Python
@eel.expose
def get_img():
# ファイルを開くダイアログの表示
filename = filedialog.askopenfilename(
title="画像ファイルを開く",
filetypes=[("Image file", ".bmp .png .jpg .tif")],
initialdir="./"
)
# 画像ファイルを開いてbase64に変換
with open(filename, 'br') as f1:
img_base64 = base64.b64encode(f1.read())
# base64を文字列で返却
return img_base64.decode()
画像を Base64 に変換して、Base64の文字列を HTML に返却しています。
グレースケール化時の処理
Javascript
async gray_scale() {
let img = this.img_src;
img = img.replace('data:image/png;base64,', '');
// Pythonでグレースケール変換
const img_base64 = await eel.gray_scale(img)();
// 画面に表示
this.img_src = 'data:image/png;base64,' + img_base64;
}
画面から Base64文字列の画像を取得して、Python に渡しています。
そして、戻ってきた画像データを再度画面に表示しています。
Python
@eel.expose
def gray_scale(img_str: str):
# バリナリデータ <- Base64文字列
img_binary: bytes = base64.b64decode(img_str)
# バイナリーストリーム <- バリナリデータ
img_binarystream: io.BytesIO = io.BytesIO(img_binary)
# PILイメージ <- バイナリーストリーム
img_pil: Image = Image.open(img_binarystream)
# numpy配列(RGBA) <- PILイメージ
img_numpy: np.ndarray = np.asarray(img_pil)
# numpy配列(GRAY) <- numpy配列(RGBA)
img_gray: np.ndarray = cv2.cvtColor(img_numpy, cv2.COLOR_RGBA2GRAY)
# Base64 <- numpy配列(GRAY)
result, dst_data = cv2.imencode('.png', img_gray)
img_base64: bytes = base64.b64encode(dst_data)
# base64を文字列で返却
return img_base64.decode()
受け取った Base64文字列を画像に変換してから、OpenCV を使ってグレースケール化し、再度Base64文字列に変換してHTMLに返却しています。