Generate MEMEs Programmtically

MEMEs are de facto internet standard nowadays. At least, dozen if not hundred of daily top posts on Imgur or Reddit are probably MEMEs. That is, a pop culture image with sarcastic text (always) displayed on Top, Bottom or Center of that image. A lot of web tools out there let you create memes graphically but a few ones actually propose an API for generating memes from your favorite programming language.

In this blog post, we'll try to generate a few MEMEs programmatically using Python, PHP or whatever language that support HTTP requests with the help of the PixLab API but before that, lets dive a little bit into the tools needed to build a MEME generator.

Crafting a MEME API

Building a RESTful API capable of generating memes at request is not that difficult. The most important part is to find a good image processing library that support the annotate operation (i.e. Text drawing). The most capable & open source libraries are the ImageMagick suite and its popular fork GraphicsMagick. Both provides advanced annotate & draw capability such as selecting the target font, its size, text position, the stroke width & height and beyond. Both should be a good fit and up to the task. Here is some good tutorials to follow if you wanna build your own RESTful API:

In our case, we'll stick with the PixLab API due to the fact that is shipped with robust API endpoints such as Image compositing, facial landmarks extraction, dynamic image creation that proves of great help when working with complex stuff such as cloning Snapchat filters or playing with GIFs. So, without further ado, let's start programming some memes..

First MEME

Given an input image of the famous Michael Jordan crying face:

JDR face

Draw some funny text on top & bottom of that image to obtain something like this:

JDR Draw

Using the following code:

import requests
import json
# Draw some funny text on top & button of the famous Michael Jordan crying face.
# https://pixlab.io/cmd?id=drawtext is the target command
req = requests.get('https://api.pixlab.io/drawtext',params={
    'img': 'https://pixlab.io/images/jdr.jpg',
    'top': 'someone bumps the table',
    'bottom':'right before you win',
    'cap':True, # Capitalize text,
    'strokecolor': 'black',
    'key':'Pix_Key',
})
reply = req.json()
if reply['status'] != 200:
    print (reply['error'])
else:
    print ("Meme: "+ reply['link'])

make_meme.py/php snippet available on the PixLab Github Repository.

If this is the first time you've seen the PixLab API in action, your are invited to take a look at the excellent introduction to the API in 5 minutes or less. Only one command (API endpoint) is actually needed in order to generate such a meme:

drawtext is the command used for text annotation. It expect the text to be displayed on Top, Center or Bottom of the target image and support a bunch of other options such as selecting the text font, its size & colors, whether to capitalize the text or not, stroke width & opacity and so on. You can find out all the options the drawtext command takes here.

There is a more flexible command named drawtextat that let you draw text on any desired region of the input image by specifying the target coordinates (X,Y) of where the text should be displayed. Here is an usage example.

Dynamic MEME

This example is similar to the previous one except that the image we'll draw something on top is generated dynamically. That is, we will request from the PixLab API server to create a new image for us with a specified height, width, background color and output format and finally we'll draw our text at the center of the generated image to obtain something like this:

dynamic image

Using this code:

import requests
import json

# Dynamically create a 300x300 PNG image with a yellow background and draw some text on the center of it later.
# Refer to https://pixlab.io/cmd?id=newimage && https://pixlab.io/cmd?id=drawtext for additional information.

req = requests.get('https://api.pixlab.io/newimage',params={
    'key':'My_Pix_Key',
    "width":300,
    "height":300,
    "color":"yellow"
})
reply = req.json()
if reply['status'] != 200:
    print (reply['error'])
    exit();
# Link to the new image
img = reply['link'];

# Draw some text now on the new image
req = requests.get('https://api.pixlab.io/drawtext',params={
    'img':img, #The newly created image
    'key':'My_Pix_Key',
    "cap":True, #Uppercase
    "color":"black", #Text color
    "font":"wolf",
    "center":"bonjour"
})
reply = req.json()
if reply['status'] != 200:
    print (reply['error'])
else:
    print ("Pic location: "+ reply['link'])

dynamic_meme.py/php snippet available on the PixLab Github Repository.

Here, we request a new image using the newimage API endpoint which export to PNG by default but you can change the output format at request. We set the image height, width and the background color respectively to 300x300 with a yellow background color.

Note that if one of the height or width parameter is missing (but not both), then the available length is applied to the missing side and if you want a transparent image, set the color parameter to none.

We finally draw our text at the center of the newly created image using the wolf font, black color and 35 px font size. Of course, one could draw lines, a rectangle for example to surround faces, merge with other images and so forth...

Image Composite

Let's generate the following by compositing two smiley on top of Jordan's face:

jdr smiley

Using this code:

import requests
import json

# Composite two smiley on top of the famous Michael jordan crying face.
# A more sophisticated approach would be to extract the face landmarks using facelandmarks and composite something on the different regions.
# https://pixlab.io/cmd?id=merge for more info.

req = requests.post('https://api.pixlab.io/merge',
    headers={'Content-Type':'application/json'},
    data=json.dumps({
        'src':'https://pbs.twimg.com/media/CcEfpp0W4AEQVPf.jpg',
        'key':'My_Pix_Key',
        'cord':[
        {
           'img': 'http://www.wowpng.com/wp-content/uploads/2016/10/lol-troll-face-png-image-october-2016-370x297.png',
           'x': 30,
           'y': 320
        },
        {
           'img': 'http://orig08.deviantart.net/67d1/f/2010/216/6/7/lol_face_by_bloodyhalfdemon.png',
           'x': 630,
           'y': 95
        }]
    })
)
reply = req.json()
if reply['status'] != 200:
    print (reply['error'])
else:
    print ("Pic Link: "+ reply['link'])

face_composite.py/php snippet available on the PixLab Github Repository.

This operation is named compositing and is done via a single PixLab command named merge. this command expects a list of coordinates (X, Y) and a list of images to be composited (i.e. The two smiley in our case) on top of the target region. The coordinates here were set randomly and passed verbatim to merge but a more sophisticated approach would gather the facial coordinates and composite something on top of them such as a flower crown to mimic the Snapchat filters for example. Refer to the PixLab documentation for additional information on the merge command.

Mimic Snapchat Filters

This last example, although relatively unrelated to our subject here is about to show how to mimic the famous Snapchat filters programmatically. So, given an input image: plain woman face and this eye mask: eye_mask

located at. pixlab.xyz/images/eye_mask.png

plus this mustache: mustache located at. pixlab.xyz/images/mustache.png

output something like this: snapchat filter Well, in order to achieve that effect except for the MEME we draw on the bottom of that image, lots of computer vision algorithms are involved here such as face detection, facial landmarks extraction, pose estimation and so on. You are invited to take a look at our previous blog post on how such filter is produced, what techniques are involved and so on: Mimic Snapchat Filters Programmatically.

Conclusion

Generating MEMEs is quite easy providing a good image manipulation library. We saw that ImageMagick and GraphicsMagick with their PHP/Node.js binding can be used to create your own MEME Restful API. Our simple yet elegant solution is to rely on the PixLab API. Not only generating MEMEs is straightforward but also, you'll be able to perform advanced analysis & processing operations on your input media such as face analysis, nsfw content detection and so forth. Your are invited to take a look at the Github sample page for dozen of the others interesting samples in action such as censoring images based on their nsfw score, blurring human faces, making gifs, etc. All of them are documented on the PixLab API endpoints reference doc and the 5 minutes intro the the API. Finally, if you have any suggestion or critics, please leave a comment below.


Author: Root

Master of AI (Not related to Mr Wayne)

Comments on “Generate MEMEs Programmtically”