Yesterday I saw that the Expression Blend and Design team had blogged about the new DeepZoomTool.dll:
In our most recent release of Deep Zoom Composer, one of the major changes we made was to change how we generated the image tiles both for designing as well as exporting your Deep Zoom Content. In the past, ever since our first release at MIX, our image encoding was done using a combination of SparseImageTool.exe and ImageTool.exe command line tools. Starting with this release, we have retired those tools and have shifted to a preview version of a .NET based DLL that provides image generation capabilities.
Building Deep Zoom Images via code is something that I’ve wanted to do for some time. I’ve tried to figure out how to do this many different ways, but I’ve never gotten it to work. So I was pretty excited to try out this new API for Deep Zoom. I still don’t fully understand it all, but I was able to create a very simple program to generate a deep zoom image based on a bunch of photos.
First, I read all the image files into a List of strings. I created my code so that it will go into subfolders as well:
private static List<string> GetImagesInDirectory(string path)
return GetImagesInDirectory(new DirectoryInfo(path));
private static List<string> GetImagesInDirectory(DirectoryInfo di)
List<string> images = new List<string>();
// get all the images in this directory first
foreach (var fi in di.GetFiles("*.jpg"))
// get all the directories with their images
foreach (var sub in di.GetDirectories())
Next, once you have the list of Images, you need to generate all the Deep Zoom images which are folders containing tiles of the image at different zoom levels. We generate these images using the ImageCreator. For a great overview on Deep Zoom and Tiles, check out Jaime Rodriguez: A deepzoom primer.
List<string> images = GetImagesInDirectory(source);
List<string> data = new List<string>();
foreach (var image in images)
ImageCreator ic = new ImageCreator();
ic.TileSize = 256;
ic.TileFormat = ImageFormat.Jpg;
ic.ImageQuality = 0.95;
ic.TileOverlap = 0;
string target = dest + "\\output_images\\" + Path.GetFileNameWithoutExtension(image);
Now we should have a bunch of folders and xml files in our “output_images” folder in our destination. Now that we’ve created all the images and their tiles we need to create the collection using the CollectionCreator. The collection creator takes in the list of xml files that we generated and creates another xml file plus some more image tiles.
CollectionCreator cc = new CollectionCreator();
cc.TileSize = 256;
cc.TileFormat = ImageFormat.Jpg;
cc.MaxLevel = 8;
cc.ImageQuality = 0.95;
cc.Create(data, dest + "\\output");
Now we can actually start to use our Deep Zoom image. However, we will need a Silverlight Deep Zoom project in order to display the images. To do this just create a Deep Zoom project, add an image or two, and then export it to a Silverlight Project. In that project delete the contents of the GeneratedImages folder inside of the client bin and then set the dest variable in the above code to the path of the GeneratedImages folder you just cleaned out. Point the source variable to a folder containing the folder you want to load the images from and run it. You should get an output.xml file in the GeneratedImages folder.
You will need to make a couple of changes to the Silverlight project once you’ve done all that. First, we need to position our images since right now they are just a collection. We do this by setting the ViewportWidth and ViewportOrigin. I’m still trying to fully understand these, but the best explanation I’ve seen so far is also on Jaime Rodriguez’s blog: Working with Collections in Deep Zoom.
void msi_ImageOpenSucceeded(object sender, RoutedEventArgs e)
//If collection, this gets you a list of all of the MultiScaleSubImages
var x = 0.0;
var y = 0.0;
foreach (MultiScaleSubImage subImage in msi.SubImages)
subImage.ViewportWidth = 5.333;
subImage.ViewportOrigin = new Point(-x, -y);
x += 1;
if (x >= 5)
y += 1.333;
x = 0.0;
msi.ViewportWidth = 1;
Now we’ve arranged out images on the viewport, but we also need to point the MultiScaleImage to our output.xml instead of what it was before (do that in the page.xaml file). Once we’ve done that we should be able to run and see our generated deep zoom!
There is still a lot of work to do on this, like figuring out the proper ViewPortWidth based on the number of images and image size, but this is a good starting point. I’m hoping to get some more time to play with this this weekend and I’ll post more as I figure it out.
Update: Just uploaded my project which should make it a lot easier to try out. Just set the source and dest variables, run the console app, and then build and run the website. Have fun!