Pixar's color scripts

Visualizing The Incredibles' color script.

The Duck Tale

The one about hand-making Korean wedding ducks.

Smile

Transforming sketches into a mixed media piece.

The mixed media process

A photo narrative about making a mixed media piece.


Method chaining in Python

Posted on 2010-01-04 02:47:24

Method chaining is a great way to keep your source code lean. I'll demonstrate by modeling a SQL-like language using Python classes. Suppose you have the following class:

class Statement(object):
  def __init__(self):
    pass
  
  def select(self, fields):
    self._fields = fields
    
  def table(self, table):
    self._table = table
    
  def where(self, where):
    self._where = where
    
  def __str__(self):
		# If where exists...we can also try/except
    if dir(self).__contains__('_where'):
      return "SELECT %s FROM %s WHERE %s" % (self._fields, self._table, self._where) 
    else:
      return "SELECT %s FROM %s" % (self._fields, self._table)

Usage of the aforementioned class:

s = Statement()
s.select("first_name, last_name")
s.table("users")
s.where("id = 5")
print s # Output: SELECT first_name, last_name FROM users WHERE id = 5

Looks like standard Python, right? The Statement class methods are not doing anything other than setting instance variables. We can make our usage more concise by making every method chainable. Here is the revised class:

class Statement(object):
  def __init__(self):
    pass
  
  def select(self, fields):
    self._fields = fields
    return self
    
  def table(self, table):
    self._table = table
    return self
    
  def where(self, where):
    self._where = where
    return self
    
  def __str__(self):
    if dir(self).__contains__('_where'):
      return "SELECT %s FROM %s WHERE %s" % (self._fields, self._table, self._where) 
    else:
      return "SELECT %s FROM %s" % (self._fields, self._table)

The only difference between the implementations is that every class method (minus the constructor) returns the class instance. Now we can write code that looks like:

s = Statement()
s.select("first_name, last_name").table("users").where("id = 5")
print s # Output: SELECT first_name, last_name FROM users WHERE id = 5

There are pros and cons for each approach. For this particular example, the latter makes for code that is more readable. I'm interested in seeing good examples of method chaining - send me an email if you see a neat implementation.

Visualizing Pixar's color scripts

Posted on 2009-12-20 08:44:54

Color is a critical element in all of Pixar's films. If you are unaware, a color script details the color tones for a film. You can read more about color scripts here.

After learning about color scripts, I was fascinated to visualize a color script for The Incredibles, my favorite Pixar film. As a comparison, concept art and color scripts for The Incredibles can be found on Lou Romano's blog. Before going forward, I should mention a simple disclaimer: I am not trying to infringe upon Pixar's copyrights or trademarks - I am merely describing a process for creating a data visualization. With that said, let's jump in.

Most worthy data visualizations start with a simple hand-drawn sketch:



I determined that I was going to capture a frame every few seconds, and extract a color palette from each frame. With a palette for each frame, I could create several visualizations. It was at this point that I decided on the tools for each step:

  1. PyObjc w/ QTKit and CoreImage to thumbnail frames
  2. The NodeBox colors library to extract color information for each frame
  3. Processing and/or OpenFrameworks for visualization
I settled on an interval of 10 seconds, which spawned 612 files. I would have shortened the interval, but I'm not equipped with amazing computational power and hard drive space.



Featured above is a tile dump featuring image extraction from the first sequence of the film. Obviously the images are at a much higher resolution. The code to do this was very straight-forward. The heart of the code is the following:

def frame(self, second):
  second = max(0, min(second, self.duration))
  second = int(second * self.timescale)
  second = max(0, second - 1)
  time = QTKit.QTMakeTime(second, self.timescale)
  frame = self.movie.frameImageAtTime_(time)  
  return frame.TIFFRepresentation()

With the frames thumbnailed, I proceeded to extract a color pallete. I ended up extracting each Pixel's color data, converting it from RGB to Hex. Thereafter, I mapped each Hex to a primary and secondary hue representation. Here is a snippet of code which calculates the secondary colors:

for filename in os.listdir(FOLDER):
  im = Image.open(filename)
  colors = im.getcolors(im.size[0] * im.size[1])
  secondary_hue_counts = {}
  for color in colors:
    count = color[0]
    hex_color = get_hex(color[1])
    c = color_lib.Color('#%s' % hex_color)
    secondary_hue = c.nearest_hue()
    if (secondary_hue in secondary_hue_counts): secondary_hue_counts[secondary_hue] += 1
    else: secondary_hue_counts[secondary_hue] = 1

If the NodeBox libraries were not available, I would have resorted to brute quantization using the Python Image Library:

result = im.convert('P', palette=Image.ADAPTIVE, colors=32)
result.save("test.png")

Another option could have been to sample the histogram at various peaks. Also, I could have applied a radial blur and combined the aforementioned approaches. However, the combination of the colors would not be entirely accurate.

Next, I visualized all the secondary colors as divs in an HTML file. Note - this was probably the cheapest and most effective way to prototype color extraction. Essentially, it was the first time I could see the process coming together. Here is a snippet:



