Creating Deep Zoom applications with C#

Posted April 26th, 2009 by Juozas

SeadragonToday I was again working with my entry for WinPhp competition. Now with a key feature – Microsoft Deep Zoom.

To start with, there are many ways how Deep Zoom application can be created. As I have written before here, easiest way is to use Deep Zoom Composer. However, I want to use it as a part of my application, so any outside application is not a choice.

Microsoft has released independent Deep Zoom library, but documentation is very limited, so I mostly used various MSDN blogs. For example, only in this article I have found list of available classes (with some useful comments). My first try was to use this Bryan Like’s example (at the end of post you can find a link to a working application).

SeadragonGiven code works just fine, but it can be improved. It allows doing a lot of post-processing modifications inside Silverligt client application, but in most cases such approach is very slow. Problem is, for every zoom level it loads not “grouped” image like this but required size copies of all visible images.

If, for example, there are 1000 images in a window, it will load all of them even if a single image size is just some pixels. What correct application should do is to load “grouped” images – downloaded amount of data is the same, but required HTTP calls is minimal. I only recommend using that code if you need to have dynamic layout or something like that. As I said before, in most cases, different approach should be chosen.

For my tests I downloaded big collection (>5000) of books covers from my project ManoKnyga.lt and when tried to show them in one screen. Working demo (requires Silverlight installed), JavaScript example:

After doing some in-depth analysis of Composer generated files I almost ended up witting my own Deep Zoom implementation, because I couldn’t find any flexible solution. However, later I found out that SparseImageCreator class is the only thing I need. It works almost the same as previously discussed CollectionCreator class, but generated output is exactly what I need. Code:

string source = @"C:\tests\Books";
string dest = @"C:\tests\GeneratedImages";
 
List images = GetImagesInDirectory(source);
List<Image> data = new List<Image>();
 
int start = 200;
int limit = start;
 
double x = 0.0;
double y = 0.0;
 
double rows = Math.Sqrt(start);
 
foreach (var image in images)
{
    if (limit < 0)
        break;
 
    limit--;
 
    Image img = new Image(image);
 
    img.ViewportWidth = rows+1;
    img.ViewportOrigin = new System.Windows.Point(-x, -y);
 
    x += 1;
 
    if (x >= rows)
    {
        y += 1.333;
        x = 0.0;
    }
 
    data.Add(img);
}
 
SparseImageCreator cc = new SparseImageCreator();
 
cc.TileSize = 256;
cc.TileFormat = ImageFormat.Jpg;
cc.ImageQuality = 0.95;
cc.TileOverlap = 1;
 
cc.Create(data, dest + "\\output");

This code loops through all images (with limit) in folder and adds them to a list of Images. Also it sets the ViewportOrigin property, which is used to position Image in space. Last step is to create a collection, what is done by SparseImageCreator class. Depending on images count this takes a while and consumes quite a lot of memory, so for using in a web application I need to create a scheduler too.

Another part of Deep Zoom is creating a Silverlight application. It can be easily done with Composer (just create a project with one image, and then customize generated source code for your needs). However, I’m not going to explain how to do it, because there are lots of examples online and I’m going to write another article about Silverlight only.

Currently I have some problems with library throwing Exceptions with big collections, nevertheless another milestone is reached (first was using .NET assemblies in PHP). Now I need to work on front-end part.

Comments (2)

  1. Sandeep Aparajit

    Good one..
    I was not aware of Seadragon. Thanks for this post.

    -Sandeep
    My BlogPhotography

  2. nosuic

    Great post.. congrats!

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">