Description
A developer's journey through code. I build, I break, and I write about it. Explore articles on modern software development, programming tips, and more.
Bring images to life with animated GIFs! These are like mini-cartoons made up of a sequence of slightly different pictures. Imagine a flip book where a stick figure changes a little on each page. Flipping quickly creates the illusion of movement. In this article we are going to cover both how to create and how to view GIF with Python, but first let us start with how to create an animated GIF with Python.
Ready to make your own? Python's Pillow library can help!
Before we proceed to creating GIFs, let us ensure you have the necessary tools required to get started.
python3 -m pip install Pillow
To create an animated GIF, you will need multiple images displayed sequentially. Here are two methods for acquiring these frames:
Let us begin by learning how to convert a series of image files (like JPGs) into an animated GIF. Create a new Python file named "gif_maker.py" and paste the following code:
import glob
from PIL import Image
def make_gif(frame_folder):
frames = [Image.open(image) for image in glob.glob(f"{frame_folder}/*.JPG")]
frame_one = frames[0]
frame_one.save("my_awesome.gif", format="GIF", append_images=frames,
save_all=True, duration=100, loop=0)
if __name__ == "__main__":
make_gif("/path/to/images")
Let me breakdown the code for a better understanding:
Importing Libraries: We begin by importing the glob module from Python's standard library and the Image class from the Pillow library. glob helps us search for files matching a specific pattern, in this case, JPEGs within a designated path.
Gathering Images: The make_gif function takes a path as input. We use glob to find all JPG files within that path and store them in a Python list.
Note: If your images are large, consider resizing them before creating the GIF to avoid creating a massive file.
Creating the Animation: Once we have the list of images, we use Pillow's save function to create a GIF. The first image in the list is used as the base, and the append_images parameter specifies the remaining images as frames for the animation. We set save_all to True to ensure all images are included.
Customizing the Animation: The duration parameter allows you to control the display time of each frame in milliseconds. Here, we set it to 100 milliseconds. The loop parameter determines how many times the animation repeats. Setting it to 0 creates a continuously looping GIF, while a value greater than 0 specifies a finite number of loops.
Testing the Code: You can experiment with this code using a provided zip archive containing hummingbird images. Unzip the archive and run the code. The resulting GIF will resemble the provided animation below.
Using a tripod to capture your photos will significantly enhance the smoothness of the final animation. The shakiness from handheld shots disrupts the flow when converted to a GIF. Rerun the code with tripod-captured images for a noticeably smoother animation.
Pillow empowers you to draw various shapes directly onto image objects. This functionality unlocks the creation of frame-by-frame animations, Our example will showcase drawing circles using Pillow's ellipse function. Remember, you can also create arcs, lines, rectangles, polygons, and more.
Let us Get Animated!
Begin by creating a new Python file and incorporating the following code:
from PIL import Image, ImageDraw
def draw_circle(x, y, offset):
"""
Creates an image with a red circle at the specified coordinates.
Args:
x (int): The x-coordinate of the circle's center.
y (int): The y-coordinate of the circle's center.
offset (int): The radius of the circle.
Returns:
Image: The newly created image with the drawn circle.
"""
image = Image.new("RGB", (400, 400), "blue")
draw = ImageDraw.Draw(image)
draw.ellipse((x, y, x + offset, y + offset), fill="red")
return image
def make_animation():
"""
Generates a GIF animation showcasing a bouncing circle.
"""
frames = []
x = 0
y = 0
offset = 50
for _ in range(20): # Using underscore for loop counter variable
frames.append(draw_circle(x, y, offset))
x += 35
y += 35
frames[0].save("circle.gif",
format="GIF",
append_images=frames[1:], # Slicing to exclude first frame
save_all=True,
duration=100,
loop=0)
if __name__ == "__main__":
make_animation()
The core logic resides within the make_animation function. Here, we construct a loop that iterates 20 times, generating an image with a circle at each iteration and appending it to the frames list.
The draw_circle function encapsulates the circle creation process, taking the x and y coordinates along with the offset (radius) as arguments. It then constructs a blue-backed image and utilizes Pillow's ellipse method to draw the desired circle. Execute the code, and you will witness a GIF animation depicting a bouncing red circle!
This example provides a foundation for crafting frame-by-frame animations using Pillow. Feel free to experiment with various shapes, colors, movements, and timings to bring your creative visions to life!
Experiment by drawing different shapes, change your code to use a rainbow of colors, or even animate multiple bouncing balls on the screen and you will see the possibilities are endless. Beyond the Basics Pillow's power extends far beyond creating animations. You can edit photos, add artistic filters, adjust image contrast, and much more.
Ever wanted to display those captivating animated GIFs you see on social media? While creating them is a skill in itself, Python allows you to showcase them with ease. Let us explore various methods for viewing animated GIFs using Python.
Get ready to unlock the power of animation with these approaches:
Before diving in, you will need an animated GIF which I have taken time to teach above which you should read before getting to this stage of this article. For this tutorial, we will use a lighthearted "hello world" example GIF created with Asciimatics, a Python library for building text-based user interfaces.
For future reference, save the animated GIF as asicmatics_hello.gif on your computer. This will allow you to use it in the examples throughout this tutorial.
There are several methods for displaying animated GIFs using Python. One popular approach leverages tkinter, Python's built-in GUI library. The following code demonstrates a refined example based on a suggestion I found on StackOverflow:
from tkinter import *
from PIL import Image, ImageTk
class MyLabel(Label):
def __init__(self, master, filename):
im = Image.open(filename)
seq = []
try:
while 1:
seq.append(im.copy())
im.seek(len(seq)) # skip to next frame
except EOFError:
pass # we're done
try:
self.delay = im.info['duration']
except KeyError:
self.delay = 100
first = seq[0].convert('RGBA')
self.frames = [ImageTk.PhotoImage(first)]
Label.__init__(self, master, image=self.frames[0])
temp = seq[0]
for image in seq[1:]:
temp.paste(image)
frame = temp.convert('RGBA')
self.frames.append(ImageTk.PhotoImage(frame))
self.idx = 0
self.cancel = self.after(self.delay, self.play)
def play(self):
self.config(image=self.frames[self.idx])
self.idx += 1
if self.idx == len(self.frames):
self.idx = 0
self.cancel = self.after(self.delay, self.play)
class Main():
def __init__(self):
root = Tk()
self.anim = MyLabel(root, 'asciimatics_hello.gif')
self.anim.pack()
Button(root, text='stop', command=self.stop_it).pack()
root.mainloop()
def stop_it(self):
self.anim.after_cancel(self.anim.cancel)
main = Main()
This code utilizes the tkinter library to create a Label widget. Labels can display various elements, including images. In this example, we will extract individual frames from a GIF and store them within a list named self.frames. Each frame will be an instance of ImageTk.PhotoImage. To achieve animation, we will leverage Tkinter's after() method. This method schedules the play function to be called again after a brief delay, effectively creating a loop that iterates through the frames.
Running this code should display the GIF animation:
Tkinter treats GIFs differently than some other image formats. While the animation itself will play, the colors may not be displayed accurately. If you require full color support for your GIFs, you might need to explore alternative GUI libraries like PySimpleGUI.
Tkinter is not the only option for creating graphical user interfaces (GUIs) in Python. PySimpleGUI, a library that works with Tkinter, wxPython, and PyQt, can also be used. Since PySimpleGUI is not included by default in Python, you will need to install it using pip:
python -m pip install pysimplegui
Once installed, you can start writing code. The following example is inspired by one found on the PySimpleGUI GitHub repository.
import PySimpleGUI as sg
from PIL import Image, ImageTk, ImageSequence
gif_filename = 'asciimatics_hello.gif'
layout = [[sg.Image(key='-IMAGE-')]]
window = sg.Window('Window Title', layout, element_justification='c', margins=(0,0), element_padding=(0,0), finalize=True)
interframe_duration = Image.open(gif_filename).info['duration']
while True:
for frame in ImageSequence.Iterator(Image.open(gif_filename)):
event, values = window.read(timeout=interframe_duration)
if event == sg.WIN_CLOSED:
exit(0)
window['-IMAGE-'].update(data=ImageTk.PhotoImage(frame) )
This code is more concise than the Tkinter example, making it easier to read and manage. Why not give it a run and see the results? Now you are ready to view a GIF directly within your Jupyter Notebook so let us get to it.
Jupyter Notebooks offer a fantastic way to combine code, explanations, and interactive elements. You can use them to create presentations, showcase code examples with their outputs, and even build interactive widgets. The good news is, Jupyter Notebooks also allow embedding images, including animated GIFs.
Installation:
To follow along, you will need Jupyter Notebook installed. Luckily, it is just a pip install away:
python -m pip install jupyter
Launching Jupyter Notebook:
Once installed, open your terminal and run:
jupyter notebook
This will launch Jupyter in your default web browser.
Creating a New Notebook:
In the top right corner of the newly opened webpage, click the "New" button. You will see a few options - choose "Notebook" (the topmost choice). This will open a new browser tab where you might encounter a pop-up asking you to select a kernel. The default (Python 3) is usually the right choice, so proceed with that.
Switching to Markdown Mode:
Locate the dropdown menu near the top of your Jupyter Notebook window labeled "Code". Click on it and change the selection to "Markdown". This will switch the current cell from code mode to markdown mode, which is what you need for displaying images.
Embedding the GIF:
Paste the following code into your cell:

