Using the Twitter and Face.com APIs to put googly eyes on people

UPDATE: So obviously with the Face.com API changes this project no longer works, but if a project of mine had to die I’m glad it was something like this and not, say, an open government tool. The world is not worse off for not being able to put googly eyes on twitter avatars.

This year I’ve decided to really make an effort to learn coding, in all its glorious and torturous forms.

That’s led me to look for more excuses to do anything somewhat code related, from joining CodeYear to building more random things for this site.

I’ve been doing more with APIs at work recently (mostly OpenStates) and wanted to give myself a project to force some practice. Thus was born TweetEyes.

It’s a very juvenile application which allows a user to search for a Twitter account, load the avatar and then — if there’s a face in the photo — put googly eyes on it. World Peace will surely follow.

The page relies on the Twitter and Face.com APIs. While Twitter is recognizable to most, Face.com does most of the heavy lifting. The application takes a photo and then parses it for faces, returning data such as gender, whether or not the person is smiling or is wearing glasses and most importantly for me, position of features such as eyes, nose and mouth.

I first saw it used in Dan Nguyen’s Congressmiles, which rates the smiles of congresspeople based on tags returned by Face.com.

One of the first things that popped into my head as a possible use of the API was the continue one of the running jokes in the newsroom, which is putting googly eyes on anything and everything, from trees to rocks and even kittens. So here we are.

The HTML itself is pretty basic. I load some CSS, Google fonts, JQuery, and some custom JavaScript we’ll get to in a moment. Below there’s a <div> called image which hold the three key components, an <img> which will hold the Twitter avatar and two which will hold a transparent png with the googly eye picture. Below that there’s the search button users will add Twitter handles to, some text which acts first as directions and will later have update the status of a search and then Flickr credit for the frame photo serving as the background. The JavaScript holds the actual meat of the application, calling the two APIs and then manipulating the display elements.

A function tweetFace starts by attaching the PNGs to #eyel and #eyer, storing the user’s search term and updating the text to let him or her know the process has begun. After that the Twitter API get user url is stored as twitter_json.

In sections of the code I use query’s built in $.getJson() method, but for the Twitter call I used $.ajax because the default doesn’t have a good way of inserting a failure callback. On success the json is parsed, storing the twitter user name (which isn’t used at the moment, but my plan is to insert it into the text eventually) and the path to the twitter account’s image. Since twitter API user call returns the normal size image, I replace that with “bigger” to get the larger image option. Error handling is done with complete.

I added two helper functions, one to hide both eyes and another which will be used later to set the position once the eye coordinates are found (I’ll come back to this in a minute).

getPhoto does most of the work of the application, beginning with sending the twitter image url to the Face.com API’s faces.detect and storing the json.

Here I use the default $.getJson(). After pulling the width and height of the image, I check that the json comes with tags, which indicates whether or not a face was detected. From there I used $.each() to start looping through the tags on the photo.

Eye_size resizes the eye based on the size of the face. The formula was a little trial and error, but seems to work OK so far. Since the photo is placed based on its top left edge, I need to move it slightly up and to the left to get the center on the actual eye position, so I use a modified Pythagorean setup to get the position correct.

Originally I had the eye functions combined, but after testing I found out faces can come back with only one eye if the subject is in profile, so now I test for the presence each eye specifically in addition to checking for a face. If the eye isn’t found its visibility is set to none.

Eye position is returned as a pair of x and y coordinates set to a percentage of the photo width and height. To get pixels I reversed that and then subtracted the Pythagorean outcome from before.

Those positions are then sent to the eyeSet function, which sets the CSS positioning of each eye, makes it visible and adjusts the height and width based on the face.

At the bottom is the else case of all this, which alerts the user that no face was found and calls hide_eyes().

If everything goes well the avatar image is updated with the new Twitter user image.

At the end of the script I add the code which will actually call all the code when the user click or hits enter (thanks to this tutorial for help on that):

    $('#search').click(tweetFace);
    $('#query').keyup(function(event){
       if(event.keyCode == 13){
           tweetFace();
       }

That’s it. Definitely not something which will make the world a better place, but it was a good exercise without a lot riding on it. If it collapsed around me, no harm.

Post a comment

You may use the following HTML:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>