I'm creating a game and I want to incorporate a gif of a running man when the user uses the arrow keys etc. I'm currently trying to use wxpython and I have code that allows it to be played in a small separate window, but I need to know how to get it on the canvas and place it where I want, if that is possible.

I hope I was clear with my question.

Dani AI

Generated

To animate on a Tkinter Canvas, avoid time.sleep() (it blocks the event loop). Instead, schedule frame updates with after, and pre-decode frames once with Pillow (the actively maintained fork of PIL). This lets you position the sprite anywhere on the Canvas and move it smoothly with arrow keys.

import tkinter as tk
from PIL import Image, ImageTk, ImageSequence

root = tk.Tk()
src = Image.open("run.gif")  # animated GIF
frames, delays = [], []
for fr in ImageSequence.Iterator(src):
    frames.append(ImageTk.PhotoImage(fr.convert("RGBA")))
    delays.append(fr.info.get("duration", 100))  # ms

canvas = tk.Canvas(root, width=frames[0].width(), height=frames[0].height())
canvas.pack()
sprite = canvas.create_image(50, 50, image=frames[0], anchor="nw")

i = 0
def tick():
    nonlocal i
    i = (i + 1) % len(frames)
    canvas.itemconfigure(sprite, image=frames[i])
    root.after(delays[i], tick)

tick()
root.mainloop()

To flip a right-facing sprite to left, mirror the image once and reuse the result (no rotation needed):

from PIL import ImageOps
left_facing = ImageOps.mirror(right_facing)  # or img.transpose(Image.FLIP_LEFT_RIGHT)

Notes:

  • Install Pillow with pip install pillow; legacy PIL errors about missing C modules typically indicate an old or incomplete install. See Pillow installation.
  • Keep references to PhotoImage objects (as above) to prevent garbage collection.
  • Use canvas.coords(sprite, x, y) to reposition the sprite rather than recreating it.
  • Tkinter Canvas images and methods are documented in tkinter.Canvas and after in tkinter.Misc.after. Animated GIF frame handling with Pillow: ImageSequence.

Recommended Answers

All 4 Replies

Nvm. I just extracted the frames from the animations and looped through them. Thanks anyway.

I have another question. How do I go about inverting an image in python so a character facing right would face left?

I'm trying to use the Image module but I'm getting errors about not having a C module or something...

Here is one way to rotate an image with PIL (Python Image Library) ...

# rotate an image counter-clockwise using the PIL image library
# free from:  
# save the rotated image as a GIF file so Tkinter can read it

from PIL import Image
import Tkinter as tk   # for Python3 use tkinter

# open an image file (.bmp, .jpg, .png, .gif)
# change image filename to something you have in the working folder
file_in = "Duck.jpg"
img1 = Image.open(file_in)

# rotate 90 degrees counter-clockwise
img2 = img1.rotate(90)

# save the rotated image as a .gif file to the working folder
# you could save it as a .bmp, .jpg, .png  too, but Tkinter reads GIF
file_out = "DuckRot90.gif"
img2.save(file_out)

# now display saved GIF file with Tkinter
root = tk.Tk()

photo = tk.PhotoImage(file=file_out)

# put the image on a label widget
# it auto-sizes to the image
label = tk.Label(root,image=photo)
label.pack(padx=5, pady=5)

root.mainloop()

Animation is a little more complex ...

# mimic an animated GIF displaying a series of GIFs
# an animated GIF was used to create the series of GIFs 
# with a common GIF animator utility

import time
from Tkinter import *

root = Tk()

imagelist = ["dog001.gif","dog002.gif","dog003.gif",
             "dog004.gif","dog005.gif","dog006.gif","dog007.gif"]

# extract width and height info
photo = PhotoImage(file=imagelist[0])
width = photo.width()
height = photo.height()
canvas = Canvas(width=width, height=height)
canvas.pack()

# create a list of image objects
giflist = []
for imagefile in imagelist:
    photo = PhotoImage(file=imagefile)
    giflist.append(photo)

# loop through the gif image objects for a while
for k in range(0, 1000):
    for gif in giflist:
        canvas.delete(ALL)
        canvas.create_image(width/2.0, height/2.0, image=gif)
        canvas.update()
        time.sleep(0.1)

root.mainloop()
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.