Mike Taulty's Blog
Bits and Bytes from Microsoft UK
Silverlight 2 - First Attempt with MultiScaleImage

Blogs

Mike Taulty's Blog

Elsewhere

Archives

I couldn't find much in the way of documentation around this so I thought I'd post something rough here as I was playing with it.

I should caveat this by saying that this is my first attempt so don't expect it to be necessarily "right". I can't find any docs :-)

I wanted to play with MultiScaleImage in Silverlight 2 so I first went and downloaded the Deep Zoom Composer tool;

Download the Preview of the Deep Zoom Composer

and I ran it up and created a new project. Into that project I used the Import button to import all the images from my c:\windows\web\wallpaper folder;

image

I then went to the Compose tab and tried to lay them all out after a fashion (i.e. not very well :-));

image

Having done a bit of composition, I used the Export function to export this and ended up with a bunch of files - I called the export windowsbackdrops so I got;

    • windowsbackdrops.sdi
    • windowsbackdrops folder
      • Lots of subfolders
      • info.bin
      • info.xml
    • SparseImageSceneGraph.xml

With that in place, I started up a new Silverlight 2 Project in VS 2008.

image

Added a web project;

image

Compiled and then ( probably a bit hackily ) I went and copied into the ClientBin folder of my web project the files/folders that Deep Zoom Composer had created for me;

image

That's my ClientBin folder of my web app up above.

I then went and altered the XAML for my Page to read;

<UserControl
  x:Class="TestDz.Page"
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Grid
    x:Name="LayoutRoot"
    Background="Gray">
    <MultiScaleImage
      x:Name="msi"
      ViewportWidth="1.0"
      Source="/windowsbackdrops/info.bin" />
  </Grid>
</UserControl>

 

And, staggerinly, my Deep Zoom image seemed to spring into life;

image

Note - as far as I can figure out that ViewportWidth is "How much of this image do you want to see in your control". I'm saying 1.0 which appears to mean "all of it". Here's what it looks like at 0.5 e.g.;

image

There's also a ViewportOrigin which looks to control where your viewport is within the picture. So, if I set ViewportWidth=0.5 and ViewportOrigin=0.5,0 then I get this;

image

i.e. the right hand half of the picture.

Ok, I then set ViewportOrigin back to 0,0 and ViewportWidth back to 1.0.

Now...what about all that scrolling and zooming? Well, I must admit that I thought the control just "did it" for you but it appears that you have to do a bit of work.

I'd have liked to have zooming in and out correspond to the mouse wheel but, as far as I know, you can't catch mouse wheel events in Silverlight ( unless you catch them in Javascript and poke them into the .NET world ) so I went for a simple scheme;

  • Zoom in by some amount when someone presses the "i" key ( i for in :-) )
  • Zoom out by some amount when someone presses the "o" key ( o for out :-))

So I added a key handler to my user control;

<UserControl
  x:Class="TestDz.Page"
  xmlns="http://schemas.microsoft.com/client/2007"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  KeyDown="OnKeyDown">
  <Grid
    x:Name="LayoutRoot"
    Background="Gray">
    <MultiScaleImage
      x:Name="msi"
      ViewportWidth="1.0"
      ViewportOrigin="0,0"
      Source="/windowsbackdrops/info.bin" />
  </Grid>
</UserControl>

 

and added code to my code-behind file;

    void OnKeyDown(object sender, KeyEventArgs e)
    {
      switch (e.Key)
      {
        case Key.I:
          break;
        case Key.O:
          break;
        default:
          break;
      }
    }

Now, at this point I did a little head-scratching as I wasn't quite sure what to do but I noticed that the MultiScaleImage has a function called ZoomAboutLogicalPoint so I thought I'd give that a whirl. It takes a zoomIncrementFactor and it looks like you set this to "larger than 1.0" to zoom in and "between 0 and 1.0" to zoom out.

The function also takes a logical point. There seems to be a function called ElementToLogicalPoint so I figured that probably converts a screen coord to a logical point so I gave this a whirl;

 void OnKeyDown(object sender, KeyEventArgs e)
    {
      double centreX = msi.Width / 2;

      // Note - not very sure about this. Then again, not very sure about
      // any of it :-)
      double centreY = (msi.Width / msi.AspectRatio) / 2;
      Point p = msi.ElementToLogicalPoint(new Point(centreX, centreY));

      switch (e.Key)
      {
        case Key.I:
          msi.ZoomAboutLogicalPoint(1.1, p.X, p.Y);
          break;  
        case Key.O:
          msi.ZoomAboutLogicalPoint(0.9, p.X, p.Y);
          break;
        default:
          break;
      }
    }

