WYSIWYG

http://kufli.blogspot.com
http://github.com/karthik20522

Tuesday, August 7, 2012

YearInImages.com - How I built this?

Image mosaic source at https://github.com/karthik20522/ImageMosaic



Following post is a very high level technical overview of how the images were constructed and stored and how Getty Images Connect API was used to make this site possible. Site link: yearinimages.com

Connect API story:
All editorial images in Getty images are associated to an event. An event could be anything, Oscar awards, Olympics etc with a bunch of images associated to it. Every event has a numerical id that makes the event unique in our system. The years in focus 2011 images are categorized into 4 main categories (News, Sports, Entertainment, Archive). Each of these categories has many Events and with some simple scripting the EventId’s of each Event was scraped from the site and the image associated with these events was queried using Connect API. Following is a code snippet of querying Getty Connect API:
More technical information of GettyImages Connect API can be found at https://api.gettyimages.com/apis

C# wrapper to call GettyImages connect API: https://github.com/karthik20522/GettyConnect

Note that Connect API only returns back maximum of 75 images per search, so you would have to loop if an event has more than 75 images. The image metadata that Connect API provides has enough information to describe an image but you could also query GetImageDetail endpoint to get complete metadata details of an image. Once the image information was queried and saved (yearinimage uses mongodb as datastore), the image thumbnails were then downloaded for building image mosaic using following code snippet:

Image mosaic story:
The idea behind building image mosaic is to take the original image and split it to a grid say 20x20 pixels (depending on the size of the image) and compute the average RGB within each of the blocks.



Now unfortunately the thumbnail images that were downloaded from GettyImages are not uniform in size (landscape vs portrait). Since we are splitting the image into square Grid, the thumbnails had to be resized to be uniform. Once the thumbnails were resized, their average RGB values were calculated. Average color code snippet:

The next step was to iterate through each image and find the closest match to each block on the image. Since the image grid is basically a matrix of n x m, this can be serialized and stored in file/db. YearinImage used the following class model to store the matrix:


Upon page load, the browser builds a table/grid and places the image in the appropriate location (x,y) to make it look like a single mosaic. With client side scripting (JavaScript), user interaction with each of the mosaic image was possible like displaying image information when a user hovers over the image. This image information (caption) is fetched from the server using ajax calls. The ajax calls by themselves are relatively fast (less than 100ms) but when a user hovers over many images really fast these ajax calls get’s queued up and the user experiences slowness as the browser is waiting for queued ajax calls to complete. This delay can be avoided by aborting the previous ajax call to the server when a user hovers away from the image. Example of aborting an ajax call is like follows:


As a side note, since the browser displays 100’s of images for the mosaic, this potentially could lead to memory build up on the browser. This can be handled by using revokeObjectURL method. Code snippet:

Labels: , , , ,