[Python] Making a gif animation from a set of image files

from PIL import Image,ImageDraw,ImageFont
import os
import re

"""
User Inputs
"""
png = re.compile("png") # Search images that match this suffix
skip = 1 # interval to skip the images (if no skip, 1)
duration = 100 # [ms]
init_duration = 500 # [ms]
last_duration = 500 # [ms]
crop = (0,0,0,0) # left, upper, right, lower [pixel]
enable_caption = True
enable_reverse = True
caption_position = (0.0,0.2) # [0,1]
caption_color = (100,100,100) # [R,G,B] [0-255]
caption_font = ImageFont.truetype("arial.ttf",size=30) # available fonts can be found at C:¥Windows¥Fonts (Windows) or /Library/Fonts/, /System/Library/Fonts/, ~/Library/Fonts/ (MacOS)

'''
Methods
'''
def ImageList(dir,flip_left_right=False,flip_top_bottom=False,crop=(0,0,0,0),show_caption=False,caption_pos=(0.0,0.0),caption_font=None,caption_color=(100,100,100)):
	files = os.listdir(dir)
	images = []
	count = 0
	for file in files:
		if png.search(file):
			im = Image.open(os.path.join(dir,file))
			if flip_left_right:
				im = im.transpose(Image.FLIP_LEFT_RIGHT)
			if flip_top_bottom:
				im = im.transpose(Image.FLIP_TOP_BOTTOM)
			w = im.width
			h = im.height
			if show_caption:
				ImageDraw.Draw(im).text((caption_pos[0]*w,caption_pos[1]*h),f"step {count}",(100,100,100),font=caption_font) # Add caption
			im_crop = im.crop((crop[0],crop[1],w-crop[2],h-crop[3])) # left, upper, right, lower
			images.append(im_crop)
			count += 1
	return images

def Makegif(images,skip,duration,init_duration=None,last_duration=None,reverse=False,name="animation.gif",loop=0):
	mov = [images[i] for i in range(0,len(images)-1,skip)]
	mov.append(images[-1])
	durs = [duration for i in range(len(mov))]
	if init_duration is not None:
		durs[0] = init_duration
	if last_duration is not None:
		durs[-1] = last_duration
	if reverse:
		mov.reverse()
	mov[0].save(name,save_all=True,append_images=mov[1:],optimize=True,duration=durs,loop=loop) # loop=0 specifies infinite loop

'''
Make gif animation
'''
images = ImageList(os.getcwd(),crop=crop,show_caption=enable_caption,caption_pos=caption_position)
Makegif(images,skip,duration,init_duration,last_duration,enable_reverse,"animation.gif")

'''
Appendix: Specify the subdirectory to make another gif animation (images2),
          Concatenate images1 and images2 animations (images_concat)
'''
# images2 = ImageList(os.path.join(os.getcwd(),"folder_name"),crop=crop,show_caption=enable_caption,caption_pos=caption_position)
# Makegif(images2,skip,duration,init_duration,last_duration,enable_reverse,"animation2.gif")

# def Concat_Images(images_1,images_2):
# 	images = []
# 	canvas = Image.new('RGB', (images_1[0].width + images_2[0].width, images_1[0].height), color=(255,255,255))
# 	for i in range(len(images_1)):
# 		dst = canvas.copy()
# 		dst.paste(images_1[i], (0, 0))
# 		dst.paste(images_2[i], (images_1[i].width, 0))
# 		images.append(dst)
# 	return images

# images_concat = Concat_Images(images,images2)
# Makegif(images_concat,skip,duration,init_duration,last_duration,enable_reverse,"animation_concat.gif")
Before running this program, put the Python file into the same directory where the image files are located.
The above gif animation will be generated when you run the Python code.

If you want an mp4 file instead of a gif file, please convert the generated gif animation using the following code:

import moviepy.editor as mp
filename = 'animation'
movie_file=mp.VideoFileClip(filename+'.gif')
movie_file.write_videofile(filename+'.mp4')
movie_file.close()

Tags:

Comments are closed