在 Python 中使用 Tkinter canvas 循环浏览图像
Loop through images with Tkinter canvas in Python
我正在尝试编写一个脚本,允许用户 select 一个包含图像的文件夹,然后保存用户在每个图像上的点击坐标。为此,我想在 Tkinter canvas 上显示每个图像文件,保存点击位置,然后当 canvas 关闭时,打开下一张图像。
我可以使用下面的代码(改编自 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()
如果你能改用标签会容易很多:
此外,请注意,没有理由使用 ImageTk,因为从文件加载图像已作为 Tkinter.PhotoImage
内置到 tkinter 中。
此外,我将您的通配符导入转换为普通导入;通配符导入是混乱的并且不符合 PEP8。
最后,我不知道你说的 'on closing' 是什么意思,所以我添加了一个按钮来前进到下一张图片。这将在您需要处理的最后一张图像上引发 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
我正在尝试编写一个脚本,允许用户 select 一个包含图像的文件夹,然后保存用户在每个图像上的点击坐标。为此,我想在 Tkinter canvas 上显示每个图像文件,保存点击位置,然后当 canvas 关闭时,打开下一张图像。
我可以使用下面的代码(改编自 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()
如果你能改用标签会容易很多:
此外,请注意,没有理由使用 ImageTk,因为从文件加载图像已作为 Tkinter.PhotoImage
内置到 tkinter 中。
此外,我将您的通配符导入转换为普通导入;通配符导入是混乱的并且不符合 PEP8。
最后,我不知道你说的 'on closing' 是什么意思,所以我添加了一个按钮来前进到下一张图片。这将在您需要处理的最后一张图像上引发 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