Artists and designers should know how to code. There, I said it.
Now, I could go into a good in-depth exposition on how the artist mindset and the developer/engineer mindset aren't all that different, or how the image of the "non-technical artist" is a relatively recent phenomenon. Those are topics for another article. For the purposes of this article, suffice it to say that knowing a little code will not only give you a better understanding of how your digital tools work, but that knowledge will help you create your work more efficiently.
It doesn't matter if you're working on a large-scale collaborative project for a paying customer, or if you're using digital art as your freeform, free-wheeling catharsis engine. We all want to make the most effective use of our time. For myself, if I find that I'm doing some kind of monotonous task more than three times in a row, I'm already thinking about how I might be able to automate it and have my computer do the work for me.
Automation means cobbling together a script. Coding. And when it comes to scripting tasks that relate to digital media, you'd be hard-pressed to find a more suitable language than Python. Python is hugely popular open source scripting language that's used to write all kinds of open source software.
For digital creatives there are other advantages to learning Python. The language syntax is relatively easy to learn and Python is available on all major platforms. This means that your scripts can travel with you, regardless of whether you're running Linux, BSD, or one of those proprietary operating systems. Not only that, Python is well-integrated in a number of digital content creation tools like Blender and GIMP. Even some proprietary tools have integrated Python in them. This means that you can use Python to automate tasks in those programs, or even add new features that are specific to your particular way of working.
"That's great and all," you might say, "but be specific. What can I actually do with Python?"
I'm glad you asked.
This series of articles is meant to answer that question, to let you dip your toe into the stream and get a sense of what's possible with just a little knowledge about scripting. Fair warning: if these articles do whet your appetite for scripting, I highly encourage you to go through one of the many Python courses available online, including the tutorial that's part of the official Python documentation.
I should also mention that the examples I give might make a "real" Python developer cringe. And that's fine. Worst case, we still have a script that does exactly what we need it to. Best case, we get suggestions for improvements in the comments section of this article.
So let's start with something easy. We all know that command line tools like FFmpeg and ImageMagick are usually a faster way to do one-off video or image operations. Let's say all you want to do is encode a video or desaturate a PNG and convert it to a JPEG. It's way faster to fire off a single command than it is to launch a program with a full graphical interface, load your source media, and then perform that one little operation.
The problem, however, is that powerful command line tools like FFmpeg and ImageMagick have a lot of options and flexibility. They do so many things, and they're all controlled by a dizzying array of flags and options that you need to type in correctly. It's difficult to remember the exact magical incantation you need for the one or two specific tasks you need to get done.
For an example, let's say you have a directory full of PNG images generated by your favorite animation software. There are hundreds, or even thousands of individual images in there. Now let's say that you realize that there's no need for all of those images to be saved as 16-bit RGBA PNGs. You could save a ton of disk space and have faster loading times if those images were all converted to 1-bit black-and-white PNG images. Sure, you could re-render, but the images are already there. With FFmpeg you could churn though those images and convert them in far less time... if you could only remember the exact command to do that.
Fortunately, you've had to do this a few times before, so you took a little bit of time and scraped together a little Python script called
make_1bit.py. It's way easier to remember
ffmpeg -i something -flipflop -blah blah -please -o somethingelse or whatever. Here's the content of your script (with line breaks to fit in this column width; see below for the correct way to format your script):
subprocess.call(['ffmpeg', '-f', 'image2', '-i',
'%04d.png', '-pix_fmt', 'monob', '-threads', '0',
Let's take a quick moment to walk through the script and describe what it does. The first line,
import subprocess, imports a Python module called
subprocess. Think of modules as chunks of code that someone else has already written. You just need to make your script aware of that code. That's done with the
import statement. In this case, you're importing the subprocess module, a Python module made specifically for launching commands as if you were typing them at the command line.
In the next block of code (
subprocess.call(['ffmpeg',...])), you actually use code in that module to run FFmpeg for you. The whole FFmpeg command is broken into a list of strings. In Python, a list is simply a collection of data. It's indicated by the square braces (
) and each bit of data is separated by a comma. In this case, each bit of data is a string, or a bit of text wrapped in single quotes. Each string in the list is an argument (flag) from the FFmpeg command you want to run, in the correct order.
In this particular example, we're assuming that the script is in the same directory as your images and that the images have numbered file names like 0001.png, 0002.png, 0003.png, and so on.
For organizational sake, you may want to put each of those argument pairs on their own lines. That way it's a bit easier to see what's going on. (Note: Python is very particular about "whitespace" (spaces and tabs) in your code. So make sure you use either spaces or tabs don't mix!, and that you use the same number of them when indenting.) If you do that, your script might look like this:
Now all you have to do is run
python make_1bit.py from within that directory and, BOOM, files converted! No need to remember all of those various flags for FFmpeg. The script has that remembered for you. Of course, if you want to run FFmpeg directly (or perhaps some variant of this command), it's easy to open your script file and have those flags available and clearly organized as a reference. You can even add comments to your script so you can more easily know what each flag does:
'-f', 'image2', # Read input as images
'-i', '%04d.png', # Input files (sequential PNGs)
'-pix_fmt', 'monob', # Output colorspace is 1-bit
'-threads', '0', # Use all available CPU cores
'%04d.png']) # Output files (overwrite input)
So this is where we start. We make one little script at a time. The point is to save us time and keep us focused on getting work done by simplifying and automating repetitive or tedious tasks.
There will be more in this series... but in the meantime, if you happen to use Python scripting to simplify tasks (whether for creative work or not), perhaps you can use the comments section to explain what you do.