Skip to content

Instantly share code, notes, and snippets.

@benman1
Created October 26, 2020 16:23
Show Gist options
  • Save benman1/a873350c827f5cbdb2e58986ab576c80 to your computer and use it in GitHub Desktop.
Save benman1/a873350c827f5cbdb2e58986ab576c80 to your computer and use it in GitHub Desktop.
Create a poster based on a video. This can be useful for educational videos for your children.
# # Recipe for creating a poster based on a video
#
# 1. download a video (for example, youtube-dl)
# 2. extract images from the video, say every second one frame (ffmpeg)
# 3. choose the images you want and delete the images you don't want
# 4. (this notebook) align the images horizontally and vertically based on the numbering
# got this part from https://note.nkmk.me/en/python-pillow-concat-images/
from PIL import Image
def get_concat_h(im1, im2):
dst = Image.new('RGB', (im1.width + im2.width, im1.height))
dst.paste(im1, (0, 0))
dst.paste(im2, (im1.width, 0))
return dst
def get_concat_v(im1, im2):
dst = Image.new('RGB', (im1.width, im1.height + im2.height))
dst.paste(im1, (0, 0))
dst.paste(im2, (0, im1.height))
return dst
import os
# get all the image files in a directory:
imagepath = '/Users/ben/Dropbox/nico/animals/'
images = [image for image in os.listdir(imagepath) if image.endswith('jpeg')]
import re
def get_number(filename):
"""This is for ordering the images. Each image should
have a number in the filename.
"""
return int(re.search(r'[0-9][0-9]*', filename).group())
images = sorted(images, key=lambda item: get_number(item))
# ncols is the one parameter you need to set. This is the number of columns in the poster.
# ncols - The number of images in one row
ncols = 4
rows = []
row = []
for image in images:
row.append(Image.open(os.path.join(imagepath, image)))
if len(row) >= ncols:
rows.append(row)
row = []
if len(row) > 0:
nblanks = ncols - len(row)
for bl in range(nblanks):
# The background is set to white:
row.append(Image.new('RGB', row[0].size, (255, 255, 255)))
rows.append(row)
if len(rows) % 2 == 1:
row = []
for bl in range(ncols):
row.append(Image.new('RGB', rows[0][0].size, (255, 255, 255)))
rows.append(row)
def grouped(iterable, n=2):
"""return iterator over n objects
"""
return zip(*[iter(iterable)]*n)
def concat_images(horiz_images, op=get_concat_h):
"""this concatenates horizonally or vertically
(depending on the operation specified by the op parameter)
"""
while len(horiz_images) > 1:
new_image = []
for image1, image2 in grouped(horiz_images, 2):
new_image.append(op(image1, image2))
horiz_images = new_image
return horiz_images
# first: horizontally concatenating in order to get the rows
image_rows = []
for row in rows:
image_rows.append(concat_images(row)[0])
# second: vertically concatenating the rows in order to get the whole poster
image = concat_images(image_rows, op=get_concat_v)[0]
# save the image:
image.save(
os.path.join(imagepath, 'animal_poster.png'),
dpi=(350, 350)
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment