mieki256's diary



2020/03/04(水) [n年前の日記]

#1 [python] PySimpleGUIを使って画像表示

せっかく Python + PySimpleGUI を触ったことだし、せめて画像表示できるところまで試してみようかと。

環境は、Windows10 x64 1909 + Python 3.7.6 32bit + PySimpleGUI 4.16.0 + Pillow 7.0.0。

_PySimpleGUI/DemoPrograms の中に、 _PySimpleGUI/Demo_Img_Viewer.py というデモスクリプトがあるのでソレを参考に。件のスクリプトは、指定したフォルダ内の画像ファイルをリスト表示して、選択すると画像を表示するスクリプトだけど、自分の場合は単に画像ファイルを1ファイル指定して表示するようにしてみたり。

こんな感じになった。

myimgviewer_ss.png

ソース。 :

_myimgviewer.py
import PySimpleGUI as sg
from PIL import Image, ImageTk
import io
import sys
# import os

img_types = (".png", ".jpg", "jpeg", ".tiff", ".bmp")

status_text = ''
fname = None
if not len(sys.argv) == 1:
    fname = sys.argv[1]

if fname:
    if not fname.lower().endswith(img_types):
        sg.popup("Cancel", fname + " is Not image file")
        raise SystemExit("Canceling: Not image file")


def get_img_data(f, maxsize=(1200, 850), first=False):
    """Generate image data using PIL."""
    global status_text
    im = Image.open(f)
    status_text = "%d x %d" % im.size  # original image size
    im.thumbnail(maxsize)
    status_text += " (%d x %d)" % im.size  # thumbnail image size
    if first:
        bio = io.BytesIO()
        im.save(bio, format="PNG")
        del im
        return bio.getvalue()
    return ImageTk.PhotoImage(im)


# layout
firstfg = True
if fname:
    image_elem = sg.Image(data=get_img_data(fname, first=firstfg))
    fname_elem = sg.InputText(size=(80, 1), enable_events=True,
                              default_text=fname)
    firstfg = False
else:
    image_elem = sg.Image()
    fname_elem = sg.InputText(size=(80, 1), enable_events=True)
status_elem = sg.Text(key='-STATUS-', size=(64, 1))

layout = [
    [fname_elem, sg.FileBrowse(key='-FILENAME-')],
    [status_elem],
    [image_elem]
]

# create window
window = sg.Window('Image Viewer', layout, return_keyboard_events=True,
                   location=(0, 0), use_default_focus=False)

# event loop
while True:
    event, values = window.read()
    if event in (None, 'Exit'):
        break

    if values['-FILENAME-'] != '':
        # filename select
        fname = values['-FILENAME-']
        if fname.lower().endswith(img_types):
            # load image
            image_elem.update(data=get_img_data(fname, first=firstfg))
            fname_elem.update(fname)
            status_elem.update(status_text)
            firstfg = False

window.close()

以下で実行。
python myimgviewer.py
or
python myimgviewer.py hoge.png

ハマったところは、ファイル選択処理部分。FileBrowse というエレメント(?)を用意すれば、ウインドウ上では「Browse」というボタンが表示されて、そのボタンをクリックするとファイル選択ができるのだけど。その選択されたファイルパスをどうやって取得するのかが分からなくて。

ひたすらググってみた感じでは、イベントループ内で、values[] の中にファイルパスが入ってくる瞬間が、ファイル選択された時、みたいな感じで…。

ということで、FileBrowse() を用意する際に key='-FILENAME-' を指定しておいて、後に、イベントループの中で、values['-FILENAME-'] の中身が空じゃないかチェックして、空じゃなければ画像ファイルが選択された時だから画像ファイルを読み込んで更新、てな感じに。

とりあえず、PySimpleGUI を使って画像表示はできたから、画像を読み込んで何か処理をして結果をプレビュー、といったスクリプトなら書けそうかなと…。

本当は、エクスプローラ等からD&D(ドラッグアンドドロップ)してファイルを開けたらいいのだけれど。tkinter にそんな機能は無いので、それはちょっと無理っぽい。tkinter を使う PySimpleGUI ではなく、おそらくは Qt を使う PySimpleGUIQt なら可能らしいけど…。

以上です。

過去ログ表示

Prev - 2020/03 - Next
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project