Instagram Filters with Python

In this tutorial, I’ll demonstrate how to create vintage (just like Instagram does) photos with Python and ImageMagick. Wait? What? Yes, you can do this very thing with Python and ImageMagick, and that’s just scratching the surface!

We Made Digital Vintage Photos, Before it Was Cool

Once upon a time – technically 22 years ago – ImageMagick was released. Since then, it has evolved to a platform independent software suite that can create, edit, compose, or convert raster images (over 100 formats supported!). You can use it to resize, flip, mirror, rotate, distort, shear and transform images, adjust image colors, apply various special effects, or draw text, lines, polygons, ellipses and Bézier curves. It truly has everything you will ever need, when dealing with image manipulation in web development, video processing, panorama generating, etc. Please note, however: it is not a GUI image editor.

Installing ImageMagick

Although nearly every good hosting company has ImageMagick installed, you probably don’t have one on a local machine, simply because it isn’t shipped with Python.

Installing ImageMagick is a cinch, though. Go to the ImageMagick Download page, choose your platform (Unix/Mac/Win), and select recommended package. Simply follow the simple instructions; you can’t make a mistake here.

Once finished, go to your terminal/command-prompt, type in convert and hit Enter, If you receive a list of options instead of “Command not found”, you’re good go! Note that you don’t need to configure anything in Python.

Next Install PythonMagick to interface ImageMagick with Python.

How Does Instagram Work?

Well, to be honest, I don’t know what system the Instagram team are using for image processing. ImageMagick is also available for iOS; perhaps that is the magic of how Instagram works? To quote Kevin Systrom, Instagram CEO and co-founder:

It’s really a combination of a bunch of different methods. In some cases, we draw on top of images, in others we do pixel math. It really depends on the effect we’re going for.

For instance, Lomo-fi really isn’t much more than the image with boosted contrast. Whereas Toaster is one of the most complex (and slow, yet popular) filters we have with multiple passes and drawing.

I’d give up more info, but it’s our secret sauce :) Maybe some day…

“Maybe some day…” isn’t good enough for us, Mr Systrom. Challenge accepted!

Show Me Teh Codez!

We are going to mimic gotham (return of gotham), toaster (the complex one),nashville (the popular one), lomo (lomo-fi isn’t that good) and kelvin (lord kelvin – original) filters.

Create the directory structure as shown:

Pygram – the Python Class

I have created a little Python wrapper class to make the process of filtering images as simple as possible. In these filters, as you know, we have lots of…

  • colortone: will color tone an image in highlights and/or shadows. For example, we want to change black to purple.
  • vignette: edges of photo fade out or desaturate gradually. We can even reverse this, or use colors for vignette.
  • border: will add a border to the photo. For example, we want a white or black or any color border of a certain width; note that the width of the border will add up to the photo dimensions.
  • frame: will read specified frame and stretch in to fit to photo. We need this for the Nashville and kelvin filters.
  • output: simply renames the working copy.
  • execute: we will send all commands through this method to prevent errors that can occur while working with the shell.

I’ve made all of these mentioned, so we can skip to fun part. Open the file, called pygram.py, and copy & paste the code below.

Now, open decorations directory and create a new file called border.py inside it.

Now, create frame.py

Next vignette.py

Instagram Filters

We will go over the filters, one by one; I will explain the necessary Python methods and Imagemagick commands, including examples. So let’s begin…


Here we simply have a photo of dogs enjoying the day at the beach.


The Gotham filter produces a black&white, high contrast image with bluish undertones. In real life, this would be created with a Holga camera and Ilford X2 film.

Create gotham.py inside filters directory.

In English: create a working file, load the image into memory, improve brightness a bit, (almost) desaturate, change the remaining colors to deep purple, gamma correction (value below 1 darkens image), add more contrast, add more contrast, and save everything to a file. Add a 20px black border. Simple, eh?


The Toaster filter resembles old Polaroid shots; it features vivid colors with pink/orange glow out of the center. By the words of Instagram CEO, it’s one of the most difficult effects to create; we’ll take his word for it.

In English: create a working file, load the image into memory, change blacks to dark red, enhance brightness, desaturate by a fifth, perform gamma correction (make image brighter), add more contrast, add more contrast, save. Lastly, add a grayish vignette (desaturates edges a bit), and an “inverted” orange vignette for color burn effect.


Nashville has a nice washed out 80s fashion photo feel. It produces image with a magenta/peach tint. It additionally adds a frame to get that slide look. It’s easily one of the most popular Instagram filters.

In English: create a working file, load the image into memory, change blacks to indigo, change whites to peach color, enhance contrast, enhance saturation by half, gamma auto-correction. Add a frame from a PNG file.


Lomography is all about making high contrast photos with vignettes and soft focus (everywhere you go). In real life, they are mostly made with Holga, LOMO LC-A or so called toy cameras (cameras with plastic lens). This effect is pretty easy to recreate; we will simply enhance the red and green channels’ contrast by a third, and add a vignette. Feel free to experiment as you wish.

Create a working file, load the image into memory, enhance red channel contrast by a third, enhance red channel again, apply a vignette.

Tip: If you prefer lomo effect without vignette, just comment or remove that section of code.


Named after Lord Kelvin, this effect applies a strong peach/orange overlay, and adds a washed out photo frame.

In English: create a working file, load the image into memory, normalize, enhance brightness by a fifth, desaturate by half, create an peach/orange color overlay, and apply the multiply blending mode. Lastly, add a frame, using the PNG file.
Next place this code inside filters/__init__.py.

How to Use

It’s easy to use these effects!

Available filters:

  • Gotham
  • Kelvin
  • Lomo
  • Nashville
  • Toaster

Note The filters change the image in-place. Be sure to copy it before applying any filter if you want to copy the original image.


Performance is certainly an important part of every application. Because the average time to apply a filter to an image is roughly 1 second, we can safely say it is pretty fast!


ImageMagick Resources

To learn more about ImageMagick, here’s a list of links to all the commands and options that were used in these filter methods:

  • convert:
  • modulate: vary the brightness, saturation, and hue
  • contrast: enhance or reduce the image contrast
  • size: width and height of image
  • fill: color to use when filling a graphic primitive
  • draw: annotate the image with a graphic primitive
  • compose: set image composite operator
  • channel: apply option to select image channels
  • level: adjust the level of image contrast
  • auto-gamma: automagically adjust gamma level of image
  • gamma: level of gamma correction

Additionally, here’s a list of ImageMagick scripts, tutorials and examples:


In this tutorial, we learned a bit about Imagemagick, and demonstrated the power of it by creating filters that are similar to the ones generated by Instagram. We created PyGram!

If you need any help, or need assistance creating additional filters, such as Tilt Shift or Earlybird, let me know within the comments, and I’ll do my best to assist!


  • nielsenjared

    Great tutorial! One thing: the Nashville code is presented twice, but with semicolons in the second instance.