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

Raspberry Pi Download Machine Part 2

Well SSH is Boring I have got my RPi download machine up and running and having success, unfortunately though SSH is annoying and tedious, so I am gonna do something about it. But a disclaimer; this is my first time working with Aria2 in the most part. RPC  Remote Procedure Call is fancy way of saying 'make this thing make that thing do a thing'. So I ran the command to load the config file (and added to my init file) in the last post and ..... BOLLOCKS ALL. So ran the command again, and need to check the processes (like Task Manager). pi@raspberrypi : ~ $  ps aux | grep aria2c root       524  0.0  0.9  17028  9284 ?        Ss   21:21   0:00 aria2c --conf-path=/home/pi/.aria2/aria2.conf pi        1008  0.0  0.2   4272  1948 pts/0    S+   21:34   0:00 grep --color=auto aria2c There it is, that little scumbag. But still no dice. In the conf file I stated that the rpc-port to be 6800 so need to check that port.  A quick note on ports, every service

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

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 ima