新着情報

1-1-(a) GUI画像表示プログラムの補足説明

(1a) GUI画像表示プログラム(showGUIimage.py)の補足説明
ここで showGUIimage.py の各部分について補足説明を行う。

① まず、Pythonプログラムに必要な各種のライブラリ・モジュールのimport宣言を行う。

tkinter のライブラリ・モジュールを全てimportする。

次に、tkinterから対話的に対象とする画像ファイルを選択するために必要なfiledialogと

ブログラム終了の時に確認するメッセージを提示する時に必要なmessageboxを明示的にimportする。

Python3用の画像ライブラリPillowからImageとImageTkをimportする。

しかし、この場合もPilow Image Libraryの頭文字はPILなので、Python2の時と同様に

from PIL import Image, ImageTk と記述することに注意する。

今後において、GUI画像処理システム開発を想定しているので、画像処理ライブラリ・モジュールOpenCV

バージョン3をimportする。

OpenCVのバージョン3をimportするのに、import cv3ではなくて、バージョン2の時と同様にimport cv2 と記述することにも注意する。

必要なライブラリのimport宣言は以下の通りである。

from tkinter import *
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
import cv2

② 画像を表示する画面枠としてクラスWindowを定義し、その引数にtkinterモジュールのクラスFrame Widgetを取る。即ち、FrameクラスはWindowクラスの上位クラスとなる。

Frame Widgetはtkinterモジュールが提供するGUI部品のLabel WidgetやButton Widgetなど

他のWidgetをまとめて配置可能である。

ここでは、クラスWindowのコンストラクタ定義(初期値化) def __init__ 中で、

上位のクラスFrameを明示的にコンストラクタ定義することにより、

WindowクラスはFrameクラスをすべて継承してることになる。

また、Windowクラスの窓枠全体のタイトルや窓枠の最低サイズ(500,500)画素を定義している。

class Window(Frame):# クラス Window(Frame)の定義
    def __init__(self,master=None):# クラス Window()のコン
                                   # ストラクタ
        #フレーム
        Frame.__init__(self, master)# 上位クラス Frame の
                                    #  コンストラクタ
        self.master.title('画像表示')
        self.master.minsize(500,500)

③ menu_barをクラスWindowに関連付け、親メニューファイル(F)と、’開く’, ‘保存’、’終了’の3通りの

子メニューを想定し、これら子メニューとイベント関数def quit( ), def open( ), def save( )とを関係づける。


        #メニューバー
        self.menu_bar = Menu(self.master)
        self.master.config(menu=self.menu_bar)
        self.menu_file = Menu(self.menu_bar,tearoff = 0)
 
        self.menu_file.add_command(label='開く­', command=self.open, underline=3, accelerator = 'Ctrl-O')
        self.menu_file.add_command(label='保存', command=self.save, underline=5, accelerator = 'Ctrl-S')
        self.menu_file.add_command(label='終了', command=self.quit, underline=5, accelerator = 'Ctrl-Q')
        self.menu_bar.add_cascade(label='ファイル(F)', menu=self.menu_file,  underline=5)

    #終了
    def quit(self):
       if messagebox.askokcancel('Confirm Closing', 'Are you sure you want to close?'):
         self.master.destroy()
    #開く
    def open(self):
          global filename
          global size
          size=300,300
          filename = filedialog.askopenfilename()
          if filename != "":
            im = Image.open(filename)
            im.thumbnail(size, Image.ANTIALIAS)
          if im.mode == '1': # bitmap image
            self.image = ImageTk.BitmapImage(im)
          else:              # photo image
            self.image = ImageTk.PhotoImage(im)
          self.la.config(text='Original Image',image=self.image,
                         width=self.image.width(), height=self.image.height(),compound='top')
    #保存
    def save(self):
        global filename
        global filename2

        cv2.imwrite('result.jpg',filename2)
        

④ クラスLabel Widget のインスタンス変数self.la を定義する[行23-24]。クラスWindow枠内の左上から横へ100画素、下へ100画素の場所にLabel Widgetを配置する。Label Widget内に画像表示の領域として(300,300)画素サイズを準備する。画像はまだ選択されていないので、bg=バックグランドカラー(#44aaaa)が貼り付けられた状態である。

        
        self.image1 = PhotoImage()

        #ラベル1
        self.la = Label(self,image=self.image1,bg="#44aaaa",width=300, height=300)
        self.la.pack(side=LEFT,padx=100, pady=100)

⑤ イベント関数 def open (self)に関して[行43~58]、filename=filedialog.askopenfilename( )によって、ファイル選択のためのダイアログ画面が表示され、表示したい画像ファイル名を対話的に選択可能となる。対象画像ファイルは白黒ビットマップ画像の場合はBitmapImage( )関数によって、また、カラー画像の場合はPhotoImage( )関数によってLabel ,Text, Button, Canvas Widgetに添付可能なImageクラスに変換する必要がある。このImageクラス変数の値はインスタンス変数(self.image)に代入する必要がある。これをしないと、関数から出る時、変数のメモリーが 回収されるため、画像が消えてしまう。これが、文中で self.image1=ImageTk.Bitmap(im)、或いは self.image1=ImageTk.PhotoImage(im) 等としている理由である。


    #開く
    def open(self):
          global filename
          global size
          size=300,300
          filename = filedialog.askopenfilename()
          if filename != "":
            im = Image.open(filename)
            im.thumbnail(size, Image.ANTIALIAS)#画像サイズを縮小する
            print(im.mode)
          if im.mode == '1': # 白黒bitmap imageの場合
            self.image1 = ImageTk.BitmapImage(im)
          else:              # photo image .png,.jpgなどの拡張子の場合
            self.image1 = ImageTk.PhotoImage(im)
          self.la.config(text='Original Image',image=self.image1,
                         width=self.image1.width(), height=self.image1.height(),compound='top')

⑥ 最後の部分[行65~68]についての説明である。プログラムが実行されると、__name__

の値は__main__になるので、if  __name__ == ‘__main__’: は成立し、以下の3つの文が実行される。

root = Window( ) により、Windowクラスのインスタンスrootが作られ、root.pack( )により画面上にインスタンスrootが配置される。そして、root.mainloop( )により、次のイベントまで待機が続くことになる。


if __name__ == '__main__':
    root = Window()
    root.pack()
    root.mainloop()

参考文献:

http://www.shido.info/py/tkinter_a1.html

コメント投稿フォーム

メールアドレスが公開されることはありません。 が付いている欄は必須項目です