Note:
I’m using Ubuntu 16.04 to play.
Week 1: Making GIFs
It’s not my first attempt at creating moving images. Each time I met with a problem that stopped me in my tracks until I ran out of steam and lost interest. But now two changes brought me success!
First I found out that Pillow 3.4.0 can now save images sequences!
Second I discovered Gizeh, a very nice library written by Zulko. Gizeh is a wrapper for cairocffi, which is a Python binding for Cairo, which is a 2D graphics library written in C… Lots of things to learn!
I did get into some trouble while installing Gizeh. Pip installed a version that was different from what is available on github. I didn’t have access to some elements (ellipse, bezier_curve, more?). To fix this I just replaced the gizeh.py file on my computer with the one from github.
To help with the gif making process I made an image viewer using Pillow and Tkinter. Mixing those two also gave me trouble. For some reason ImageTk was missing and I had to install python-pil.imagetk (thanks to saulspatz). After I managed to get the viewer running it was trivial to make a GIF from my pictures. By the way, do you know about Lena Söderberg?
Once I learened to make GIFs the next step was to learn how to draw my own images. Being lazy I used Gizeh’s square example as a starting point. The idea was to have those squares revolve.
I learned a lot with this little project. Not only about code but also about animation. (Getting a gif to loop perfectly can be tricky)
ps. Don’t forget to read about beautiful Lena
Here’s the code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
import os import gizeh as gz import numpy as np from PIL import Image def rotating_squares(name): SIZE = 400 # dimension of the final picture fps = 30 frames = 30 # how many frames in the GIF temp_name = 'frame_' # prefix for temporary png files temp_files = [] # our list of png files # We generate n_squares random values of size, angle, color, position. # 'rand' is a function that generates numbers between 0 and 1 n_squares = 100 sizes = 20 + 40 * np.random.rand(n_squares) angles = 2*np.pi * np.random.rand(n_squares) colors = np.random.rand(n_squares, 3) positions = SIZE * np.random.rand(n_squares, 2) # draw our frames and save temporary files as .png for frame in range(0,frames): surface = gz.Surface(SIZE, SIZE, bg_color=(0,0,0)) for angle, size, pos, color in zip(angles, sizes, positions, colors): angle = (np.pi/frames) * frame / 2 + angle # rotate the square square = gz.square(size, xy=pos, angle=angle, fill=color, stroke_width=size/20) square.draw(surface) frame_name = temp_name + str(frame) + '.png' temp_files.append(frame_name) surface.write_to_png(frame_name) # build the gif sequence = [] for file in temp_files: sequence.append(Image.open(file)) # load png files as Pillow images sequence[0].save(name, save_all=True, append_images=sequence[1:], duration=1000/fps, loop=0) # clean up our temporary png files for file in temp_files: os.remove(file) if __name__ == '__main__': rotating_squares('test.gif') |