Skip to main content
Engineering LibreTexts

3.19: Drawing Images with pygame.image.load() and blit()

  • Page ID

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    The drawing functions are fine if you want to draw simple shapes on the screen, but many games have images (also called sprites). Pygame is able to load images onto Surface objects from PNG, JPG, GIF, and BMP image files. The differences between these image file formats is described at

    The image of the cat was stored in a file named cat.png. To load this file’s image, the string 'cat.png' is passed to the pygame.image.load() function. The pygame.image.load() function call will return a Surface object that has the image drawn on it. This Surface object will be a separate Surface object from the display Surface object, so we must blit (that is, copy) the image’s Surface object to the display Surface object. Blitting is drawing the contents of one Surface onto another. It is done with the blit() Surface object method.

    If you get an error message like "pygame.error: Couldn't open cat.png" when calling pygame.image.load(), then make sure the cat.png file is in the same folder as the file before you run the program.

    Line 39 of the animation program uses the blit() method to copy catImg to DISPLAYSURF. There are two parameters for blit(). The first is the source Surface object, which is what will be copied onto the DISPLAYSURF Surface object. The second parameter is a two-integer tuple for the X and Y values of the topleft corner where the image should be blitted to.

    import pygame, sys
    from pygame.locals import *
    FPS = 30 # frames per second setting
    fpsClock = pygame.time.Clock()
    # set up the window
    DISPLAYSURF = pygame.display.set_mode((400, 300), 0, 32)
    WHITE = (255, 255, 255)
    catImg = pygame.image.load('cat.png')
    catx = 10
    caty = 10
    direction = 'right'
    while True: # the main game loop
        if direction == 'right':
            catx += 5
            if catx == 280:
                direction = 'down'
        elif direction == 'down':
            caty += 5
            if caty == 220:
                direction = 'left'
        elif direction == 'left':
            catx -= 5
            if catx == 10:
                direction = 'up'
        elif direction == 'up':
            caty -= 5
            if caty == 10:
                direction = 'right'
        DISPLAYSURF.blit(catImg, (catx, caty))
        for event in pygame.event.get():
            if event.type == QUIT:

    If catx and caty were set to 100 and 200 and the width of catImg was 125 and the height was 79, this blit() call would copy this image onto DISPLAYSURF so that the top left corner of the catImg was at the XY coordinate (100, 200) and the bottom right corner’s XY coordinate was at (225, 279).

    Note that you cannot blit to a Surface that is currently "locked" (such as when a PixelArray object has been made from it and not yet been deleted.)

    The rest of the game loop is just changing the catx, caty, and direction variables so that the cat moves around the window. There is also a call to pygame.event.get() to handle the QUIT event.

    This page titled 3.19: Drawing Images with pygame.image.load() and blit() is shared under a CC BY-NC-SA 3.0 license and was authored, remixed, and/or curated by Al Sweigart via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.