How to Add an Image to Python Turtle (GIF, PNG and Background)

To attach an image to a Python Turtle, register the image as a shape with screen.register_shape("rocket.gif") and then call t.shape("rocket.gif"). Up to Python 3.13 that shortcut only accepts GIF files; PNG works too, but through tkinter.PhotoImage (shown below), and Python 3.14 adds PNG to register_shape() directly. This guide also covers background images, resizing, making images turn with the turtle, and the errors you’re likely to hit.

Every program was run with Python 3.12.5 (Tk 8.6.13) and Pillow 12.3.0 on Windows 11, and the screenshots are the real windows. The sample images (a rocket and a night sky) were made with Pillow; use your own files in the same folder as your script.

Use a GIF image as the turtle

import turtle

screen = turtle.Screen()
screen.setup(500, 400)

screen.register_shape("rocket.gif")     # 1. register the image file
t = turtle.Turtle()
t.shape("rocket.gif")                   # 2. use it as the turtle's shape

t.penup()
t.goto(0, -60)
t.pendown()
t.pensize(3)
t.goto(0, 60)                           # it moves and draws like any turtle

turtle.done()
Python Turtle image: a rocket GIF registered with register_shape used as the turtle shape, drawing a vertical line
The rocket image replaces the turtle arrow.
  • The file name you register is also the shape name.
  • The image file must be in the folder Python runs from, or use a full path.
  • The image moves, draws and stamps like any turtle shape.

PNG images (Python 3.13 and earlier)

In Python 3.12 and 3.13, passing a PNG file name to register_shape() fails, because it only accepts names ending in .gif:

import turtle

screen = turtle.Screen()
try:
    screen.register_shape("rocket.png")
except turtle.TurtleGraphicsError as err:
    print("TurtleGraphicsError:", err)
screen.bye()

Output:

TurtleGraphicsError: Bad arguments for register_shape.
Use  help(register_shape)

But Tk 8.6, which Turtle draws with, can read PNG files, including transparent ones. Load the image yourself with tkinter.PhotoImage and register it as an image Shape:

import tkinter as tk
import turtle

screen = turtle.Screen()
screen.setup(620, 470)
screen.bgpic("sky.png")                             # PNG background works

png = tk.PhotoImage(file="rocket.png")              # Tk 8.6 reads PNG, including transparency
screen.register_shape("rocket", turtle.Shape("image", png))

t = turtle.Turtle()
t.shape("rocket")
t.penup()
t.goto(-120, -80)

turtle.done()
Python Turtle transparent PNG image as the turtle shape on a PNG night sky background image
A transparent PNG rocket over a PNG background, in Python 3.12.

PNG in Python 3.14 and later

Python 3.14 added PNG (and PGM/PPM) support to register_shape() and bgpic(), and a second form that takes a shape name plus a file name. Per the official documentation (not run here, since this page was tested on 3.12):

screen.register_shape("rocket.png")             # Python 3.14+
screen.register_shape("rocket", "rocket.png")   # Python 3.14+: your own shape name
t.shape("rocket")

If your code must run on older versions too, use the PhotoImage method above; it works on all of them.

Add a background image with bgpic()

screen.bgpic() puts an image behind everything. It’s centred and not scaled, so make the window about the size of the image. bgpic("nopic") removes it again:

import turtle

screen = turtle.Screen()
screen.setup(620, 470)                  # the image is 600 x 450
screen.title("Background image")
screen.bgpic("sky.png")                 # shown centred, not stretched

writer = turtle.Turtle(visible=False)
writer.penup()
writer.color("white")
writer.goto(0, -20)
writer.write("Good night!", align="center", font=("Arial", 32, "bold"))

turtle.done()
Python Turtle background image with bgpic: a night sky with stars and a moon and white text Good night
A 600 × 450 PNG background with text on top.

More on backgrounds in Python Turtle background.

Resize an image

PhotoImage can shrink with subsample(n) and grow with zoom(n) by whole numbers. stamp() leaves a copy of the current shape on the screen:

import tkinter as tk
import turtle

screen = turtle.Screen()
screen.setup(560, 340)

original = tk.PhotoImage(file="rocket.png")
screen.register_shape("small", turtle.Shape("image", original.subsample(2)))   # half size
screen.register_shape("normal", turtle.Shape("image", original))
screen.register_shape("big", turtle.Shape("image", original.zoom(2)))          # double size

t = turtle.Turtle()
t.penup()
for x, name in [(-170, "small"), (-40, "normal"), (140, "big")]:
    t.goto(x, 0)
    t.shape(name)
    t.stamp()                           # leave a copy of the image behind
t.hideturtle()

turtle.done()
Python Turtle resize image: the same rocket at half size, normal size and double size using PhotoImage subsample and zoom
subsample(2), original, zoom(2).

For any size (for example 64 × 64), resize with Pillow first; see the conversion example below.

Make the image turn with the turtle

Image shapes don’t rotate: the turtle’s heading changes but the picture stays the same. Turtle’s own documentation says so, and the shape type confirms it:

import turtle

screen = turtle.Screen()
screen.register_shape("rocket.gif")
t = turtle.Turtle(shape="rocket.gif")

t.left(90)
print("heading:", t.heading(), "| shape:", t.shape())   # the heading changes...
print("shape polygon:", t.get_shapepoly())              # ...but an image has no polygon to rotate
screen.bye()

Output:

heading: 90.0 | shape: rocket.gif
shape polygon: None

