Eel を使うと Python から HTML を呼んだり、その逆で HTML から Python を呼び出すことができます。
今回はその Eel を使って、Python で読み込んだ画像データを HTMLに送って画面に表示したり、表示してある画像を Python に送って OpenCV でグレースケール化して戻すってことをやってみたいと思います。
環境
ソースコード
実際に動くソースコードは GitHub に上げてあるので、ここでは要点だけ説明します。
Python 実行時に HTML を表示する処理
Python
1 2 3 4 5 6 7 8 9 10 11 12 13
| 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
1 2 3 4 5 6 7
| 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| @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
1 2 3 4 5 6 7 8 9 10
| 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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| @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に返却しています。