2017-08-18 69 views
1

我有兩個完全相同大小的圖像。一個是基礎背景圖像,另一個圖像是背景圖像的改變版本。我試圖在背景圖像的頂部顯示一個靜態大小(例如100,100)的窗口,在這些窗口中,無論鼠標移動到哪裏,它們都會排列起來。在基本圖像上覆蓋改變後的圖像的移動窗口的排序。我一直在試圖修改我在Stack Overflow的某處找到的一些基本代碼,但似乎無法弄清楚如何修改它以獲得所需的結果。如果您認爲我錯誤地採取了這種方式,或者在我錯過了某個地方的情況下,請提出另一種方法。我對tkinter很新。另外,我不需要以下圖像示例中顯示的座標系。只有圖像是好的。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() 

背景圖片: enter image description here

修改過的圖片: enter image description here

所需的結果: enter image description here

回答

1

你居然做了幾乎所有的。你只需要重新定位一些東西並在這裏和那裏添加一些東西(我不打算以一種乾淨的方式來做,否則我必須改變更多的東西。你以後可以自己做,以避免重複行您的代碼):

  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()) 
    

    這樣:

    # 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()) 
    
  2. 變化"<ButtonPress-1>""<Motion>"所以它會通過改變鼠標位置來運行。或者將其更改爲"<B1-Motion>",以便在您按住左鍵並移動鼠標時運行。

  3. 更改此:

    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_window中的很多代碼與主循環之前的代碼相同
祝您好運。

+0

你讓它看起來很簡單!謝謝! – Beaker

+0

嘿。我在那裏修改了一個可怕的錯誤。我再次混淆了tkinter mainloop的機制! (每次我回到tkinter都會發生!)。你根本不需要first_run的東西。只要刪除,你會沒事的。主循環不能像那樣工作! – ROAR