I earn my living writing content in one form or another. I write for myself, as a ghost writer or as a copywriter for blogs, websites, magazines, businesses or newspapers. One thing that’s always bothered me was the repetitive task of grabbing screenshots from websites. And especially when I am doing roundups or other lists of some kind, it is time consuming and not very funny to take 50+ screenshots of different websites for machine learning frameworks, just to give an example.
So I set out to write a few lines of Python code to help me with this very specific task. That article I linked to earlier is a great example of what this script does. Except the new version doesn’t show scrollbar on the right side since that was annoying.
The result is an unordered list ready for descriptions to make a quick and easy post of any kind using screenshots from websites. Posting to WordPress automatically using xmlrpc.php is an easy way but might not work for all hosts.
I’ve also posted it all on GitHub, so head over there if you prefer.
This has so far only been tested on Windows 7 with Python 3.5 – some modifications might need to take place in order for this to work on other systems.
So recently I’ve been wanting to create a years worth of images with quotes from famous people and then schedule them on various social media for a few different pet projects of mine. Please note that I’m not at all a professional developer, so experienced developers, please brace yourselves.
This post will provide a working example of a very simple, yet powerful enough Python image batch script using Pillow, that iterate through stock images, and combine them with famous quotes and authors from CSV files.
At the end of this tutorial, you can generate hundreds or thousands of unique images with added quotes and their respective authors. I also add support for embedding custom graphics and or optional text for company logos or websites, so you can further customize to your needs.
And last but not least I show off the opacity function for overlays, separating the quote texts from the backgrounds.
What you will end up with, could be something like this.
I might update the code later with an added transparent image overlay containing a few swirls and lines to give the image a bit more panache, but the main purpose is to show you how to generate images in batch, not give a lesson in design.
As of writing, there are some issues with the functionality of the code, such as some text being incorrectly padded like this:
Another quite big issue is the fact that the first line is set to simply just use a fixed width, meaning that for quotes particularly, oftentimes it just looks wrong, such as this one:
As I’m not using this script for anything, I doubt I’ll get around to updating it, but I mention it as I hope someone might comment with a quick solution.
It should also be noted that I by no means encourage you to just use this code as I am neither a professional developer, nor am I read up on any theory regarding best practices. (Read: the code is most likely horrible)
So, first we need an installation of Python, I use the lastest version. So create a folder named after you liking, this folder will contain the entire script, including folders for images and CSV files.
Create your main script, name it whatever you like, I will just refer to this as:
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
First few lines are importing and assigning the libraries we need, namely Pillow, csv and textwrap. If you are new to Python and the above lines are throwing an error, look into package managers, and install the needed modules.
The way I have structured things in this script are as follows:
The authors and quotes are split up for my own benefit, as I originally wrote this script for movie quotes where I needed to link various data from 2 separate files. I’ve left it like this, since it might provide some additional functionality that would otherwise be left out. Feel free to change it.
The folder called /in/, are simply containing a list of JPG’s that I’ve downloaded from various CC0 image archive sites, such as Pexels and Pixabay.
The folder called /out/ are used to store the newly generated images.
I then run a simple windows .bat file thats simply located inside the /in/ folder to rename all files to my liking. This way I could even match up quote #4 with image #4 if I wished to.
ren *.jpeg *.jpg
for %%a in (*.jpg) do (
ren "%%a" "!i!.new"
set /a i+=1
ren *.new *.jpg
As you can see, both CSV files are simply separated by line breaks.
This is the first time I write a tutorial that covers more than a few lines of code, so I hope you can bear with my bad commenting, and even worse quality of code and formatting. Below is the full script.
#BIMP - Batch Image Manipulating with Python
Author; Mark Pedersen @makerspender
License: CC BY 2.0 https://creativecommons.org/licenses/by/2.0/
#load required libraries
from PIL import ImageFont
from PIL import Image
from PIL import ImageDraw
#create lists to store quotes and authors in
lines = [line.rstrip() for line in open('quotes.csv')]
authors = [author.rstrip() for author in open('authors.csv')]
#start the for loop
for idx, val in enumerate(lines):
#echo each quote and author
#create main quote value
para = textwrap.wrap(val, width=40)
#set image dimensions
MAX_W, MAX_H = 1920, 1280
#set image location
imageFile = "D:\imgapp\in\%s.jpg" %idx
#assign im to pillow and open the image
im = Image.open(imageFile).convert('RGBA')
#resize the image to our chosen proportions and use antialiasing
im = im.resize((1920, 1280), Image.ANTIALIAS)
#create new layer for adding opacity
poly = Image.new('RGBA', (1920,1280))
polydraw = ImageDraw.Draw(poly)
#fill the image with black and 165/255 opacity
polydraw.rectangle([(0,0),(1920,1280)], fill=(0,0,0,165), outline=None)
#paste in the layer on top of the image im
#command to start merging layers
draw = ImageDraw.Draw(im)
#setting up fonts
font = ImageFont.truetype("C:\Windows\Fonts\ArchivoBlack-Regular.ttf",80)
authorfont = ImageFont.truetype("C:\Windows\Fonts\Roboto-BlackItalic.ttf",60)
linkfont = ImageFont.truetype("C:\Windows\Fonts\Roboto-Black.ttf",24)
#setting up padding and positioning for quote text
current_h, pad = 300, 50
#for loop breaking up each quote into lines not exceeding the width of the image dimensions
for line in para:
w, h = draw.textsize(line, font=font)
draw.text(((MAX_W - w) / 2, current_h), line, font=font)
current_h += h + pad
#setting up padding and positioning for author text
current_h2, pad2 = 900, 80
currentauthor = authors[idx]
w, h = draw.textsize(currentauthor, font=authorfont)
draw.text(((MAX_W - w) / 2, (current_h + 100)), currentauthor, font=authorfont)
current_h2 += h + pad2
#setting up padding and positining for optional text
current_h3, pad3 = 1200, 30
sitelink = "Batch Image Manipulating with Python"
w, h = draw.textsize(sitelink, font=linkfont)
draw.text(((MAX_W - w) / 2, current_h3), sitelink, font=linkfont)
current_h3 += h + pad3
#loading optional logo and converting to RGBA for transparency support
logo = Image.open('logo.png').convert('RGBA')
logo_w, logo_h = logo.size
im.paste(logo, (50,1150), logo)
#saving the image to our chosen location
I’ve used the official pillow documentation extensively, and while I had an idea that there would be plenty of tutorials out there offering a quick and better solution than the one I came up with, I couldn’t find any complete package.
So while the above code is neither pretty nor optimal, it works for the intended purpose, and hopefully can serve as inspiration or a bootstrap for your own projects.
Please let me know in the comments whether I’ve made a giant error, if you have updates, fixes or wishes for new features.