2017-05-03 110 views
0

我正在嘗試編寫一個腳本,允許用戶選擇一個包含圖像的文件夾,然後在每個圖像上保存用戶點擊的座標。爲此,我想在Tkinter畫布上顯示每個圖像文件,保存點擊位置,然後在畫布關閉時打開下一個圖像。使用Tkinter畫布在Python中循環顯示圖像

我可以用下面的代碼(改編自this question)得到這個圖像。我希望for File in imgs循環將繼續打開下一個圖像,但它不會。我懷疑我需要一個on_closing函數來告訴Tkinter打開另一個圖像。

什麼是正確的方式讓Tkinter關閉圖像後打開下一張圖片?

from Tkinter import * 
from tkFileDialog import askopenfilenames, askopenfilename, askdirectory 
from PIL import Image, ImageTk 
import cv2 
import numpy as np 
import os 

if __name__ == "__main__": 
    root = Tk() 

    #setting up a tkinter canvas with scrollbars 
    frame = Frame(width=1920, height=1080, bd=2, relief=SUNKEN) 
    frame.grid_rowconfigure(0, weight=1) 
    frame.grid_columnconfigure(0, weight=1) 
    xscroll = Scrollbar(frame, orient=HORIZONTAL) 
    xscroll.grid(row=1, column=0, sticky=E+W) 
    yscroll = Scrollbar(frame) 
    yscroll.grid(row=0, column=1, sticky=N+S) 
    canvas = Canvas(frame, bd=0, xscrollcommand=xscroll.set, yscrollcommand=yscroll.set) 
    canvas.config(width=1920, height=1080) 
    canvas.grid(row=0, column=0, sticky=N+S+E+W) 
    xscroll.config(command=canvas.xview) 
    yscroll.config(command=canvas.yview) 
    frame.pack(fill=BOTH,expand=1) 

    # Function to be called when mouse is clicked 
    def save_coords(event): 
     coords.append([event.x, event.y]) 

    # def on_closing(): 
     # Open the next image file 


    # Create empty list for coordinate arrays to be appended to 
    coords = [] 

    # Choose multiple images 
    img_dir = askdirectory(parent=root, initialdir="D:/Temp/", title='Choose folder') 
    os.chdir(img_dir) 
    imgs = os.listdir(img_dir) 
    #imgs = askopenfilenames(parent=root, initialdir="D:/Temp/cvCal/", title='Choose images') 
    for File in imgs: 
     img = ImageTk.PhotoImage(Image.open(File).resize((1280,720), Image.ANTIALIAS)) 
     canvas.create_image(0,0,image=img,anchor="nw") 
     canvas.config(scrollregion=canvas.bbox(ALL)) 
     canvas.bind("<Button 1>",save_coords) 
     # on_closing()... 

    root.mainloop() 
+0

爲什麼要用Canvas而不是Label來顯示圖像?你需要圖像滾動嗎? – Novel

+0

它不需要滾動,我只需要獲取點擊位置。我從來沒有使用過標籤小部件,所以我對你的問題並沒有很好的答案,但我願意接受建議。 – Bird

回答

1

這將是一個容易得多,如果你可以用一個標籤來代替:

另外,請注意,沒有理由使用ImageTk因爲加載從文件的圖像內置的Tkinter爲Tkinter.PhotoImage

此外,我將通配符導入轉換爲正常導入;通配符導入很混亂,而且與PEP8相反。

最後,我不知道'關閉'是什麼意思,所以我添加了一個按鈕來前進到下一個圖像。這將在您需要處理的最後一張圖像上引發StopIteration錯誤。

import Tkinter as tk 
from tkFileDialog import askdirectory 
import os 

# Create empty list for coordinate arrays to be appended to 
coords = [] 

# Function to be called when mouse is clicked 
def save_coords(event): 
    click_loc = [event.x, event.y] 
    print "you clicked on", click_loc 
    coords.append(click_loc) 

# Function to load the next image into the Label 
def next_img(): 
    img_label.img = tk.PhotoImage(file=next(imgs)) 
    img_label.config(image=img_label.img) 

root = tk.Tk() 

# Choose multiple images 
img_dir = askdirectory(parent=root, initialdir="D:/Temp/", title='Choose folder') 
os.chdir(img_dir) 
imgs = iter(os.listdir(img_dir)) 

img_label = tk.Label(root) 
img_label.pack() 
img_label.bind("<Button-1>",save_coords) 

btn = tk.Button(root, text='Next image', command=next_img) 
btn.pack() 

next_img() # load first image 

root.mainloop() 

print coords 
+0

這很好,謝謝!我使用ImageTk部件來打開PNG文件,這似乎不適用於普通的tkinter。很好學習一個新的tkinter小部件。 – Bird