Python tkinter-使用鼠标移动在画布图像上显示图像覆盖

Python tkinter-使用鼠标移动在画布图像上显示图像覆盖,python,image,tkinter,tkinter-canvas,photoimage,Python,Image,Tkinter,Tkinter Canvas,Photoimage,我有两张大小完全相同的图片。一个是基础背景图像,另一个是背景图像的修改版本。我试图在背景图像的顶部显示一个静态大小(如100100)的修改图像窗口,它们在鼠标移动的任何位置排列。有点像一个移动窗口,将修改后的图像覆盖在基础图像上。我一直在尝试修改在堆栈溢出中找到的一些基本代码,但似乎不知道如何修改它以获得所需的结果。如果你认为我走错了路,或者如果我错过了一个很接近的例子,请建议另一种方法。我对特金特很陌生。此外,我不需要下图示例中显示的坐标系。仅仅是图像本身就是好的 from tkinter i

我有两张大小完全相同的图片。一个是基础背景图像,另一个是背景图像的修改版本。我试图在背景图像的顶部显示一个静态大小(如100100)的修改图像窗口,它们在鼠标移动的任何位置排列。有点像一个移动窗口,将修改后的图像覆盖在基础图像上。我一直在尝试修改在堆栈溢出中找到的一些基本代码,但似乎不知道如何修改它以获得所需的结果。如果你认为我走错了路,或者如果我错过了一个很接近的例子,请建议另一种方法。我对特金特很陌生。此外,我不需要下图示例中显示的坐标系。仅仅是图像本身就是好的

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()
从tkinter导入*
从PIL导入ImageTk,图像
从scipy.misc导入imread
event2canvas=lambdae,c:(c.canvasx(e.x),c.canvasy(e.y))
#移动鼠标时要调用的函数
def move_窗口(事件):
#将x和y坐标输出到控制台
cx,cy=event2canvas(事件,画布)
打印((%d,%d)/(%d,%d)“%(事件x、事件y、cx、cy))
如果名称=“\uuuuu main\uuuuuuuu”:
root=Tk()
#使用滚动条设置tkinter画布
框架=框架(根部,bd=2,浮雕=凹陷)
frame.grid_rowconfigure(0,权重=1)
frame.grid\u columnconfigure(0,权重=1)
xscroll=滚动条(框架,方向=水平)
xscroll.grid(行=1,列=0,粘性=E+W)
yscroll=滚动条(帧)
yscroll.grid(行=0,列=1,粘性=N+S)
canvas=canvas(frame,bd=0,xscrollcommand=xscroll.set,yscrollcommand=yscroll.set)
网格(行=0,列=0,粘性=N+S+E+W)
xscroll.config(命令=canvas.xview)
yscroll.config(命令=canvas.yview)
frame.pack(填充=两者,扩展=1)
#正在将背景和更改后的图像加载到numpy数组中。
background\u image\u data=imread(“images/original.png”,mode=“L”)
前景图像数据=imread(“images/altered.png”,mode=“L”)
#这里是应该注入鼠标坐标以在背景图像上移动窗口的位置
窗口数据=前景图像数据[500:600,500:600]
背景图像数据[500:600,500:600]=窗口数据
img=ImageTk.PhotoImage(Image.fromarray(背景图像数据))
canvas.create_image(0,0,image=img,anchor=“nw”)
canvas.config(scrollregion=canvas.bbox(全部),width=img.width(),height=img.height())
test=canvas.bind(“,移动窗口)
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())
    
  • 更改为
    ,以便通过更改鼠标位置来运行。或者将其更改为
    ,以便在按住左键并移动鼠标时运行

  • 更改此项:

    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")
    
  • 你完了!正如你所看到的,这都是你自己的代码,只是移动了一些香料。我并没有在画布上做过很多工作,所以我不知道最后一部分是否会继续在另一部分的基础上创建新的图像,或者替换已经存在的图像。因此,我不知道这是否是最好的代码,但它是有效的。
    您最好清理这段代码,因为您可以从
    move\u窗口中看到很多代码,这些代码与主循环之前的代码相同

    祝你好运。

    你让它看起来很简单!谢谢嘿我在那里犯了一个可怕的错误,我在编辑中纠正了这个错误。我又把tkinter主回路的机制搞糊涂了!(每次我回到tkinter都会发生!)。你根本不需要第一次跑步。只要去掉它,你就会没事的。主循环不是那样工作的!!!