Note: Replace asciimatics_hello.gif with the actual filename of your GIF. Make sure the GIF is in the same folder as your Jupyter Notebook, or provide the complete file path if it is located elsewhere.
Running the Cell:
To display the animated GIF, run the cell. You can either click the "play" button in the toolbar or press SHIFT+ENTER. If everything works as expected, you should now see your animated GIF displayed within the Jupyter Notebook cell as shown below:
Python offers several approaches to display animated GIFs. The Tkinter library, included in the standard library, provides functionalities for creating graphical user interfaces (GUIs) that can render GIFs. Alternatively, the PySimpleGUI library simplifies GUI development, potentially making it easier to integrate animated GIFs. Finally, Jupyter Notebook, a popular environment for interactive computing, allows embedding and displaying GIFs directly within notebooks.
This is not an exhaustive list, and there might be other libraries or tools suitable for your specific needs. Feel free to share your preferred method or any interesting packages you have encountered in the comments section below.
Cookies improve user experience on SunshineIHCTS. By continuing to use this website, you consent to the use of cookies in accordance with the Privacy policy.
A developer's journey through code. I build, I break, and I write about it. Explore articles on modern software development, programming tips, and more.
Comments section
You need to be logged in to comment, Login or Register.Approved comments:
Mbam Clinton in 2024-04-04 12:31:24
Well explained, thank you.
Reply You need to be logged in to reply to this comment, Login or Register.
_SunshineIHCTS in 2024-10-19 09:15:44
_Welcome 🤗
VincenZöArt in 2024-04-04 12:38:28
You have done well Sir.
Reply You need to be logged in to reply to this comment, Login or Register.
_SunshineIHCTS in 2024-10-19 09:16:23
_You're welcome Vincenzo.