Recommended

  • Silverlight 4 Podcast Pack with Tim Heuer
  • Building Modular Silverlight Applications
  • Prism -  10 Things to Know
  • Securing Silverlight Application and WCF Service using ASP.Net Authentication Techniques
  • Model– View – ViewModel in Silverlight

More from Donavon West

Skip Navigation LinksHome / Articles / View Article

The Making of Deep Zoom Obama

+ Add to SilverlightShow Favorites
1 comments   /   posted by Donavon West on Jul 08, 2008
(3 votes)
Categories: Demos , Learn , Tutorials

Note: This article is submitted by Donavon West for Silverlight Contest: Write and Win.Thanks a lot, Donavon! Hello All, Please drop a comment if you like it.

In this article, I will explain how I built the Deep Zoom Obama project. It was developed in Silverlight 2 Beta2, uses Deep Zoom and is hosted on Silverlight Streaming (Microsoft’s free 10GB hosting service). It uses, of course, Deep Zoom to display a very large mosaic image of Barack Obama constructed from over 12,000 individual images of his supporters.

So how was it done? Read on young Skywalker.

Step 1: Get 12,000 supporter images

That reminds me of that old Steve Martin bit about how to be a millionaire and never pay taxes. “First…”, he says “get a million dollars”. When you build a mosaic as large as the one I wanted to built, you need a lot of images. Maybe not a million, but I figured I would need many many thousands. I decided to use avatar images of Barack Obama supporters from the campaign’s web site. But navigating to a supporter page, right clicking on the avatar and selecting “Save Picture as” would take forever. But as luck would have it, the image files are nice and safe in Internet Explorer’s browser cache folder.

The filenames we need end in “@mx_150@my_150” but to get these, you must visit each individual supporter’s page and I was not about to visit 12,000 individual supporter’s pages. However, each supporter has “friends” and their smaller images are displayed on a particular supporter’s page. These smaller image filenames end with “@mx_30@my_100”.

This is where I used the power of Fiddler, Microsoft’s free debugging proxy. I simply inserted the following code into the OnBeforeRequest function in Fiddler’s CustomRules.js file.

   1: if (oSession.uriContains("@mx_30@my_100")){
   2:     oSession.url = oSession.url.replace("@mx_30@my_100","@mx_150@my_150");
   3: }

What does this do? When a request is made to download the smaller image, Fiddler alters the request to download the larger image (i.e. the one we need). This allowed me to visit a lot fewer pages to fill up my cache. I found a few supporters with 3000+ friends and viola, I had 12,000 images before I knew it!

Step 2: Build the 10,000 x 10,000 Mosaic

This is the cool part and I can’t take the credit for the find. I read a post on Microsoft’s Channel 10 about a mosaic of the Sydney Opera House made up of Virtual Earth images. It was made by the Australian firm SoulSolutions. They used a free mosaic generator called AndreaMosaic to generate their image. It’s not the most visual appealing user interface in the world, but what it lacks in aesthetics, it more than makes up for in raw power.

I played around with the settings until I found some that worked for my project. The result was a 10,000 x 10,000 pixel file. I was surprised at how fast the mosaic was generated (less than 20 minutes). 

Step 3: Build the Multi Scale Images

First a little background on the Deep Zoom file format. An image is broken into many small pieces of varying resolutions. As you can see, only a small piece of the hi-resolution image is downloaded (shown highlighted in the example above) as one zooms into an image. More detail of the Deep Zoom file format can be found on MSDN.

These multi scale images are built with a free tool from Microsoft called Deep Zoom Composer (shown below). Armed with the mosaic image and a few other hi-resolution images, it was time to built the images, but I wanted to add a bit of a twist. Deep Zoom has the concept of sparse images where parts of an image has a higher resolution that others. I would use this to place hi resolutions tiles into the mosaic. For example, if you zoom into the pupil in either eye, a completely different hi resolution picture can be zoomed into even further.

You can think of sparse images as the spec of dust from Dr. Seuss’s Horton Hears a Who! In the book we learn that when you look at it from a far, the spec appears as just that, a spec of dust. But if you zoom in deep, you find a whole other world living on that spec. This is the concept behind sparse images.

I’m not going into great detail on how to use Deep Zoom Composer (as a great tutorial can be found on the Expression Blend blog). But, in the screen shot above, you can see how you can arrange images on top of other images at different zoom levels. The Image of Obama waving is actually a spec in Obama’s left eye when viewed from a far. 

Step 4: Build the Silverlight Application

This is where the new version of Deep Zoom Composer was a lot of help. Not only does it slice up your images into tasty browser sized morsels, it actually generates a Visual Studio solution with two projects: the actual Silverlight application (i.e. your XAP file) and a web project test bed.

If you are satisfied with the generated XAML, and it is probably fine for some applications, you are done. The generated code-behind now has support for mouse scroll-wheel zooming, but you may want to tweak the code and/or XAML to suit your needs. For example, I removed from the XAML the pesky border and 10 pixel white margin as well as any height and width as I wanted the hosting application to be able to specify these values.

The key to Deep Zoom is the MultiScaleImage object defined in the XAML.

   1: <MultiScaleImage x:Name="msi" />

