新着情報
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宣言は以下の通りである。
8 9 10 11 | 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)画素を定義している。
13 14 15 16 17 18 19 20 | 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( )とを関係づける。
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #メニューバー 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)が貼り付けられた状態である。
20 21 22 23 24 | 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) 等としている理由である。
43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | #開く 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( )により、次のイベントまで待機が続くことになる。
1 2 3 4 | if __name__ = = '__main__' : root = Window() root.pack() root.mainloop() |
参考文献:
http://www.shido.info/py/tkinter_a1.html