In the previous article, I introduced ** Tkinter template **. In this article, I will introduce how to create an Image Viewer application based on this template.
Windows 10 64 bit Python 3.7 IDE : Pycharm
The following figure shows a ponchi-e of the Image Viewer application created this time. .. The only function of this application is to select an image file and display that image. Then, add the function to turn off the display screen and the function to close the application.
`The person in the picture is Professor Ralph, an authority on immunology in the United States. ``
The following figure shows the layout of the Image Viewer.
Prepare Widget **, which is a ** part of the application. 1.Canvas Widget: A box for displaying Images. 2.Label Frame Widget: Prepare three buttons, but a box to put those buttons together. 3.Button: Three buttons: Load Image, Clear Image, Quit Application.
Use the grid method to place each widget.
** This is the template program code introduced in Tkinter Templated Article.
Template configuration
In this template, ** assemble the code by the procedure of setting and arranging the widget described in the previous chapter and filling in the Event Callback function. ** (framework → flesh)
import tkinter as tk
from tkinter import ttk
class Application(tk.Frame):
def __init__(self,master):
super().__init__(master)
self.pack()
self.master.geometry("300x300")
self.master.title("Tkinter with Class Template")
self.create_widgets()
def create_widgets(self):
pass
def callBack(self):
pass
def main():
root = tk.Tk()
app = Application(master=root)#Inherit
app.mainloop()
if __name__ == "__main__":
main()
Set and place Canvas Widget in the create_widgets method part of Class Application. Use the Grid method for placement.
def create_widgets(self):
#Canvas
self.canvas1 = tk.Canvas(self)
self.canvas1.configure(width=640, height=480, bg='orange')
self.canvas1.create_rectangle(0,0,120, 70, fill='green')
self.canvas1.grid(column=1, row=0)
self.canvas1.grid(padx=20, pady=20)
3.2.File Open -> Image Load
This is the part that opens the file and loads the Image file.
After setting the Button, define the loadImage () of the Event Callback function.
The if statement inside LoadImage () was added to see the aspect ratio of the image and resize the original image to fit the size of the Canvas.
Then, as the conversion of the image file, the part of RGB conversion of openCV, conversion to PIL, and conversion to imageTK continues.
Finally, use self.canvas1.create_image
to display the image in the Canvas Widget.
def create_widgets(self):
#File open and Load Image
self.button_open = ttk.Button(self.frame_button)
self.button_open.configure(text = 'Load Image')
self.button_open.grid(column=0, row=1)
self.button_open.configure(command=self.loadImage)
# Event Call Back
def loadImage(self):
self.filename = filedialog.askopenfilename()
self.image_bgr = cv2.imread(self.filename)
self.height, self.width = self.image_bgr.shape[:2]
if self.width > self.height:
self.new_size = (640,480)
else:
self.new_size = (480,480)
self.image_bgr_resize = cv2.resize(self.image_bgr, self.new_size, interpolation=cv2.INTER_AREA)
self.image_rgb = cv2.cvtColor( self.image_bgr_resize, cv2.COLOR_BGR2RGB ) #Since imread is BGR, it is converted to RGB
self.image_PIL = Image.fromarray(self.image_rgb) #Convert from RGB to PIL format
self.image_tk = ImageTk.PhotoImage(self.image_PIL) #Convert to ImageTk format
self.canvas1.create_image(320,240, image=self.image_tk)
The figure below is the image captured when opening the file. To use this feature, use filedialog.askopenfilename ()
.
However, if the folder name contains Japanese characters (UTF-8), an error will occur. This time, please make the folder name where the image file is stored in English. (If you know how to solve this problem, please leave a message.)
It is a function to turn off the screen on Canvas. Use the canvas.delete ()
method.
def clearImage(self):
self.canvas1.delete("all")
At the end, the MessageBox is displayed and the user's judgment is confirmed again as "Are you sure you want to end?"
def quit_app(self):
self.Msgbox = tk.messagebox.askquestion("Exit Applictaion", "Are you sure?", icon="warning")
if self.Msgbox == "yes":
self.master.destroy()
else:
tk.messagebox.showinfo("Return", "you will now return to application screen")
The figure below shows the screen when the MessageBox is displayed.
The following figure shows the execution result. It was confirmed that it works as designed. I was able to confirm that Clear Image and Quit are also OK.
import tkinter as tk
from tkinter import ttk
import sys
import os
from tkinter import *
from tkinter import messagebox,filedialog
import numpy as np
from PIL import Image, ImageTk
import cv2
# coding: utf-8
#I couldn't put Japanese characters in the Folder name.
class Application(tk.Frame):
def __init__(self,master):
super().__init__(master)
self.pack()
self.master.geometry("800x600")
self.master.title("Tkinter with Class Template")
self.create_widgets()
def create_widgets(self):
#Canvas
self.canvas1 = tk.Canvas(self)
self.canvas1.configure(width=640, height=480, bg='orange')
self.canvas1.create_rectangle(0,0,120, 70, fill='green')
self.canvas1.grid(column=1, row=0)
self.canvas1.grid(padx=20, pady=20)
#Frame
self.frame_button = ttk.LabelFrame(self)
self.frame_button.configure(text=' Button Frame ')
self.frame_button.grid(column=1,row=1)
self.frame_button.grid(padx=20, pady=20)
#File open and Load Image
self.button_open = ttk.Button(self.frame_button)
self.button_open.configure(text = 'Load Image')
self.button_open.grid(column=0, row=1)
self.button_open.configure(command=self.loadImage)
# Clear Button
self.button_clear = ttk.Button( self.frame_button )
self.button_clear.configure( text='Clear Image' )
self.button_clear.grid( column=1, row=1 )
self.button_clear.configure(command=self.clearImage)
# Quit Button
self.button_quit = ttk.Button( self.frame_button )
self.button_quit.config( text='Quit' )
self.button_quit.grid( column=2, row=1 )
self.button_quit.configure(command = self.quit_app)
# Event Call Back
def loadImage(self):
#self.folder_name = filedialog.askdirectory()
self.filename = filedialog.askopenfilename()
#print(self.folder_name)
print(self.filename)
self.image_bgr = cv2.imread(self.filename)
self.height, self.width = self.image_bgr.shape[:2]
print(self.height, self.width)
if self.width > self.height:
self.new_size = (640,480)
else:
self.new_size = (480,480)
self.image_bgr_resize = cv2.resize(self.image_bgr, self.new_size, interpolation=cv2.INTER_AREA)
self.image_rgb = cv2.cvtColor( self.image_bgr_resize, cv2.COLOR_BGR2RGB ) #Since imread is BGR, it is converted to RGB
# self.image_rgb = cv2.cvtColor(self.image_bgr, cv2.COLOR_BGR2RGB) #Since imread is BGR, it is converted to RGB
self.image_PIL = Image.fromarray(self.image_rgb) #Convert from RGB to PIL format
self.image_tk = ImageTk.PhotoImage(self.image_PIL) #Convert to ImageTk format
self.canvas1.create_image(320,240, image=self.image_tk)
def clearImage(self):
self.canvas1.delete("all")
def quit_app(self):
self.Msgbox = tk.messagebox.askquestion("Exit Applictaion", "Are you sure?", icon="warning")
if self.Msgbox == "yes":
self.master.destroy()
else:
tk.messagebox.showinfo("Return", "you will now return to application screen")
def main():
root = tk.Tk()
app = Application(master=root)#Inherit
app.mainloop()
if __name__ == "__main__":
main()
Recommended Posts