The code generated by Deep Zoom Composer is not the most elegant in the world. I’ve streamlined it a bit and modified it to capture the mouse when the user is dragging. This allows the user to move the mouse outside of the application area and retain the drag state.

Here is my modified code in the constructor of Page.xaml.cs. Pay attention to the calls to CaptureMouse and ReleaseMouseCapture.

   1: this.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e)
   2: {
   3:     mouseButtonPressed = true;
   4:     mouseIsDragging = false;
   5:     dragOffset = e.GetPosition(this);
   6:     currentPosition = msi.ViewportOrigin;
   7: };
   8: 
   9: this.MouseLeftButtonUp += delegate(object sender, MouseButtonEventArgs e)
  10: {
  11:     mouseButtonPressed = false;
  12:     if (mouseIsDragging == false)
  13:     {
  14:         if ((Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
  15:             ZoomFactor = 0.5;
  16:         else
  17:             ZoomFactor = 2.0;
  18: 
  19:         Zoom(ZoomFactor, this.lastMousePos);
  20:     }
  21:     else
  22:     {
  23:         mouseIsDragging = false;
  24:         this.ReleaseMouseCapture();
  25:     }
  26: };
  27: 
  28: this.MouseMove += delegate(object sender, MouseEventArgs e)
  29: {
  30:     if (mouseButtonPressed)
  31:     {
  32:         if (!mouseIsDragging)
  33:         {
  34:             this.CaptureMouse();
  35:             mouseIsDragging = true;
  36:         }
  37:     }
  38:     this.lastMousePos = e.GetPosition(this.msi);
  39: 
  40:     if (mouseIsDragging)
  41:     {
  42:         Point newOrigin = new Point();
  43:         newOrigin.X = currentPosition.X - (((e.GetPosition(msi).X - dragOffset.X) / msi.ActualWidth) * msi.ViewportWidth);
  44:         newOrigin.Y = currentPosition.Y - (((e.GetPosition(msi).Y - dragOffset.Y) / msi.ActualHeight) * msi.ViewportWidth);
  45:         msi.ViewportOrigin = newOrigin;
  46:     }
  47: };
  48: 
  49: new MouseWheelHelper(this).Moved += delegate(object sender, MouseWheelEventArgs e)
  50: {
  51:     e.Handled = true;
  52:     if (e.Delta > 0)
  53:         ZoomFactor = 1.2;
  54:     else
  55:         ZoomFactor = .80;
  56: 
  57:     Zoom(ZoomFactor, this.lastMousePos);
  58: };

Step 5: Place the Application on Silverlight Streaming

Now that you have your application, where will you host it? Remember that it could go viral and get millions of hits and even more in image downloads. Microsoft has a free service to host your Silverlight applications. It’s called Silverlight Streaming.

In order to host your Silverlight 2 application, you need to add a manifest.xml file that describes your application. Here is the manifest file that I used:

   1: <SilverlightApp>
   2:   <version>2.0</version>
   3:   <source>DeepZoomObama.xap</source>
   4:   <width>480</width>
   5:   <height>480</height>
   6:   <background>white</background>
   7:   <isWindowless>false</isWindowless>
   8: </SilverlightApp>

You can change the source element to fit your needs. Place the manifest.xml file into the ClientBin folder of your web project. Then generate a ZIP file of the content of ClientBin.

Go to silverlight.live.com and click on Manage Applications then Upload an Application. You will be asked to give your application a name (mine was of course DeepZoomObama).

Next you will upload your application.  Browse to the ZIP files that you created and click Upload. This process will take some time depending on your Internet connection speed.

My application was about 43MB, but Silverlight Streaming gives you 10GB of storage. That’s a lot of Deep Zoom applications!

Step 6: Built a suitable presentation Web Site

This was the most trivial aspect of the while project. I hand coded the HTML, CSS and Photoshopped all of the images. The one most important items however was including the Silverlight Streaming application that we built in the last step.

Here is (basically) the HTML that I inserted. If you want to host the new Deep Zoom Obama Silverlight application on your web site or blog, copy and paste the following HTML code.

   1: <iframe frameborder='0' scrolling='no'
   2: style='border:solid 1px #999999; width:480px; height:480px'
   3: src="http://silverlight.services.live.com/invoke/52059/DeepZoomObama/iframe.html">
   4: </iframe>

Conclusion

Building a Deep Zoom application is fun and extremely easy once you’ve done it a few times. The mosaic also really enhances the “wow” effect and is not that much more work.

Here is a recap of the tools used in this project:

  • AndreaMosaic
  • Deep Zoom Composer
  • Microsoft Silverlight Tools Beta 2 for Visual Studio 2008
  • Fiddler
  • Silverlight Streaming
Share


Comments

Comments RSS RSS
  • RE: The Making of Deep Zoom Obama  

    posted by cam on Jul 09, 2009 21:18
    Great post!  Thanks for explaining and sharing your ingenious tips, tricks and tools.  Looking forward to delving in to my first mosaic too.

Add Comment

 
 

   
  
  
   
Please add 4 and 2 and type the answer here: