Intro

As hinted at above, this project started with a very real problem a friend of mine was having. He streams frequently on Twitch, where he plays a variety of video games to entertain his audience. He wanted to get in the habit of announcing what he was playing in advance to keep his audience informed. To do this, he was putting together these nice infographics that showed the stream schedule for the week. However, these infographics were time-consuming to put together: they take about 20 minutes in Photoshop to combine a premade template with relevant game box art, text, effects, and so on. While it was only 20 minutes a week, this time does add up quickly. We were talking about this problem and I realized that this sort of task is something that would work really well if automated. I offered to take a crack at the problem of automating the process, and this project is what spawned of it.

After some discussion, I realized that the key requirements for the application were:

In spite of the requirement for portability, I found that Python was one of the most suitable choices for a program like this. It makes extensive use of external libraries to do specific steps of the processing of the schedule, such as box art retrieval and image generation. Although, it turns out that this lack of portability from Python (remember, we don't want you to have to install the Python interpreter to use it) was a non-issue, as discussed below.

Image Transformation

Before we talk about how the application retrieves game box art, let's talk about how it would actually process that box art. As hinted at above, this is an area where Python is a beneficial choice for the application. Python has access to libraries such as Pillow which are great for image processing. In this program, that's the library I used.

One of the main components of the software is a class I called the ImageProcessor. It is responsible for taking in all box art images, applying transformations and stitching all the images together. Here's a quick rundown of the process it applies:

  1. Loads all the box arts and the template to be used.
  2. Applies gradients to each box art to darken them slightly.
  3. Adds text to each box art image (either name of the game or a custom label).
  4. Superimpose the box art images onto the template image at the right locations to combine them all into one.

IGDB API

The biggest challenge I noticed in the requirements is game box art. How is the application going to get box art for a game if I don't know in advance what he's going to play? I can't get him to find and download the box art because that defeats the point of the application - it's supposed to be fast. Thankfully, there was a solution - IGDB.

IGDB is an online, public database for Twitch video game data. It includes data for every game category possible on Twitch, and that includes box art of video games. After a bit of research I found out that IGDB has an API, and after a couple hours of experimenting I managed to get access to it working. My plan was to use IGDB to serve my application the box art images when it needs them during schedule construction.

For games with no box art, or for non-game streams, I put together a custom image that the application could use. It fit the same size as the box art images and was a generic filler image that clearly indicated that it was a Twitch stream.

One issue I ran into was getting the API requests formatted correctly. For whatever reason I could not figure out what fields were needed (the documentation for this wasn't great) and could not get it working manually. Thankfully, I found a Python library that served as a wrapper for IGDB API calls, which saved me a lot of trouble. However, this posed an issue: it locks me in to using Python for the application. I am a really big fan of Python and normally this is not an issue, but the usage of Python conflicted with the requirement for "easy installation". Since Python is not a compiled language, if I were to share a Python program with my friend, it would require him to download Python and do all this technical stuff to get the dependencies configured. This was a problem. How was I going to make the application portable if it uses Python? Turns out the answer was simpler than I thought.

Py-2-EXE

As a Python developer, and as someone who frequently explores Python libraries, I have encountered libraries such as Py2EXE, which claim to "compile" Python code into a portable EXE file. I've been fascinated by the idea, but from what I understand the usage of these tools is very limited. They have many incompatibilities with external Python libraries, and are generally regarded as "unreliable" as far as whether or not your application will compile. They work by bundling your Python code with a copy of the Python interpreter all together into an EXE file so that the Python code has everything it needs to run, in a "portable" environment.

Given that the application I had made was pretty simple (only relying on a couple of libraries) I decided to give it a shot and see if it would work. To my surprise, it worked! My application didn't cause problems during compilation, and the resulting EXE file ran correctly and was able to assemble schedules!

I did a pilot run with my friend to see if it would work, and after sorting out some issues regarding the API key and how to share it, I managed to get a copy that could run on his computer. Success! We had a program that could automatically assemble schedules for him.

The Result

The final program is a terminal application (run through an EXE) that prompts the user for the titles of three games to stream: one for Monday, Wednesday and Friday respectively. For each game, it uses the IGDB API to query the database, find the closest match and download a copy of the box art locally. The user could also enter the prompt "???" any time they wanted to specify no game for a particular day, in which case the program would fall back on the default box art image I made. Once the three prompts were entered, the program combined the template image with the box art, overlayed some text and shadowing effects and produced a schedule image that could be used. From timing the application, it took about 20 seconds to do everything, but that mostly comes from the time it takes for the user to enter in the prompts and download the box art, not from the computation. The image processing was done in under a second usually.

Here's an example of the image that the program produces. The purple frame around the box art is a template that I created from some of the old schedules made manually by my friend. I cut out the sections in the middle where the box art would go and made them transparent so they could be overlayed easily.

Fun fact about this image: this is the very first schedule generated by the program to be used for his streams!

Here's another example of a real schedule produced by the application that went on to be used for his streams. This one showcases the "default game box art" image I produced on Friday. The application lets you label each game selection independently of what the game is actually called, so the Friday stream was titled "Community Day".

Overall, I consider the project to be a massive success. The program works 100% fine, and it made the life of my friend a lot easier.

You can find the source code for this project, as well as installation instructions, on my GitHub. I'll admit the program isn't 100% flexible: after all, I was building it for a very specific use case. If anyone has any interest in re-using this for their own streams, feel free to make a fork of it and modify it however you see fit.