I have two images that are the exact same size. One is the base background image and the other image is an altered version of the background image. I am trying to show a window of a static size (such as 100,100) of the altered image over the top of the background image where they line up wherever the mouse is moved. Sort of a moving window overlaying the altered image over the base image. I have been trying to modify some base code I found somewhere here on Stack Overflow, but can't seem to figure out how to modify it to get the desired result. Please suggest an alternative method if you think I am going about this the wrong way, or also if there is a close example somewhere I have missed. I am very new to tkinter. Also, I have no need for the coordinate system shown in my image examples below. Just the image alone is good.
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()
You actually did almost all of it. You just need to reposition some of the things and add a few things here and there (I'm not going to do it in a clean way otherwise I have to change more stuff. You can do that yourself later to not have duplicate lines in your code):
Change this part of your code:
# 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())
to this:
# 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())
Change "<ButtonPress-1>"
to "<Motion>"
so it would run by change of mouse position. Or change it to "<B1-Motion>"
so it runs whenever you are holding down Left-Button and moving the mouse.
Change this:
def move_window(event):
cx, cy = event2canvas(event, canvas)
To this:
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")
And you're done! As you can see it's all your own code just moved around, and with a few spices. I haven't worked with canvas very much so I don't know if that last part will keep creating new image on top of the other or replacing an already existing one. So I don't know if it's the best code to use there, but it works.
You better clean this code up because as you can see a lot of the code from move_window
is the same as it was before the mainloop
Good luck.