The fix is to prepare one rotated copy of the picture per direction with Pillow (pip install pillow) and switch shapes as the heading changes:

import turtle
from PIL import Image, ImageTk

screen = turtle.Screen()
screen.setup(620, 620)
screen.bgcolor("#0f2030")

base = Image.open("rocket.png")         # the picture points up (heading 90)
for heading in range(0, 360, 45):
    # Pillow rotates counterclockwise, like Turtle headings
    frame = ImageTk.PhotoImage(base.rotate(heading - 90, expand=True))
    screen.register_shape(f"rocket{heading}", turtle.Shape("image", frame))

t = turtle.Turtle()
t.penup()
for heading in range(0, 360, 45):
    t.goto(0, 0)
    t.setheading(heading)
    t.forward(200)
    t.shape(f"rocket{heading}")         # pick the picture that matches the heading
    t.stamp()
t.hideturtle()

turtle.done()
Python Turtle rotate image: eight rocket images stamped in a circle, each pointing outward in its heading direction
Eight pre-rotated shapes, one per 45°.

Move an image with the arrow keys

Put the pieces together for a tiny game: a background, an image shape and key bindings (more events in the Turtle cheat sheet):

import turtle

screen = turtle.Screen()
screen.setup(620, 470)
screen.bgpic("sky.png")
screen.register_shape("rocket.gif")

rocket = turtle.Turtle(shape="rocket.gif")
rocket.penup()
rocket.speed(0)

def move(dx, dy):
    x, y = rocket.position()
    rocket.goto(max(-280, min(280, x + dx)), max(-200, min(200, y + dy)))   # stay on screen

screen.onkey(lambda: move(0, 20), "Up")
screen.onkey(lambda: move(0, -20), "Down")
screen.onkey(lambda: move(-20, 0), "Left")
screen.onkey(lambda: move(20, 0), "Right")
screen.listen()

turtle.done()
Python Turtle move image with arrow keys: rocket image over a night sky background after moving up and to the right
After six moves up and right.

Convert PNG or JPG to GIF (and resize) with Pillow

For Python 3.13 or older, or to make an image smaller, convert it once with Pillow. GIF only supports on/off transparency, so pixels are either kept or made fully transparent:

from PIL import Image

img = Image.open("rocket.png").convert("RGBA")
img = img.resize((64, 64))                                   # resize while you're at it

# GIF has 1-bit transparency: keep pixels that are mostly opaque
alpha = img.getchannel("A").point(lambda a: 255 if a > 128 else 0)
gif = img.convert("RGB").quantize(colors=255)
gif.paste(255, mask=Image.eval(alpha, lambda a: 255 - a))   # paint the background with palette colour 255
gif.save("rocket_small.gif", transparency=255)               # ...and mark that colour as transparent

check = Image.open("rocket_small.gif").convert("RGBA")
print(check.size)
print("corner:", check.getpixel((0, 0)))        # alpha 0 = transparent
print("centre:", check.getpixel((32, 32)))      # alpha 255 = the rocket

Output:

(64, 64)
corner: (0, 0, 0, 0)
centre: (236, 239, 241, 255)

Common errors

import tkinter as tk
import turtle

screen = turtle.Screen()
for name in ["missing.gif", "photo.jpg"]:
    try:
        tk.PhotoImage(file=name)
    except tk.TclError as err:
        print(f"{name}: TclError: {err}")
screen.bye()

Output:

missing.gif: TclError: couldn't open "missing.gif": no such file or directory
photo.jpg: TclError: couldn't recognize data in image file "photo.jpg"
  • couldn't open ... no such file or directory: the path is wrong. Put the image next to your script and run the script from that folder, or use an absolute path.
  • couldn't recognize data in image file: Tk can’t read that format (JPG, WebP, BMP). Convert it to PNG or GIF with Pillow.
  • Bad arguments for register_shape: a PNG name in Python 3.13 or older. Use the PhotoImage method or upgrade to 3.14.
  • The image doesn’t turn: expected. Use pre-rotated shapes as shown above.
  • The image disappears when you create PhotoImage objects in your own code: keep a reference to them (registering them as a shape does that for you).

Summary

TaskCode
GIF as the turtlescreen.register_shape("x.gif"), t.shape("x.gif")
PNG as the turtle (any version)register_shape("x", turtle.Shape("image", tk.PhotoImage(file="x.png")))
PNG as the turtle (3.14+)screen.register_shape("x.png")
Background imagescreen.bgpic("sky.png")
Smaller / biggerphoto.subsample(2) / photo.zoom(2)
Rotate with headingPre-rotated shapes with Pillow
Leave a copyt.stamp()

Frequently asked questions

How do I add an image to a Python Turtle?

Register it as a shape with screen.register_shape("image.gif"), then call t.shape("image.gif"). The image then moves wherever the turtle goes.

Can Python Turtle use PNG images?

Yes. Python 3.14+ accepts PNG in register_shape() directly. In older versions, load it with tkinter.PhotoImage(file="x.png") and register turtle.Shape("image", photo).

How do I set a background image in Turtle?

Call turtle.Screen().bgpic("background.png"). The image is centred and not stretched, so size the window to match it.

Why doesn’t my turtle image rotate?

Image shapes never rotate in Turtle. Create rotated copies with Pillow and switch shapes when the heading changes.

Can I use a JPG image in Turtle?

Not directly: Tk can’t read JPG and raises couldn't recognize data in image file. Convert it to PNG or GIF with Pillow first.

More Turtle image tutorials: