有没有办法在Tkinter画布上索引多次点击?我正在尝试编写一个Python脚本,它将保存图像的四个唯一的用户选择区域。每张图片上都覆盖有文字,显示纬度,经度,日期和时间。目标是让用户选择具有该文本的四个区域并裁剪它们以创建四个新图像
该脚本到目前为止工作,用户打开图像,绘制矩形,并打印矩形的坐标。当我将坐标保存到变量时,它会被下一个矩形覆盖
如何索引矩形选择(或事件),以便lat,lon,date和time可以有唯一的变量,可以传递给另一个函数来裁剪图像的那些部分?
这是脚本(问题在评论附近):
import Tkinter as tk
from Tkinter import *
import tkMessageBox
from PIL import ImageTk, Image
from tkFileDialog import askopenfilename
import os
class kanvas(Frame):
def __init__ (self, master, **kwargs):
Frame.__init__(self, master, **kwargs)
self.grid_rowconfigure(0, weight=1)
self.grid_columnconfigure(0, weight=1)
self.canv = Canvas(self, width = 720, height = 480, bd=0, highlightthickness=0)
self.hScroll = Scrollbar(self, orient='horizontal',
command=self.canv.xview)
self.hScroll.grid(row=1, column=0, sticky='we')
self.vScroll = Scrollbar(self, orient='vertical',
command=self.canv.yview)
self.vScroll.grid(row=0, column=1, sticky='ns')
self.canv.grid(row=0, column=0, sticky='nsew', padx=4, pady=4)
self.canv.configure(xscrollcommand=self.hScroll.set,
yscrollcommand=self.vScroll.set)
class ImgTk(tk.Tk):
def __init__(self):
#This function asks the user to select an image then opens it on a tkinter window
tk.Tk.__init__(self)
#Above line calls the super class's '__init__' method; resolved error of 'get attr'
button = tkMessageBox.showinfo(message = "Draw rectangles around lat, lon, date and time")
self.main = kanvas(self)
self.main.grid(row=0, column = 0, sticky = 'nsew')
self.c = self.main.canv
self.currentImage = {}
self.load_imgfile(askopenfilename(parent = tk.Toplevel(), initialdir = "D:/", title = "Choose an image:"))
self.c.bind('<ButtonPress-1>', self.on_mouse_down)
self.c.bind('<B1-Motion>', self.on_mouse_drag)
self.c.bind('<ButtonRelease-1>', self.on_mouse_up)
def load_imgfile(self, filename):
self.img = Image.open(filename)
self.currentImage['data'] = self.img
self.photo = ImageTk.PhotoImage(self.img)
self.c.xview_moveto(0)
self.c.yview_moveto(0)
self.c.create_image(0, 0, image=self.photo, anchor='nw', tags='img')
self.c.config(scrollregion=self.c.bbox('all'))
self.currentImage['photo'] = self.photo
def on_mouse_down(self, event):
self.anchor = (event.widget.canvasx(event.x),
event.widget.canvasy(event.y))
self.item = None
def on_mouse_drag(self, event):
bbox = self.anchor + (event.widget.canvasx(event.x),
event.widget.canvasy(event.y))
if self.item is None:
self.item = event.widget.create_rectangle(bbox, outline="red")
else:
event.widget.coords(self.item, *bbox)
def on_mouse_up(self, event):
if self.item:
self.on_mouse_drag(event)
box = tuple((int(round(v)) for v in event.widget.coords(self.item)))
roi = self.currentImage['data'].crop(box) # region of interest
values = roi.getdata() # pixel values
coords = [roi.size[0], roi.size[1], box[0], box[1]]
print coords
# Main question: how do I save unique variables from events?
# The following is what I would like to be able to do:
# lat = coords from event[0]
# lon = coords from event[1]
# time = coords from event[2]
# date = coords from event[3]
app = ImgTk()
app.mainloop()
Here is an example image (rectangle selections in red)
我对Python比较新,所以请原谅任何新手语法错误。谢谢你的帮助!
编辑我找到了一个解决方案,以防其他人遇到此问题。创建一个全局列表(crop_regions),然后将其附加到最后一个函数中。
import...
cro_regions = []
class kanvas(...):
...
class ImgTk(...):
def __init__(...)
...
def on_mouse_up(...)
if self.item:
self.on_mouse_drag(event)
box = tuple((int(round(v)) for v in event.widget.coords(self.item)))
roi = self.currentImage['data'].crop(box) # region of interest
values = roi.getdata() # pixel values
coords = [roi.size[0], roi.size[1], box[0], box[1]]
lat = roi.size[0],'x',roi.size[1],'+',box[0],'+',box[1]
lat = str(lat)
lat = lat.replace(',','')
lat = lat.replace("'", '')
lat = lat.replace(' ','')
global crop_regions
crop_regions.append(lat)
app = ImgTk()
app.mainloop()