Truchet! – iPhone Game Available Now!

July 9, 2010

A new and unique iPhone game built on a foundation of Truchet tiling. Start with a random tile set and strategically flip tiles to turn the board into a series of disconnected circles. The catch? Touching a tile will flip it, but it will also flip the four adjacent tiles, adding a significant level of complexity.

Features

  • Random Levels – With over 4.5 million potential levels you’ll never see the same level twice
  • Customization – Personalize your Truchet! board by changing the background, curve, and grid-line colors from over 20 different colors
  • Difficulty Levels – Five difficulty settings allow beginners and masters (and everyone in between) to remain challenged
  • Hints – If you get stuck the hint tool will highlight your next move for you

Screenshots

sh1 sh2 sh3

truchet

Movie Color Palettes

February 27, 2010

Cinematographers often spend a great deal of time making color decisions for a given film. Sometimes these choices are subtle, but often enough there are segments of films that have strong color themes, and I was curious as to how to view this in a single image.

An example of one such film is Jet Li’s Hero (shown below). There are blue scenes (stone courtyard in evening rain), red scenes (calligraphy school in the desert), and a stunning green scene (assassination attempt in the king’s chamber). On the flip side you have Saving Private Ryan which was intentionally greatly de-saturated and is essentially a dull brown/green throughout the entire film.

hero

Extracting the Colors

Step one of my plan was to loop through a video file and extract the color information for each frame, or every hundredth frame to be more precise. Since this was the slowest part of the process, I wrote this information to a simple text file to be processed later.

import pyffmpeg
import csv
import Image

outfile = csv.writer(open(‘out.csv’, ‘w’))
stream = pyffmpeg.VideoStream()
stream.open(‘C:\movie.avi’)
i=0
while(stream.GetFrameNo(i*100)):
image = stream.GetFrameNo(i*100)
color = image.resize( (1,1), Image.ANTIALIAS).getpixel((0,0))
outfile.writerow([i,color[0],color[1],color[2]])
i=i+1

outfile.close

This produces a simple csv file with the sequence number and the red, green, and blue components of the average color of the frame.

image

Creating Raw Image

From the text file, I create a very simple image file that’s just a series of solid color horizontal lines.

import Image,ImageDraw
from random import randint as rint
import csv

