# PiTFT Python + Pillow Animated Gif Player

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/086/708/medium800thumb/raspberry_pi_main_image.jpg?1578506182)

Have you wanted to play animated Gifs on the Raspberry Pi without showing or taking over the entire desktop? Or maybe you are only wanting to SSH into the Pi and play some kind of animation without the fancy graphical environment. Or possibly, you just want to know how to play animated Gifs with Python and the Pillow library. If so, this is the guide for you.

This is an animated Gif player that runs on the Raspberry Pi and uses a PiTFT Display. It works kind of like a Slideshow player, but displays animated Gifs instead. Because this is written in pure Python, it won't quite be as speedy as a C-based player, but the smaller the resolution of display that you use, the better the performance.

## Parts
To get started, you will need a Raspberry Pi. A Raspberry Pi 4 is recommended because it's pretty fast.

### Raspberry Pi 4 Model B

[Raspberry Pi 4 Model B](https://www.adafruit.com/product/4297)
The Raspberry Pi 4 Model B is the newest Raspberry Pi computer made, and the Pi Foundation knows you can always make a good thing _better_! And what could make the Pi 4 better than the 3? How about a&nbsp;_faster_ processor, USB 3.0 ports, and updated Gigabit Ethernet chip with...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4297)
[Related Guides to the Product](https://learn.adafruit.com/products/4297/guides)
![Angled shot of Raspberry Pi 4](https://cdn-shop.adafruit.com/640x480/4297-02.jpg)

You will also need a PiTFT to display the images. We recommend these smaller Mini PiTFT's since we can write to the display fairly fast.

### Adafruit Mini PiTFT 1.3" - 240x240 TFT Add-on for Raspberry Pi

[Adafruit Mini PiTFT 1.3" - 240x240 TFT Add-on for Raspberry Pi](https://www.adafruit.com/product/4484)
If you're looking for the most compact li'l color display for a [Raspberry Pi](https://www.adafruit.com/category/361) (most&nbsp;likely a [Pi Zero](https://www.adafruit.com/category/813)) project, this might be just the thing you need!

The **...**

In Stock
[Buy Now](https://www.adafruit.com/product/4484)
[Related Guides to the Product](https://learn.adafruit.com/products/4484/guides)
![Video of Adafruit Mini PiTFT 1.3" - 240x240 TFT Add-on on a Raspberry Pi 4. The TFT displays a bootup sequence.](https://cdn-shop.adafruit.com/product-videos/640x480/4484-05.jpg)

### Adafruit Mini PiTFT - 135x240 Color TFT Add-on for Raspberry Pi

[Adafruit Mini PiTFT - 135x240 Color TFT Add-on for Raspberry Pi](https://www.adafruit.com/product/4393)
If you're looking for the most compact li'l color display for a [Raspberry Pi](https://www.adafruit.com/category/361) (most&nbsp;likely a [Pi Zero](https://www.adafruit.com/category/813)) project, this might be just the thing you need!

The **...**

In Stock
[Buy Now](https://www.adafruit.com/product/4393)
[Related Guides to the Product](https://learn.adafruit.com/products/4393/guides)
![Video of Adafruit Mini PiTFT - 135x240 Color TFT Add-on assembled onto a Raspberry Pi 3. The TFT displays a bootup.](https://cdn-shop.adafruit.com/product-videos/640x480/4393-03.jpg)

You could use larger 320x240 ones too for slower images.

### Adafruit PiTFT Plus 320x240 2.8" TFT + Capacitive Touchscreen

[Adafruit PiTFT Plus 320x240 2.8" TFT + Capacitive Touchscreen](https://www.adafruit.com/product/2423)
Is this not the cutest little display for the Raspberry Pi? It features a 2.8" display with 320x240 16-bit color pixels and a capacitive touch overlay.&nbsp;That's right, instead of a resistive touchscreen, which requires a fingernail or stylus, you can now use a fingerpad. The screen...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2423)
[Related Guides to the Product](https://learn.adafruit.com/products/2423/guides)
![Red polished nail touching the screen of a Adafruit PiTFT Plus 320x240 2.8" TFT + Capacitive Touchscreen. ](https://cdn-shop.adafruit.com/640x480/2423-14.jpg)

### PiTFT Plus Assembled 320x240 2.8" TFT + Resistive Touchscreen

[PiTFT Plus Assembled 320x240 2.8" TFT + Resistive Touchscreen](https://www.adafruit.com/product/2298)
Is this not the cutest little display for the Raspberry Pi? It features a 2.8" display with 320x240 16-bit color pixels and a resistive&nbsp;touch overlay. The plate uses the high speed SPI interface on the Pi and can use the mini display as a console, X window port, displaying images or...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2298)
[Related Guides to the Product](https://learn.adafruit.com/products/2298/guides)
![Red polished white finger touching the PiTFT Plus Assembled 320x240 2.8" TFT + Resistive Touchscreen. ](https://cdn-shop.adafruit.com/640x480/2298-16.jpg)

### Adafruit PiTFT 2.2" HAT Mini Kit - 320x240 2.2" TFT - No Touch

[Adafruit PiTFT 2.2" HAT Mini Kit - 320x240 2.2" TFT - No Touch](https://www.adafruit.com/product/2315)
The cute PiTFT got even more adorable with this little primary display for Raspberry Pi in HAT form! It features a 2.2" display with 320x240 16-bit color pixels. The HAT uses the high-speed SPI interface on the Pi and can use the mini display as a console, X window port, displaying images...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2315)
[Related Guides to the Product](https://learn.adafruit.com/products/2315/guides)
![Top down view of a Adafruit PiTFT 2.2" HAT Mini Kit with desktop image on the display. ](https://cdn-shop.adafruit.com/640x480/2315-04.jpg)

You can also get the PiTFT in 3.2" or 2.4", but they don't come with buttons, so you'll want to pick up some of those so you can scroll.

### PiTFT Plus 320x240 3.2" TFT + Resistive Touchscreen

[PiTFT Plus 320x240 3.2" TFT + Resistive Touchscreen](https://www.adafruit.com/product/2616)
Is this not the cutest little display for the Raspberry Pi? It features a 3.2" display with 320x240 16-bit color pixels and a resistive&nbsp;touch overlay. The plate uses the high speed SPI interface on the Pi and can use the mini display as a console, X window port, displaying images or...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2616)
[Related Guides to the Product](https://learn.adafruit.com/products/2616/guides)
![Pink polished finger touching the screen of a PiTFT Plus 320x240 3.2" TFT + Resistive Touchscreen. ](https://cdn-shop.adafruit.com/640x480/2616-00.jpg)

### Adafruit PiTFT 2.4" HAT Mini Kit - 320x240 TFT Touchscreen

[Adafruit PiTFT 2.4" HAT Mini Kit - 320x240 TFT Touchscreen](https://www.adafruit.com/product/2455)
Is this not the cutest little display for the Raspberry Pi? It features a 2.4" display with 320x240 16-bit color pixels and a resistive touch overlay. The HAT uses the high speed SPI interface on the Pi and can use the mini display as a console, X window port, displaying images or video...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2455)
[Related Guides to the Product](https://learn.adafruit.com/products/2455/guides)
![Black polished white finger touching Adafruit PiTFT 2.4" HAT display in a Adafruit PiTFT 2.4" HAT Mini Kit.](https://cdn-shop.adafruit.com/640x480/2455-08.jpg)

### Tactile Switch Buttons (6mm slim) x 20 pack

[Tactile Switch Buttons (6mm slim) x 20 pack](https://www.adafruit.com/product/1489)
Slim clicky momentary switches are standard input "buttons" on electronic projects. These are half the width of classic 6mm tactile switches so they line up better on a breadboard, just plug them into every-other row. These work best in a PCB but <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/1489)
[Related Guides to the Product](https://learn.adafruit.com/products/1489/guides)
![2 white 6mm tactile switch buttons on a breadboard.](https://cdn-shop.adafruit.com/640x480/1489-05.jpg)

Of course you'll need a power supply for your Pi.

### Official Raspberry Pi Power Supply 5.1V 3A with USB C

[Official Raspberry Pi Power Supply 5.1V 3A with USB C](https://www.adafruit.com/product/4298)
The official Raspberry Pi USB-C power supply is here! And of course, we have 'em in classic Adafruit black! Superfast with just the right amount of cable length to get your Pi 4 projects up and running!

Best for use with Pi 4 series, [Pi...](https://www.adafruit.com/product/5814)

In Stock
[Buy Now](https://www.adafruit.com/product/4298)
[Related Guides to the Product](https://learn.adafruit.com/products/4298/guides)
![Angled shot of Official Raspberry Pi Power Supply 5.1V 3A with USB C with Power plug facing down. ](https://cdn-shop.adafruit.com/640x480/4298-04.jpg)

You may want a case for your Pi.

### Official Raspberry Pi Foundation Raspberry Pi 4 Case - Red White

[Official Raspberry Pi Foundation Raspberry Pi 4 Case - Red White](https://www.adafruit.com/product/4301)
Keep your Raspberry Pi® 4 Model B&nbsp;computer safe and snug in this solid ABS acrylic enclosure. Y[ou can even pick up an official case fan + heatsink kit](https://www.adafruit.com/product/4794) to super-charge your Pi 4 projects and keep them cool even under computational...

In Stock
[Buy Now](https://www.adafruit.com/product/4301)
[Related Guides to the Product](https://learn.adafruit.com/products/4301/guides)
![Partially assembled Red and whit Raspberry Pi Foundation Raspberry Pi 4 Case. ](https://cdn-shop.adafruit.com/640x480/4301-03.jpg)

If you have a case, these little header extensions are really useful.

### Stacking Header for Pi A+/B+/Pi 2/Pi 3 - 2x20 Extra Tall Header

[Stacking Header for Pi A+/B+/Pi 2/Pi 3 - 2x20 Extra Tall Header](https://www.adafruit.com/product/1979)
Stack multiple plates, breakouts etc onto your Raspberry Pi Model B+ with this custom-made extra-tall and extra-long 2x20&nbsp;female header. The female header part has extra spaces to make it 23mm tall: when placed on your Pi, a PCB will clear the Ethernet and USB jacks. The stacky pin part...

In Stock
[Buy Now](https://www.adafruit.com/product/1979)
[Related Guides to the Product](https://learn.adafruit.com/products/1979/guides)
![Extra-tall GPIO stacking header.](https://cdn-shop.adafruit.com/640x480/1979-02.jpg)

# PiTFT Python + Pillow Animated Gif Player

## Python Setup

Warning: 

# Attaching
It's easy to use display breakouts with Python and the&nbsp;[Adafruit CircuitPython RGB Display](https://github.com/adafruit/Adafruit_CircuitPython_RGB_Display)&nbsp;module.&nbsp; This module allows you to easily write Python code to control the display.

Since the PiTFT comes preassembled, all you need to do is place it onto the GPIO pins.

Since there's&nbsp;_dozens_&nbsp;of Linux computers/boards you can use we will show wiring for Raspberry Pi. For other platforms,&nbsp;[please visit the guide for CircuitPython on Linux to see whether your platform is supported](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux).&nbsp;

Connect the display as shown below to your Raspberry Pi.

Info: 

Warning: 

For the 1.14":

![](https://cdn-learn.adafruit.com/assets/assets/000/082/903/medium800/adafruit_products_4393-06.jpg?1571866945)

For the 1.3":

![](https://cdn-learn.adafruit.com/assets/assets/000/096/410/medium800/adafruit_products_Pi_MiniTFT_1-3in_plugged_in.png?1603729442)

# Setup

You'll need to install the Adafruit\_Blinka library that provides the CircuitPython support in Python. This may also require enabling SPI on your platform and verifying you are running Python 3. [Since each platform is a little different, and Linux changes often, please visit the CircuitPython on Linux guide to get your computer ready](https://learn.adafruit.com/circuitpython-on-raspberrypi-linux)!

Danger: If you have already installed the kernel module, you will need to remove it by editing your /boot/firmware/config.txt file before proceeding.

## Python Installation of RGB Display Library

Once that's done, from your command line run the following commands:

```terminal
pip3 install adafruit-circuitpython-rgb-display
```

If your default Python is version 3 you may need to run 'pip' instead. Just make sure you aren't trying to use CircuitPython on Python 2.x, it isn't supported!

If that complains about pip3 not being installed, then run this first to install it:

```terminal
sudo apt-get install python3-pip
```

## DejaVu TTF Font

Raspberry Pi usually comes with the DejaVu font already installed, but in case it didn't, you can run the following to install it:

```terminal
sudo apt-get install fonts-dejavu
```

This package was previously calls **ttf-dejavu** , so if you are running an older version of Raspberry Pi OS, it may be called that.

## Pillow Library

We also need PIL, the Python Imaging Library, to allow graphics and using text with custom fonts. There are several system libraries that PIL relies on, so installing via a package manager is the easiest way to bring in everything:

```terminal
sudo apt-get install python3-pil
```

## NumPy Library

A recent improvement of the RGB\_Display library makes use of NumPy for some additional speed. This can be installed with the following command:

```terminal
sudo apt-get install python3-numpy
```

That's it. You should be ready to go.

# Quickstart Button Test
This button test demo will test to make sure you have everything setup correctly. Go ahead and save the file to your Raspberry Pi in your home directory as **rgb\_display\_minipitfttest.py.**

https://github.com/adafruit/Adafruit_CircuitPython_RGB_Display/blob/main/examples/rgb_display_minipitfttest.py

Go ahead and run it with this command:

```terminal
python3 rgb_display_minipitfttest.py
```

Once it is running, push the buttons. The top button should make the display light up **Red** , the bottom **Blue** , and pressing both at the same time should make it **Green**.

## Modifications for the 1.3" Display

To get the **stats.py** example to display properly on the 1.3" TFT Display, you will need to make some changes due to the different geometry of the display. The parameters you will need to adjust are the **height** , **width,**  **x\_offset** , **y\_offset** , and **rotation**.

The new values should be:

- `height = 240`
- `width = 240`
- `x_offset = 0`
- `y_offset = 80`
- `rotation = 180`

The easiest way to replace them may be to copy the following code block and replace it in the above code.

```python
# Create the ST7789 display:
disp = st7789.ST7789(
    spi,
    cs=cs_pin,
    dc=dc_pin,
    rst=reset_pin,
    baudrate=BAUDRATE,
    width=240,
    height=240,
    x_offset=0,
    y_offset=80,
)

# Create blank image for drawing.
# Make sure to create image with mode 'RGB' for full color.
height = disp.width  # we swap height/width to rotate it to landscape!
width = disp.height
image = Image.new("RGB", (width, height))
rotation = 180
```

# PiTFT Python + Pillow Animated Gif Player

## Python Code

Warning: 

Now that we have everything set up, let's dig into the example code. To start with, we have a lot of code imports. Let's go over those:

We start with `os` so that we can access a list of files in the operating system, `time` for doing delays, `digitalio` for button access and display pins, `board` so we can see the pin definitions, and the `Image` and `ImageOps`&nbsp;modules for using Pillow. Then we import all of the displays so that we have a variety of displays to choose from. Since we're not so limited on memory on the Raspberry Pi, it works fine to just import everything.

```python
import os
import time
import digitalio
import board
from PIL import Image, ImageOps
import adafruit_rgb_display.ili9341 as ili9341
import adafruit_rgb_display.st7789 as st7789        # pylint: disable=unused-import
import adafruit_rgb_display.hx8357 as hx8357        # pylint: disable=unused-import
import adafruit_rgb_display.st7735 as st7735        # pylint: disable=unused-import
import adafruit_rgb_display.ssd1351 as ssd1351      # pylint: disable=unused-import
import adafruit_rgb_display.ssd1331 as ssd1331      # pylint: disable=unused-import
```

Next we have the buttons. The defaults are the most common setup, but a few of the displays vary and there is a number right next to the button. If you would like to change it, this is the correct place.

```python
# Change to match your display
BUTTON_NEXT = board.D17
BUTTON_PREVIOUS = board.D22
```

If you had the 1.14" Mini PiTFT, you would change it to something like the following:

```python
BUTTON_NEXT = board.D23
BUTTON_PREVIOUS = board.D24
```

Next, we need to set up the pins that the display will use. We are using the defaults for the PiTFT, though you could do the same thing with a breakout board. If you have a Mini PiTFT, change `reset_pin` to `None`.

```python
# Configuration for CS and DC pins (these are PiTFT defaults):
cs_pin = digitalio.DigitalInOut(board.CE0)
dc_pin = digitalio.DigitalInOut(board.D25)

# Set this to None on the Mini PiTFT
reset_pin = digitalio.DigitalInOut(board.D24)
```

Next, we have a convenience function for initializing the button with the internal pull-up resistor enabled.

```python
def init_button(pin):
    button = digitalio.DigitalInOut(pin)
    button.switch_to_input()
    button.pull = digitalio.Pull.UP
    return button
```

Next we define a `Frame` class. This probably could have been done with a named tuple, since there are no methods, but classes are very readable and it gives the flexibility to add methods. The `Frame` class is used for holding the image and the duration of the frame. This allows for displaying animated Gifs with variable durations.

```python
class Frame:
    def __init__(self, duration=0):
        self.duration = duration
        self.image = None
```

Now to get into the `AnimatedGif` class, which does most of the work. The reason for going with a class is that there are a lot of shared variables that are used in functions and this modularizes everything. A good indicator of whether to use a class is if you need to use the `global` keyword to modify variables.

In the ` __init__ ` function, it is mostly setting each of the internal variables to their defaults and initializing the buttons. If the `width` and `height` are passed in, those are used, otherwise they are extracted from the display object. We also allow the `folder` name to be passed in and if that is present, we will load all the files and automatically run it.

```python
class AnimatedGif:
    def __init__(self, display, width=None, height=None, folder=None):
        self._frame_count = 0
        self._loop = 0
        self._index = 0
        self._duration = 0
        self._gif_files = []
        self._frames = []

        if width is not None:
            self._width = width
        else:
            self._width = display.width
        if height is not None:
            self._height = height
        else:
            self._height = display.height
        self.display = display
        self.advance_button = init_button(BUTTON_NEXT)
        self.back_button = init_button(BUTTON_PREVIOUS)
        if folder is not None:
            self.load_files(folder)
            self.run()
```

Next, we have a pair of functions to either `advance` to the next image or go `back`. They use the modulus operator (`%`) to see if they go beyond the end of the range allowing them to loop back.

```python
def advance(self):
    self._index = (self._index + 1) % len(self._gif_files)

def back(self):
    self._index = (self._index - 1 + len(self._gif_files))  % len(self._gif_files)
```

Next up is the `load_files` function which will grab anything that ends in a **.gif extension** and then go through that list to check if it an animated Gif. Anything that is an animation is added to the `self._gif_files` list. If none are found, it prints a message and exits.

```python
def load_files(self, folder):
    self._gif_files = [f for f in os.listdir(folder) if f.endswith('.gif')]
    for gif_file in gif_files:
        image = Image.open(gif_file)
        # Only add animated Gifs
        if image.is_animated:
            self._gif_files.append(gif_file)

    print("Found", self._gif_files)
    if not self._gif_files:
        print("No Gif files found in current folder")
        exit()
```

The preload function is a bit more complex, so we will break that up a little bit more. It starts by opening the current image and printing out a message to the console.

```python
def preload(self):
    image = Image.open(self._gif_files[self._index])
    print("Loading {}...".format(self._gif_files[self._index]))
    #continued...
```

![](https://cdn-learn.adafruit.com/assets/assets/000/086/710/medium800/raspberry_pi_console_output.png?1578506333)

It continues loading any meta data from the animated Gif such as loop and duration info if available.

```python
self._delay = image.info['duration']
if "loop" in image.info:
    self._loop = image.info['loop']
else:
    self._loop = 1
self._frame_count = image.n_frames
self._frames.clear()
#continued...
```

Then it loops through all the frames of the image. Inside the loop, it starts off by creating a frame object using the `Frame` class and sets the duration for the frame if available, otherwise it uses the default duration for the entire image.

Next it uses the Pillow ImageOps module's `pad()` function to shrink the image to fit on the screen and draws a black border where there is any extra space. To resize the image, the **Nearest Neighbor** method is used. To fill the entire screen and crop off parts of the image, then the `fit()` function could be used instead.

Finally it adds the frame object to the frames list.

```python
for frame in range(self._frame_count):
    image.seek(frame)
    # Create blank image for drawing.
    # Make sure to create image with mode 'RGB' for full color.
    frame_object = Frame(duration=self._duration)
    if "duration" in image.info:
        frame_object.duration = image.info['duration']
    frame_object.image = ImageOps.pad(image.convert("RGB"),
                                      (self._width, self._height),
                                      method=Image.NEAREST,
                                      color=(0, 0, 0),
                                      centering=(0.5, 0.5))
    self._frames.append(frame_object)
```

Now the `play` function will load and play the current image. It starts off by calling the `preload()` function. If there aren't any Gif images to play it will let you know.

Next it will start the looping of the animation and depending on the loop setting, it will either start counting down or continue indefinitely. If it gets down to 1, the looping will end and the function will return `True` indicating the run function should automatically advance to the next image. In between each frame, it will check the value of the buttons, move the index accordingly, and return `False` indicating that we already took care of changing the index and to just play the new index. The delay is taken care of using `time.monotonic()`, which returns a float value of the elapsed time. We use it to get the start time and compare it to the current time. This allows us to take image transfer time into account.

```python
def play(self):
        self.preload()

        # Check if we have loaded any files first
        if not self._gif_files:
            print("There are no Gif Images to Play")
            return False
        while True:
            for frame_object in self._frames:
                start_time = time.monotonic()
                self.display.image(frame_object.image)
                if not self.advance_button.value:
                    self.advance()
                    return False
                if not self.back_button.value:
                    self.back()
                    return False
                while time.monotonic() &lt; (start_time + frame_object.duration / 1000):
                    pass

            if self._loop == 1:
                return True
            if self._loop &gt; 0:
                self._loop -= 1
```

Finally we have the `run` function. Its job is to keep advancing through each of the images in the list and loop back to the start if we hit the end. It the buttons were used to change the image, then it should not automatically advance.

```python
def run(self):
    while True:
        auto_advance = self.play()
        if auto_advance:
            self.advance()
```

Now that we have the classes all defined, we just need a little more setup and it's time to run it. First we initialize the display. The default display is the ili9341, but if you have a different display, feel free to comment out that one and uncomment the one you do have.

```python
# Config for display baudrate (default max is 64mhz):
BAUDRATE = 64000000

# Setup SPI bus using hardware SPI:
spi = board.SPI()

# Create the display:
#disp = st7789.ST7789(spi, rotation=90                             # 2.0" ST7789
#disp = st7789.ST7789(spi, height=240, y_offset=80, rotation=90    # 1.3", 1.54" ST7789
#disp = st7789.ST7789(spi, rotation=90, width=135, height=240, x_offset=53, y_offset=40, # 1.14" ST7789
#disp = hx8357.HX8357(spi, rotation=180,                           # 3.5" HX8357
#disp = st7735.ST7735R(spi, rotation=90,                           # 1.8" ST7735R
#disp = st7735.ST7735R(spi, rotation=270, height=128, x_offset=2, y_offset=3,   # 1.44" ST7735R
#disp = st7735.ST7735R(spi, rotation=90, bgr=True,                 # 0.96" MiniTFT ST7735R
#disp = ssd1351.SSD1351(spi, rotation=180,                         # 1.5" SSD1351
#disp = ssd1351.SSD1351(spi, height=96, y_offset=32, rotation=180, # 1.27" SSD1351
#disp = ssd1331.SSD1331(spi, rotation=180,                         # 0.96" SSD1331
disp = ili9341.ILI9341(spi, rotation=90,                           # 2.2", 2.4", 2.8", 3.2" ILI9341
                       cs=cs_pin, dc=dc_pin, rst=reset_pin, baudrate=BAUDRATE)
```

Next we have some code to swap the width and height parameters depending on the rotation. This is necessary because `RGB_Display` prefers to draw images that take up the full screen.

```python
if disp.rotation % 180 == 90:
    disp_height = disp.width   # we swap height/width to rotate it to landscape!
    disp_width = disp.height
else:
    disp_width = disp.width
    disp_height = disp.height
```

Finally we create the AnimatedGif object. By passing it the current `folder`, it will automatically run.

```python
gif_player = AnimatedGif(disp, width=disp_width, height=disp_height, folder=".")
```

## Full Code
https://github.com/adafruit/Adafruit_CircuitPython_RGB_Display/blob/main/examples/rgb_display_pillow_animated_gif.py

# PiTFT Python + Pillow Animated Gif Player

## Using the Player

## Adding Animated Gifs

You can find animated Gifs all over the internet. A great website for finding a large collection of them is [giphy.com](https://giphy.com/). Once you find them, you'll need to get them over to your Raspberry Pi. The easiest way would be to just use FTP or downloading them directly from the internet on your Pi if that's what you would prefer. Just make sure they're in the same folder as the script.

## Starting the Player

To use the player, open up the command prompt and go to the folder where the script resides. Make sure you have placed all of your animated Gifs in this folder. Once that is done, go ahead and run the command:

`python3 rgb_display_pillow_animated_gif.py`

You should see the animation running on the display:

![](https://cdn-learn.adafruit.com/assets/assets/000/086/709/medium800thumb/raspberry_pi_cat_tp_ili9341.jpg?1578506218)

## Scrolling through Animated Gifs

Some animated Gif files have a limited number of loops, some will loop indefinitely, and some will just play once. If you have any that don't play indefinitely, then the player will automatically advance to the next animated Gif.

If you are viewing one that loops indefinitely, you can get to the next image by pushing the button for advancing or you can go back to the previous image by pushing the other button.

There's definite improvements that can be made to this player, and we wanted to publish what we had to get folks started - feel free to contribute and have fun!


## Featured Products

### Raspberry Pi 4 Model B

[Raspberry Pi 4 Model B](https://www.adafruit.com/product/4297)
The Raspberry Pi 4 Model B is the newest Raspberry Pi computer made, and the Pi Foundation knows you can always make a good thing _better_! And what could make the Pi 4 better than the 3? How about a&nbsp;_faster_ processor, USB 3.0 ports, and updated Gigabit Ethernet chip with...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4297)
[Related Guides to the Product](https://learn.adafruit.com/products/4297/guides)
### Adafruit Mini PiTFT - 135x240 Color TFT Add-on for Raspberry Pi

[Adafruit Mini PiTFT - 135x240 Color TFT Add-on for Raspberry Pi](https://www.adafruit.com/product/4393)
If you're looking for the most compact li'l color display for a [Raspberry Pi](https://www.adafruit.com/category/361) (most&nbsp;likely a [Pi Zero](https://www.adafruit.com/category/813)) project, this might be just the thing you need!

The **...**

In Stock
[Buy Now](https://www.adafruit.com/product/4393)
[Related Guides to the Product](https://learn.adafruit.com/products/4393/guides)
### Adafruit Mini PiTFT 1.3" - 240x240 TFT Add-on for Raspberry Pi

[Adafruit Mini PiTFT 1.3" - 240x240 TFT Add-on for Raspberry Pi](https://www.adafruit.com/product/4484)
If you're looking for the most compact li'l color display for a [Raspberry Pi](https://www.adafruit.com/category/361) (most&nbsp;likely a [Pi Zero](https://www.adafruit.com/category/813)) project, this might be just the thing you need!

The **...**

In Stock
[Buy Now](https://www.adafruit.com/product/4484)
[Related Guides to the Product](https://learn.adafruit.com/products/4484/guides)
### Adafruit PiTFT Plus 320x240 2.8" TFT + Capacitive Touchscreen

[Adafruit PiTFT Plus 320x240 2.8" TFT + Capacitive Touchscreen](https://www.adafruit.com/product/2423)
Is this not the cutest little display for the Raspberry Pi? It features a 2.8" display with 320x240 16-bit color pixels and a capacitive touch overlay.&nbsp;That's right, instead of a resistive touchscreen, which requires a fingernail or stylus, you can now use a fingerpad. The screen...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2423)
[Related Guides to the Product](https://learn.adafruit.com/products/2423/guides)
### PiTFT Plus Assembled 320x240 2.8" TFT + Resistive Touchscreen

[PiTFT Plus Assembled 320x240 2.8" TFT + Resistive Touchscreen](https://www.adafruit.com/product/2298)
Is this not the cutest little display for the Raspberry Pi? It features a 2.8" display with 320x240 16-bit color pixels and a resistive&nbsp;touch overlay. The plate uses the high speed SPI interface on the Pi and can use the mini display as a console, X window port, displaying images or...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2298)
[Related Guides to the Product](https://learn.adafruit.com/products/2298/guides)
### Adafruit PiTFT 2.2" HAT Mini Kit - 320x240 2.2" TFT - No Touch

[Adafruit PiTFT 2.2" HAT Mini Kit - 320x240 2.2" TFT - No Touch](https://www.adafruit.com/product/2315)
The cute PiTFT got even more adorable with this little primary display for Raspberry Pi in HAT form! It features a 2.2" display with 320x240 16-bit color pixels. The HAT uses the high-speed SPI interface on the Pi and can use the mini display as a console, X window port, displaying images...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2315)
[Related Guides to the Product](https://learn.adafruit.com/products/2315/guides)
### PiTFT Plus 320x240 3.2" TFT + Resistive Touchscreen

[PiTFT Plus 320x240 3.2" TFT + Resistive Touchscreen](https://www.adafruit.com/product/2616)
Is this not the cutest little display for the Raspberry Pi? It features a 3.2" display with 320x240 16-bit color pixels and a resistive&nbsp;touch overlay. The plate uses the high speed SPI interface on the Pi and can use the mini display as a console, X window port, displaying images or...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2616)
[Related Guides to the Product](https://learn.adafruit.com/products/2616/guides)
### Adafruit PiTFT 2.4" HAT Mini Kit - 320x240 TFT Touchscreen

[Adafruit PiTFT 2.4" HAT Mini Kit - 320x240 TFT Touchscreen](https://www.adafruit.com/product/2455)
Is this not the cutest little display for the Raspberry Pi? It features a 2.4" display with 320x240 16-bit color pixels and a resistive touch overlay. The HAT uses the high speed SPI interface on the Pi and can use the mini display as a console, X window port, displaying images or video...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2455)
[Related Guides to the Product](https://learn.adafruit.com/products/2455/guides)

## Related Guides

- [Adafruit Mini PiTFT - Color TFT Add-ons for Raspberry Pi](https://learn.adafruit.com/adafruit-mini-pitft-135x240-color-tft-add-on-for-raspberry-pi.md)
- [Running OpenGL-based Games & Emulators on Adafruit PiTFT Displays](https://learn.adafruit.com/running-opengl-based-games-and-emulators-on-adafruit-pitft-displays.md)
- [Processing on the Raspberry Pi & PiTFT](https://learn.adafruit.com/processing-on-the-raspberry-pi-and-pitft.md)
- [OpenClaw on Raspberry Pi](https://learn.adafruit.com/openclaw-on-raspberry-pi.md)
- [Raspberry Pi + Teachable Machine = Teachable Pi](https://learn.adafruit.com/teachable-machine-raspberry-pi-tensorflow-camera.md)
- [Adafruit PiTFT - 2.8" Touchscreen Display for Raspberry Pi](https://learn.adafruit.com/adafruit-pitft-28-inch-resistive-touchscreen-display-raspberry-pi.md)
- [DIY WiFi Raspberry Pi Touchscreen Camera](https://learn.adafruit.com/diy-wifi-raspberry-pi-touch-cam.md)
- [Pocket PiGRRL](https://learn.adafruit.com/pocket-pigrrl.md)
- [Monitor PiCam and temperature on a PiTFT via adafruit.io](https://learn.adafruit.com/monitor-picam-and-temperature-on-a-pitft-via-adafruit-dot-io.md)
- [RasPipe: A Raspberry Pi Pipeline Viewer, Part 2](https://learn.adafruit.com/raspipe-a-raspberry-pi-pipeline-viewer-part-2.md)
- [Running TensorFlow Lite Object Recognition on the Raspberry Pi 4 or Pi 5](https://learn.adafruit.com/running-tensorflow-lite-on-the-raspberry-pi-4.md)
- [Pi Hole Ad Detection Display with PiTFT](https://learn.adafruit.com/pi-hole-ad-pitft-tft-detection-display.md)
- [reef-pi Guide 7: Dosing Controller](https://learn.adafruit.com/reef-pi-guide-5-dosing-controller.md)
- [PiGlass v2](https://learn.adafruit.com/piglass-v2-wearable-raspberry-pi-computer.md)
- [Raspberry Pi LED Matrix Sand Toy](https://learn.adafruit.com/matrix-led-sand.md)
