Skip to main content

Adventures with Pillow Part 1

I am in the middle of building an app and need to put together several promo videos for Twitter and Instagram, and man it is boring. So I thought 'how can I automate this process?', so welcome to this post.

What I am going for is a selection of images, greyscaled flipping through with our logo on the front. So my approach was to use python, pillow and ffmpeg to build something. This could be disastrous.


To start a few pre-flight checks, a variable for the test image and to check for/create a processed folder for the final images to go.

import os, errno
from PIL import Image, ImageFont, ImageDraw
testImage = 'test.png' cwd = os.getcwd()
image_dir = os.path.join(cwd, 'images')
default_dir = os.path.join(cwd, 'processed')try:
    os.makedirs(default_dir)except OSError as e:
    if e.errno != errno.EEXIST:

I am going to build a function that will do all of the processing, but first going to run on one image before looping through all of the one I need. The first process is to resize image. This is just going to social media promo video so I don't want massive images. I do this simply with the thumbnail method. Using will display the image on your OS, on mac will open in preview.

def processImage(imageFile):
    # Resize image    maxsize = (1000, 1000)
    im =

Next I want to crop out the centre to give me a nice square image. The final square image is gonna be 600px x 600px. The crop function will take the top left corner and crop a box of dimension. I have the latter but to get the start location I will have to get the size of the height of the image, divid by 2 and minus 300px, then the same for the width.

def processImage(imageFile):
    # Resize image    ...

    # Crop center of an image out    halfCropArea = 300
    halfWidth = im.size[0] / 2    halfHeight = im.size[1] / 2    startWidth = halfWidth - halfCropArea
    startHeight = halfHeight - halfCropArea
    cropWidth = halfWidth + halfCropArea
    cropHeight = halfHeight + halfCropArea

    cropped = im.crop((startWidth, startHeight, cropWidth, cropHeight))

Next I need to convert to greyscale. will simply use a convert but will look in to filters another time.

def processImage(imageFile):

    # Apply greyscale    greyscale = cropped.convert('LA')
    img = greyscale.convert('RGB')

Finally to add the logo which is set to 144px square. To set in the middle I set (600 -144)/2 = 228 to top left and then 228 + 144 for bottom right.

def processImage(imageFile):

    # Add icon    iconImage ='icon.png')
    img.paste(iconImage, (228, 228, 228 + 144 , 228 + 144))

Now I am gonna save to the new folder and also added an argument to the function for a new filename.

Movie Time

To get all of the images processed, I am gonna look at the folder with all of the images in and then loop through them. These going to be the frames of my video.

def processFolder():
    images = os.listdir(image_dir)
    for count, image in enumerate(images):
        filename = '%04d.png' % count
        imageFile = os.path.join(image_dir, image)
        print filename, imageFile
        processImage(imageFile, filename)


Inside the directory with my script I have put the ffmpeg library and just run the command form the script.

os.system('./ffmpeg -f image2 -r 2 -i ./processed/%04d.jpg -y -an -vf fps=30 -crf 25 -vcodec libx264 ./processed/video.mp4')

And Voila!!!


Popular posts from this blog

Adventures in Pillow Part 2

From my last post where I made a slideshow promo video, I realised how powerful Pillow is. I still have a fair bit of automation to do, so another thing I do a lot of is motivational quotes for Twitter (I am aware they are fucking stupid, but they share well)

The breakdown of the components are a background with a filter, the quote, who said it and our logo.
Background and Filter To start off I am going to create a folder called quote and add in an image and just name it background.jpg (sourced from Pixabay). Next I import PIL and open the file.
from PIL import Image import os, errno cwd = os.getcwd() image_dir = os.path.join(cwd, 'quote') def filterImage(imageFile): im = filterImage(os.path.join(image_dir, 'background.jpg'))

Next I need to crop the image. I am going to take the centre portion out of the image to make square. Like so:
So I start off with getting the dimensions of the image with:
I get a tuple of (1920, 1…

Raspberry Pi Download Machine Part 1

Yet Another Raspberry Pi Project Kodi builds, weird fucking robots and classic gaming always seems to be the theme of RPi projects. But a stat I would like to know is how many are just sat in a drawer somewhere. Anyway I am part of that number, until now. I manage to find a 4TB drive and managed to blag a caddy, so with this triangle of 'crap hanging around' I thought I'd build a downloader.

Open Directories So I first had the idea from the sub-reddit open directories, here storage devices are opened up to the internet without a morsel of authentication. Google comes along and indexes them and you can go and find them. Decent ones find themselves on this sub of which I assume stays up until the user realises that there broadband is getting absolutely raped.
So I wanted to be able to get a URL from a server and just throw it in a WebUI and get it to auto download and ping me when all is finished. 

First Steps So to start off I downloaded Raspbian Jessie Lite from 2017-07-0…