I already have an image displayed on a tkinter Canvas
using the Canvas.create_image()
method.
I want to now flip the image after calling the create_image()
method. I have the ID of the canvas object and also the filepath of the original image. So I want the existing canvas image to be replaced with a horizontally mirrored image.
I also want this to be something that can happen an unknown but unlimited number of times in my program, so just getting a PIL Image from the filepath and flipping that image and destroying and redrawing the image wouldn't work because the file itself always stays facing the same direction so after getting flipped once it would never go back to its original state. And also that just seems a bit cumbersome to read the disk every time I want to flip the image; surely it's possible to do it just in memory?
What's the best way of doing this?
Tagging with PIL because I thought PIL might be helpful for doing this, but obviously if it's not necessary to do this then it's not relevant.
Also, my program should be able to run in an environment with only Python standard libraries and possibly PIL if needed, so unfortunately I can't install anything with pip.
Frankly, I don't know what is the problem.
If you have item_id
then you can replace image with
canvas.itemconfig(item_id, image=tk_flipped_image)
Of course it always needs to use PIL
to flip image.
And if you want to flip the same image many times then you don't have to destroy it.
Keep both versions in memory.
Full Working code.
I use after()
to replace image every 1000ms (1s)
import tkinter as tk
from PIL import Image, ImageTk
# --- functions ---
def update_image():
global index
index = (index + 1) % 2
if index == 0:
canvas.itemconfig(image_id, image=tk_image_0)
else:
canvas.itemconfig(image_id, image=tk_image_1)
root.after(1000, update_image) # run again after 1000ms
# --- main ---
root = tk.Tk()
pil_image_0 = Image.open("test.png")
pil_image_1 = pil_image_0.transpose(Image.FLIP_TOP_BOTTOM) # Image.FLIP_LEFT_RIGHT
tk_image_0 = ImageTk.PhotoImage(pil_image_0)
tk_image_1 = ImageTk.PhotoImage(pil_image_1)
canvas = tk.Canvas(root, width=pil_image_0.width, height=pil_image_0.height)
canvas.pack(fill='both', expand='yes')
index = 0
image_id = canvas.create_image(0, 0, image=tk_image_0, anchor='nw')
root.after(1000, update_image)
root.mainloop()
Result: