Search code examples
pythonnumpypython-imaging-librarytkinter-canvastkinter-button

Tkinter canvas not updating photo


I am trying to make a photo editing app with tkinter that preforms an action to the uploaded picture on a button press(eg. flips the picture), but when the button is pressed nothing happens. The code that manipulates the picture works, I just can't get the change to show on screen. Full code:

from PIL import Image, ImageTk
import PIL
import numpy as np
import tkinter as tk
from tkinter import *

image = PIL.Image.open('images.jpg')

img_data = np.array(image)


def button_flip_onClick():
    global canvas
    global image_container
    global img
    image_flipped_data = np.flip(img_data, axis=1)
    image_flipped = Image.fromarray(image_flipped_data)
    img = ImageTk.PhotoImage(image_flipped)
    image_container.config(canvas.create_image(10,10,anchor='nw',image=img))


SCREEN_WIDTH = 300
SCREEN_HEIGHT = 300

root = tk.Tk()


canvas = tk.Canvas(width=SCREEN_WIDTH, height=SCREEN_HEIGHT)
canvas.pack()
#Load an image in the script
img = ImageTk.PhotoImage(image)



image_container = canvas.create_image(10,10,anchor='nw',image=img)


button2 = tk.Button(root, text='flip', command= lambda:button_flip_onClick)
button2.place(relx=0.01, rely=0.7, relheight=0.15, relwidth=0.2)



root.mainloop()

I've tried configuring img in the function, putting image_container after button2, configuring the canvas in the function. All resulted in the picture staying the same.


Solution

  • Modify the import part first.

    from PIL import Image, ImageTk
    import numpy as np
    import tkinter as tk
    

    and, In button_flip_onClick function

    image_container.config(canvas.create_image(10,10,anchor='nw',image=img))
    

    Replace this part with:

    canvas.itemconfig(image_container, image=img)
    

    And when your button calls a function, you don't need a lambda. It works even if you do this.

    button2 = tk.Button(root, text='flip', command= button_flip_onClick)
    

    and full code...

    from PIL import Image, ImageTk
    import numpy as np
    import tkinter as tk
    
    image = Image.open('images.jpg')
    
    img_data = np.array(image)
    
    def button_flip_onClick():
        global canvas
        global image_container
        global img
        image_flipped_data = np.flip(img_data, axis=1)
        image_flipped = Image.fromarray(image_flipped_data)
        img = ImageTk.PhotoImage(image_flipped)
        canvas.itemconfig(image_container, image=img)
    
    SCREEN_WIDTH = 300
    SCREEN_HEIGHT = 300
    
    root = tk.Tk()
    
    canvas = tk.Canvas(width=SCREEN_WIDTH, height=SCREEN_HEIGHT)
    canvas.pack()
    #Load an image in the script
    img = ImageTk.PhotoImage(image)
    
    image_container = canvas.create_image(10,10,anchor='nw',image=img)
    
    button2 = tk.Button(root, text='flip', command= button_flip_onClick)
    button2.place(relx=0.01, rely=0.7, relheight=0.15, relwidth=0.2)
    
    root.mainloop()
    

    I hope it will be of help.