Afterwards, I flipped the axes: the x-axis represents seconds and the y-axis is the ROYGBIV color wheel (every secondary color is folded into a primary color). Featured below the large graph is another histogram that shows color gaps between frames. Here is what that turned out like:



All in all, this was a fun visualization to hack up for a couple reasons: I was able to learn more about PyObjC and dabble in the land of color theory. As always, you can view the Flickr photo set for a detailed look at the project.

The duck tale

Posted on 2009-11-15 23:59:06

One of my college roomates is getting married next month in Phuket, Thailand. As a gift to him and his wife, I've designed, fabricated, and painted a pair of stylized Korean wedding ducks. Before I jump into the details, I have to give a big thanks to Steve for providing the idea, guidance and resources that were necessary to achieve a tangible outcome.

So why Korean wedding ducks? Apparently it is a Korean tradition to give a pair of ducks as a wedding gift. Aside from being cute decorations, the ducks are a way to visualize the current state of a relationship: a happy couple points their ducks face to face while a not-so-happycouple points their ducks away. There are some pretty intense ducks out there.

The process got started two weeks ago when Steve and I picked up a band saw from Westwood. Look how happy he is:



Three days later, I met up at Steve's place to learn the fine art of band sawing and earn my woodworking badge. Here is a shot of Steve showing me the ropes:



Band saw, meet wood. Wood, meet band saw.



Steve's ducks are on the left and mine are on the right. We proceeded to smooth the corners and faces with a Dremel and fine sand paper. Here is what the ducks looked like post-sanding:



We proceeded to stain the ducks and let them sit overnight in Steve's garage:



Four days later, I met back up at Steve's place and saw the dried ducks in all their glory:



Fast forward to this morning when I decided to paint the ducks with acrylics:



I ended up mixing white, orange, and light pink and went to town on the ducks:



I then went ahead and mixed orange and pink together to create some highlights and stripes:



Here is a top down shot:



Here is another shot showing the patterns from the other side:



Making these ducks made me realize how out of touch I am when it comes to working with wood and fabrication in general. Overall, this was an amazing experience to attempt a radically different project. I hope the couple keeps their ducks endlessly pointed at each other.

Smile

Posted on 2009-11-08 23:49:39

While hanging out in the library last weekend I was inspired to doodle some fun characters.



All of the characters share the same general shape but are unique in small and strange ways. Some have antennas, others are lacking additional limbs, and one even looks like it fell out of a Star Trek episode. Yesterday morning, I picked my favorite three and proceeded to transfer the outline to a piece of wood.



I solidified the sketches by inking over them with a sharpie.



I mixed yellow, pink, and beige acrylics and smeared streaks over the canvas with a plastic bag.



Here is how the first character turned out. I ended up blending orange and red acrylics for the body and a brown acrylic for the outline.



Here's a lovely show of the palette. I was forced to make green and failed. I was trying to go for something lighter but had exhausted my mixing options by this point.



Over the course of the next hour, I made it through the rest of the characters.



I tried thickening up the piece by applying black and yellow smears across the canvas. Here's a comparison of the before and after.



I let the piece dry overnight and finished it up this morning by adding a coat of orange and pink.



Hope you enjoyed the narrative. Higher resolution pictures can be found at the Smile photoset.

A narrative of the mixed media process

Posted on 2009-07-21 09:28:00

I've been frequently asked about my process for creating mixed media projects. While I could banter about technique, I decided to share photos and write a short narrative about making a piece from the previous weekend. The pictures that comprise this post are in a Flickr album.



The process began by purchasing three large particle boards. Particle board can be purchased at most hardware stores - Home Depot typically has of particle boards of all shapes and sizes. Immediately, I proceeded to doodle a simple cityscape and cloud-like balloons.



After doodling, I applied a primary coat of white/off-white acrylics. Note, I should have anticipated the difficulty of painting on a particle board. Since the board acts like a sponge, I was forced to ditch the easel and paint/mix colors directly on the target surface. The secondary coat of yellow was a lot easier to paint since the particle board had absorbed the first layer.



I found some old magazine cutouts and filtered them based on color and texture. It should be stated that previous mixed media attempts were on a surface area that was 1/20 the size of this monstrous piece. The tenuous thing about this step was that I was forced to think and re-think how to balance various images across three large panels. Here are some close ups:



At this stage I departed from the formulaic approach that guided previous pieces and started smearing newspaper sheets and sponges dipped in dark acrylics across the canvas.



Finally, I painted a layer of thick grey strokes using a medium sized brush. By the end, I spattered black paint using a large brush in various locations to create a worn effect.



Overall, this was a creatively challenging experience. I was incredibly unprepared; what started out as a mixed media piece ended up mostly as a painting. For the curious, the piece is untitled - I can't think of anything to succinctly describe result.

Categories

Art
ColdFusion
Data Visualizations
Design
Inspiration
JavaScript
Life
Python
Ruby
Snippets

Elsewhere

Facebook
Gravity
Twitter

Subscribe to this blog


Content by Kunal Anand. Connect with me on Twitter, Facebook, or email.