ICM Final - Webcam Self-Portraits


Plz excuse the dead look in my eyes. It's finals. Here are my questions for the class.

  1. How is interface of this website helping or hindering you from using it?
  2. In what ways do you feel this does or doesn't capture your personality/identity?
  3. What would you do with the photos you save from this?
  4. How could this be more engaging and exciting for you?

I was inspired by snapchat filters and how they change our perception of ourselves. This was my initial idea.

This morphed a little bit, especially after the feedback from the project proposal class and also from the playtesting class. I also did some research on the history of self-portraits (the original selfies). I found that self portraits resonated with me the most when artists were vulnerable in using their own image to express different facets of how they view themselves. It is a way for us to see stories about their identities and feelings in a specific time, place, and society.

My final concept is about users creating a self-portrait through the webcam by answering questions about themselves. Using inputs from the user, I queried images using the Flickr API. The images will swirl around you to create the filter.

To accomplish this, I started by running the p5 webcam image with clmtrackr. Here is the initial code. In this sketch, I created ellipse at each point from the array that is returned by clmtrackr when it detects a face.

Next, I figured out how to get the DOM elements working. I needed three input fields where users would answer the questions "who are you?", "what do you like?", and "Describe yourself." For the latter two questions, I wanted to have the input fields continuously drop down as the user entered more answers. I tried to accomplish this by creating new input fields every time the user entered something. This ended up creating a duplicates when I pushed to my array that was holding the user's inputs. The more important thing I discovered in this process was that the .changed() function does not simply run one time. For instance, the callback for something like "input.changed(callback);" ended up running somewhere between 70-200 times when I hit enter - I checked it with a counter in the code.

I debugged this in a separate sketch. The code is below. To keep the callback from running more than once, I added "return false;" at the end. I ended up cutting down on unnecessary inputs by deleting the old input field, replacing it with a <p> element of the user's input, and then creating a new input field below that.

The next component I needed to work with was the Flickr API. I used flickr.photos.search to query the user inputs either as text for the "noun" inputs (what do you like?) or as tags for the "adjective" inputs (describe yourself). In the code, I put loadJSON() in the callback function for the "input.changed();" components so the sketch could load a new JSON response every time the user entered something new. Then, in the loadJSON()'s callback function, I pushed images into an "Imgcloud" object. This happens each time the user enters something, so the "photoArray" is holding Imgcloud objects of all the photos from Flickr as well as their position info.

Another big issue I ran into was when to use loadImage() or createImg(). When I attempted to use the save button, I got an error that my canvas was tainted!!

I was under the impression that because I was loading images from URLs that were not local files, I needed to put them in my sketch as DOM elements using createImg(). THIS IS NOT THE CASE. To make images as p5 elements instead of <img> elements, you need to use loadImage(). To summarize, loadImage() = p5 elements and createImg() = DOM elements that are not a part of your canvas.

Finally, the Imgcloud object specified the movement of all the images. I referenced Dan Shiffman's PolarToCartesian example to figure out how to move the images in a circles instead of in lines. Here is how I coded the Imgcloud object.

Full code is available on my Github repository for this project - click here to see! Here is a video demo.

Thank you for reading this far and thank you, Mimi!