我有两张尺寸完全相同的图像。一张是基本背景图像,另一张图像是背景图像的更改版本。我试图在背景图像的顶部显示一个静态大小(例如 100,100)的更改图像的窗口,无论鼠标移动到哪里,它们都会对齐。类似于将更改后的图像覆盖在基本图像上的移动窗口。我一直在尝试修改我在 Stack Overflow 上找到的一些基本代码,但似乎无法弄清楚如何修改它以获得所需的结果。如果您认为我以错误的方式处理此问题,或者如果我错过了某个地方的接近示例,请建议一种替代方法。我对 tkinter 很陌生。另外,我不需要下面的图像示例中显示的坐标系。仅凭图像就很好。
from tkinter import *
from PIL import ImageTk, Image
from scipy.misc import imread
event2canvas = lambda e, c: (c.canvasx(e.x), c.canvasy(e.y))
# function to be called when mouse is moved
def move_window(event):
# outputting x and y coords to console
cx, cy = event2canvas(event, canvas)
print("(%d, %d) / (%d, %d)" % (event.x, event.y, cx, cy))
if __name__ == "__main__":
root = Tk()
#setting up a tkinter canvas with scrollbars
frame = Frame(root, 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.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)
# loading background and altered image into numpy array.
background_image_data = imread("images/original.png", mode="L")
foreground_image_data = imread("images/altered.png", mode="L")
# Here is where the mouse coordinates should be injected to move the window over the background image
window_data = foreground_image_data[500:600, 500:600]
background_image_data[500:600, 500:600] = window_data
img = ImageTk.PhotoImage(Image.fromarray(background_image_data))
canvas.create_image(0, 0,image=img,anchor="nw")
canvas.config(scrollregion=canvas.bbox(ALL), width=img.width(), height=img.height())
test = canvas.bind("<ButtonPress-1>", move_window)
root.mainloop()
最佳答案
事实上你几乎完成了所有的事情。你只需要重新定位一些东西,并在这里和那里添加一些东西(我不会以一种干净的方式来做,否则我必须改变更多的东西。你可以稍后自己做,以免重复的行您的代码):
更改这部分代码:
# loading background and altered image into numpy array. background_image_data = imread("images/original.png", mode="L") foreground_image_data = imread("images/altered.png", mode="L") # Here is where the mouse coordinates should be injected to move the window over the background image window_data = foreground_image_data[500:600, 500:600] background_image_data[500:600, 500:600] = window_data img = ImageTk.PhotoImage(Image.fromarray(background_image_data)) canvas.create_image(0, 0,image=img,anchor="nw") canvas.config(scrollregion=canvas.bbox(ALL), width=img.width(), height=img.height())
对此:
# loading background and altered image into numpy array. background_image_data = imread("images/original.png", mode="L") foreground_image_data = imread("images/altered.png", mode="L") '''Shouldn't change the original background image because that way the changes will be permanent''' bg_img = background_image_data.copy() # Here is where the mouse coordinates should be injected to move the window over the background image x,y,wh = (50,50,100) window_data = foreground_image_data[y:y+wh,x:x+wh] bg_img[y:y+wh,x:x+wh] = window_data img = ImageTk.PhotoImage(Image.fromarray(bg_img)) canvas.create_image(0, 0,image=img,anchor="nw") canvas.config(scrollregion=canvas.bbox(ALL), width=img.width(), height=img.height())
更改
"<ButtonPress-1>"
至"<Motion>"
所以它会通过改变鼠标位置来运行。或者改为"<B1-Motion>"
因此,只要您按住左键并移动鼠标,它就会运行。更改此:
def move_window(event): cx, cy = event2canvas(event, canvas)
对此:
def move_window(event): global img cx, cy = event2canvas(event, canvas) x,y,wh = (int(cx),int(cy),100) window_data = foreground_image_data[y:y+wh,x:x+wh] bg_img = background_image_data.copy() bg_img[y:y+wh,x:x+wh] = window_data img = ImageTk.PhotoImage(Image.fromarray(bg_img)) canvas.create_image(0, 0,image=img,anchor="nw")
你就完成了!正如您所看到的,这都是您自己的代码,只是移动了一下,并添加了一些香料。我没有经常使用 Canvas ,所以我不知道最后一部分是否会继续在另一图像之上创建新图像或替换已经存在的图像。所以我不知道这是否是最好的代码,但它确实有效。
您最好清理一下这段代码,因为您可以从move_window
中看到很多代码。与主循环之前相同
祝你好运。
关于python - tkinter - 通过鼠标移动在 Canvas 图像上显示图像叠加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45762991/