reader = csv.reader(open(“out.csv”, “r”))
img = Image.new(“RGB”, (800,2347), “#FFFFFF”)
draw = ImageDraw.Draw(img)

for row in reader:
r,g,b = row[1], row[2], row[3]
draw.line((0,int(row[0]),800,int(row[0])), fill=(int(r),int(g),int(b)))

img.save(“out.png”, “PNG”)

This creates a pretty ugly image of the movie, but certain patterns are still pretty clear – at least to the human eye.

out

Clustering

The end product I had envisioned would be large bands of a handful of colors. For example, in the image of Hero above you can see it starts with dark blue, then moves into some reds, and then back into lighter blues, etc. I tried some various clustering algorithms within Python, but none yielded the result I was looking for. Mostly I would cluster the colors to say 5 base colors, and then redraw the image using only those colors. This would still yield a lot of small bands, so I tried different algorithms to remove bands of certain sizes, or even re-cluster the clustered results. I simply couldn’t get to what I was imagining.

So sadly, I gave up on coding this part, and jumped into Photoshop. Using the Cutout filter, I quickly reached the result I was hoping for. Using 4 or 5 levels, large solid bands are produced as expected. I did a little research into the Cutout algorithm to try to recreate it it, but that didn’t lead too far. So for now, as sad as it makes me, the final step of the process requires a single Photoshop filter.

In short, we take a movie file, loop through every 100 frames or so, and draw a line of that color to a new image. Then, once we have a long image of solid color lines, we use Photoshop to more-or-less band this image into only a few common solid colors.

Final Output

Saving Private Ryan – As expected, not terribly exciting. Lots of de-saturated greens.

saving-private-ryan

 

The Wizard of Oz – I expected a little more from this one, but you can still see the big chapters. Intro, Emerald City, Witch’s castle, back to Emerald City. Also, the beginning is not gray because the “black and white” portions are actually sepia-toned.

wizard_ps

 

Curse of the Golden Flower – Who would have thought there’d be so much gold!?

curse

 

Jet Li’s Hero – My favorite result, and the movie I was most looking forward to processing because of how visually stunning the movie is.

hero

Avatar Mosaic

January 26, 2010

A few months ago I obsessed myself with creating a mosaic. Not just any mosaic, but a very large one, with no repeating tiles. I didn’t have any idea what I wanted the content to be, I just had the urge to make one. The image below is the final product, click on it to view full size (14mb).

avatar_mosaic

The Tiles

I had some requirements for the tiles: There had to be a lot of them, at least 100,000; they should all be the same size (without having to crop or distort); and they should all be unique. My mind quickly jumped to user avatars, specifically from deviantart.com. I’ve been a member since 2004, and love the site, so hopefully they don’t mind that I wrote a scraper to get the avatars – it only ran for about 36 hours, and netted me about 180,000 small image files. I could actually get up 3 files from each user, because for some silly reason if you change your avatar it will not replace one that’s already been used if the new one has a different extension. This means some users had a gif, png, and jpg avatar available.

So one night I wrote a scraper utilizing a random deviant link –  this meant I was getting one user at a time, as opposed to crawling which probably would have been a bit faster, but more difficult to code. After running about a day and a half I easily had enough images to start work on a mosaic, but I first had to get over an expected hurdle.

image

Duplicates!

Users that never set up their own avatar, had the default avatar download (deviantart does not actually link to a default file, but it copies the current default file to the users profile when they create an account. There were lots of these, but there were also plenty of people who simply had the exact same avatar. I imagine if I did this exercise last week, there would have been several hundred “I’m With Coco” avatars. I wanted uniqueness, and free app called “Duper” made this easy. It essentially sorts your files by size, and when 2 files are the same size it runs an MD5 hash to see if their the same. If there are duplicates, it gives you options on what to do – I choose to delete all but one for each group of duplicates. After doing this my total image count went down to 154,221. Still plenty.

image

The Image

So I had roughly 150,000 tiles, with no idea what image to build with them. I had a few problems. I wanted to eventually print the final product, so assuming I made a 40”x30” print, with each tile only .25” wide (16 tiles per square inch), I would only need 30x40x16=19,200 tiles. Overkill much? I wanted to throw in everything, even if images would be on top of each other – so I wanted to rotate the tiles in some sort of random fashion, which throws out just about every mosaic building software package out there. Also, making a mosaic that large without any duplicates is painfully slow, and on top of that I didn’t have an image to actually create. So I decided instead to simply map the tiles to x-y coordinates based on their average color.

Implementation

I used Python, along with the Image library, to create the mosaic. For each tile, the script does the following:

  1. Calculate the average color of the tile using
    • avatar.resize( (1,1), Image.ANTIALIAS).getpixel((0,0))
  2. Convert the RGB color to HSV
  3. Use the Hue to determine the x position of the tile
    • pos_x = (color[0]/360.0) * canvas_width
  4. Let the y position be completely random. I experimented with using Saturation or Value for y, but there understandably wasn’t enough variety of very bright to dark tiles.
    • pos_y = random.randint(0,canvas_height)
  5. Choose a random angle to slightly rotate the tile
    • theta = random.randint(340, 380)
    • avatar = avatar.rotate(theta, expand = 1)
  6. Paste the tile onto the canvas
    • canvas.paste(avatar, (pos_x, pos_y), avatar)

When it’s done it just saves the canvas as a jpg and all is done. It actually loops through a few directories. First for GIF, then PNG, then JPG, then a folder of avatars I just wanted to be on top, my own and friends and what not.

The Results

I was pretty pleased with the results although there are a number of black spots. Most of them are actually just almost black avatars, but some are actual holes, which I didn’t expect with the shear number of tiles available. This is partially because some pretty clear vertical bands appear that I didn’t do much research on. Since the x coordinates are based on Hue, perhaps some values are more prevalent do to how the images are compressed and stored? Perhaps 8 bit versus 16 bit or something? Not my area of expertise, but for whatever reason, certain Hues appear much more often than others.

It was a fun project to work on, and I might do something similar with another website or some other source of images. Anyway, let me know what you think and I hope you’re inspired to try something like this on your own.

image

Pi & Pi’s Spiral

January 23, 2010

imageIn 1769 Johann Heinrich Lambert proved that Pi is an irrational number, though mathematicians believed it to be since at least the 9th century. For centuries people have tried to calculate as many digits as possible, though with modern technology, it may be about time to just stop (according to Wikipedia, supercomputers have calculated more than the first TRILLION digits.) Few people, however, have taken the time to take Pi and turn it into something aesthetic. A few years ago that’s what was determined to do, and this is what I came up with.

(more…)