Note, I'm really not very sure about any of that but it seems to zoom about the right point. I thought I'd have a go at panning around a little by handling the arrow keys as well. Note - I think having a fixed factor of 0.1 here is not a great idea;

 void OnKeyDown(object sender, KeyEventArgs e)
    {
      double centreX = msi.Width / 2;

      // Note - not very sure about this. Then again, not very sure about
      // any of it :-)
      double centreY = (msi.Width / msi.AspectRatio) / 2;
      Point p = msi.ElementToLogicalPoint(new Point(centreX, centreY));

      switch (e.Key)
      {
        case Key.I:
          msi.ZoomAboutLogicalPoint(1.1, p.X, p.Y);
          break;  
        case Key.O:
          msi.ZoomAboutLogicalPoint(0.9, p.X, p.Y);
          break;
        case Key.Left:
          msi.ViewportOrigin = new Point(msi.ViewportOrigin.X + 0.1,
            msi.ViewportOrigin.Y);
          break;
        case Key.Right:
          msi.ViewportOrigin = new Point(msi.ViewportOrigin.X - 0.1,
            msi.ViewportOrigin.Y);
          break;
        case Key.Up:
          msi.ViewportOrigin = new Point(msi.ViewportOrigin.X,
            msi.ViewportOrigin.Y - 0.1);
          break;
        case Key.Down:
          msi.ViewportOrigin = new Point(msi.ViewportOrigin.X,
            msi.ViewportOrigin.Y + 0.1);
          break;
        default:
          break;
      }
    }

So...that seems to kind of work.

However, I don't think that I'm actually seeing zooming working in the way that I expect and I suspect that's either;

  1. I made the image incorrectly in the first place.
  2. I'm not zooming into it properly.
  3. Maybe my image just isn't big enough?

When I zoom in, I get a zoom but I don't feel like there are sub-images being downloaded and my SubImages collection is empty.

Anyway - I'll update the post when I know more about it. Perhaps this will help get you started and you can let me know when you've worked it out - I imagine an official tutorial will be along soon.


Posted Wed, Mar 5 2008 5:46 PM by mtaulty
Filed under:

Comments

Deep Zoom in Silverlight 2: How To | www.nickhodge.com wrote Deep Zoom in Silverlight 2: How To | www.nickhodge.com
on Wed, Mar 5 2008 7:12 PM
Christopher Steen wrote Link Listing - March 5, 2008
on Wed, Mar 5 2008 11:03 PM
Sharepoint  No VSE WSS for VS 2008 Until Summer [Via: Tariq ] WPF  Podder v2 has been released! [Via:...
Daniel Moth wrote MultiScaleImage with mouse support-ish
on Thu, Mar 6 2008 7:26 AM
MultiScaleImage with mouse support-ish
Sarah In Tampa wrote Building Your Own Deep Zoom
on Thu, Mar 6 2008 3:55 PM
Expression Blend and Design wrote Deep Zoom Composer Example
on Thu, Mar 6 2008 4:17 PM
Hi everyone, I have posted a quick ZIP file containing a sample project that shows you how to use the
Noticias externas wrote Building Your Own Deep Zoom
on Thu, Mar 6 2008 4:32 PM
In Silverlight 2, one of the new features is the support for Deep Zoom technology, which allows you to
Wöchentliche Rundablage: ASP.NET MVC, Silverlight 2, APIs, C#… | Code-Inside Blog wrote W&ouml;chentliche Rundablage: ASP.NET MVC, Silverlight 2, APIs, C#&#8230; | Code-Inside Blog
on Mon, Mar 10 2008 12:30 PM
Canadian User Experience wrote Silverlight 2 Resource
on Wed, Mar 26 2008 8:52 AM
It has been three weeks since we annouced Silverlight 2 at MIX08. Many of you are excited to getting
Finance Innovation Contest Winners | DavidCrow.ca wrote Finance Innovation Contest Winners | DavidCrow.ca
on Wed, Apr 2 2008 2:05 PM
Canadian User Experience wrote [Mini-Tutorial] Share Your Presentation in Deep Zoom
on Mon, Apr 7 2008 8:50 PM
Over the past several months, I went to many colleges and universities to talk about user experience
.Net World wrote MultiScaleImage with mouse support-ish
on Thu, Apr 24 2008 7:29 PM
One of the demos that captures people&amp;#39;s attention with some Silverlight 2 demos is the Seadragon
Microsoft Weblogs wrote Catching up with Silverlight 2
on Thu, Sep 10 2009 5:07 AM

Starting last week on March 5th after Silverlight 2 Beta 1 was announced, a lot has been said about Silverlight