iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 8
0
自我挑戰組

軟體開發隨筆雜記--試著解決問題系列 第 8

如何做一個簡易相簿(1)

https://ithelp.ithome.com.tw/upload/images/20200923/20119608C3lwW3TMeg.png
做一個類別class ImageViewer()並初始化:

def __init__(self, master):
    self.parent = master

上一頁和下一頁的功能和左右鍵綁定再一起:

    self.parent.bind("<Left>", self.prev)
    self.parent.bind("<Right>", self.next)

執行init_imageviewerUI部分

    self.init_imageviewer()

定義init_imageviewerUI部分

def init_imageviewer(self):
    self.image_paths = list() # image abs_paths
    # 目錄
    self.root_dir = None
    self.image_dir = None

    self.image_tk = None # showing tkimage
    self.image_idx = 0 # current image idex
    self.image_cnt = 0 # num of image
    self.image_cur_id = None # showing tkimage id

    # 主面板
    self.mframe = tk.Frame(self.parent)
    self.mframe.pack(fill=tk.BOTH, expand=1)

    # 圖像面板
    self.iframe = tk.Frame(self.mframe)
    self.iframe.pack()
    self.image_canvas = tk.Canvas(self.iframe,
                                  width=self.CANVAS_WIDTH, 
                                  height=self.CANVAS_HEIGHT,
                                  cursor='plus')
    #y-move
    image_Canvas_sbarV = tk.Scrollbar(self.iframe, orient=tk.VERTICAL)
    #x-move
    image_Canvas_sbarH = tk.Scrollbar(self.iframe, orient=tk.HORIZONTAL)
    image_Canvas_sbarV.config(command=self.image_canvas.yview)
    image_Canvas_sbarH.config(command=self.image_canvas.xview)
    self.image_canvas.config(yscrollcommand=image_Canvas_sbarV.set)
    self.image_canvas.config(xscrollcommand=image_Canvas_sbarH.set)
    image_Canvas_sbarV.pack(side=tk.RIGHT, fill=tk.Y)
    image_Canvas_sbarH.pack(side=tk.BOTTOM, fill=tk.X)
    # 圖像面板收尾
    self.image_canvas.pack(pady=0, anchor=tk.N)

    # 控制面板
    self.cframe = tk.Frame(self.mframe)
    self.cframe.pack(side=tk.TOP, padx=5, pady=10)
    self.prev_button = ttk.Button(self.cframe, 
                                  text="<<", 
                                  width=10, 
                                  command=self.prev)
    self.prev_button.pack(side = tk.LEFT, padx=5)
    self.next_button = ttk.Button(self.cframe,
                                  text=">>",
                                  width=10,
                                  command=self.next)
    self.next_button.pack(side = tk.LEFT, padx=5)

    # 狀態面板
    self.sframe = tk.Frame(self.mframe)
    self.sframe.pack(side=tk.TOP, padx=5, pady=10)
    self.status_label = ttk.Label(self.sframe,
                                 text="{:3d}/{:3d}".format(0,0),
                                 width=10,
                                 anchor=tk.CENTER)
    self.status_label.pack(side = tk.LEFT, padx=5)
    

上一張功能

def prev(self, event=None):
    if self.image_cnt == 0:
        return
    if 0 < self.image_idx:
        self.image_idx -= 1
        #3.9)
        self.show_image(self.image_idx)

下一張功能

def next(self, event=None):
    if self.image_cnt == 0:
        return
    if self.image_idx < (self.image_cnt-1):
        self.image_idx += 1
        #3.9)
        self.show_image(self.image_idx)

更新圖片狀態

def update_imagestatus(self):
    if self.image_cnt != 0:
        self.status_label.configure(text="{:3d}/{:3d}".format(self.image_idx+1,self.image_cnt))
    else:
        self.status_label.configure(text="{:3d}/{:3d}".format(0,0))

顯示圖片

def show_image(self, idx):
    if idx < 0 or idx >= self.image_cnt:
        raise ValueError("imageidx invalid")

    image_cv = cv2.imread(self.image_paths[idx],cv2.IMREAD_UNCHANGED )
    image_cv = cv2.cvtColor(image_cv, cv2.COLOR_BGR2RGB)
    image_pil = Image.fromarray(image_cv)
    self.image_tk = ImageTk.PhotoImage(image_pil)
    w, h = image_pil.size
    self.image_canvas.config(scrollregion=(0,0,w,h))
    disp_x = disp_y = 0
    self.image_cur_id = self.image_canvas.create_image(disp_x, disp_y,
                                                       image=self.image_tk,
                                                       anchor=tk.NW)
    self.update_imagestatus()

打開圖片資料夾功能

def open_dir(self):
    self.root_dir = tkfd.askdirectory()
    self.image_dir = self.root_dir
    if self.image_dir == "":
        return
    if not os.path.exists(self.image_dir):
        tkmsg.showwarning("Warning", message="{} doesn't exist.".format(self.image_dir))
        return
    if not os.path.isdir(self.image_dir):
        tkmsg.showwarning("Warning", message="{} isn't dir.".format(self.image_dir))
        return
    self.image_paths = list()
    accepted_ext = (".jpeg", '.jpg', '.png')
    for ext in accepted_ext:
        self.image_paths.extend(glob.glob(os.path.join(self.image_dir, "*"+ext)))
    image_cnt = len(self.image_paths)
    if image_cnt == 0:
        tkmsg.showwarning("Warning", message="image doesn't exist.")
        return
    self.image_idx = 0
    self.image_cnt = image_cnt
    self.show_image(self.image_idx)

https://ithelp.ithome.com.tw/upload/images/20200915/20119608oQz63W0FND.jpg


上一篇
如何顯示視訊串流在label物件上
下一篇
如何做一個簡易相簿(2)
系列文
軟體開發隨筆雜記--試著解決問題34

尚未有邦友留言

立即登入留言