So we want to cut out the individual frames from this image, put them in the right order, then stitch them into an animated GIF.
First we load the image with Pillow:
from PIL import Image im = Image.open("artichoke.jpg")
We can crop a rectangle from an image using the crop() function, which takes the four corners of the area we want to crop. For example, this code:
crop()
im_cropped = im.crop((500, 1000, 800, 700))
will extract this part of the image:
I started by writing a function that produces the 4-tuples that are passed to the crop() function. It moves from left-to-right, top-to-bottom, finding the coordinates of the crops:
def get_crops(im, *, columns, rows): column_width = im.width // columns row_height = im.height // rows for r in range(rows): for c in range(columns): x = c * column_width y = r * row_height yield (x, y, x + column_width, y + row_height)
and then I get the individual images like so:
individual_scans = [ im.crop(c) for c in get_crops(im, columns=7, rows=4) ]
The exact number of individual scans varied from image to image (for example, the sagittal view of a pumpkin has 6 columns and 3 rows), so parameterising the crops was quite handy.
Now we save the individual frames as an animated GIF, which is a one-liner in Pillow:
individual_scans[0].save( "artichoke.gif", save_all=True, append_images=individual_scans[1:] )
It’s possible to adjust the speed by passing a duration parameter, but the default seemed fine. I’m sure there’s more fun to be had by making the animation speed up or slow down at certain points!
duration
You can download all the code from this post in this file:
make_artichoke_gif.py
And if you haven’t looked already, I really recommend getting a big monitor and reading my original post. There are pumpkins, parsimmons, passion fruit, and all sorts of other mesmerising images made entirely from MRI scans.