Light Up the Web with Silverlight by Jacek Ciereszko

Blog about programming in Silverlight

  Home  |   Contact  |   Syndication    |   Login
  8 Posts | 0 Stories | 7 Comments | 0 Trackbacks

News

My post about Deep Zoom Composer was recommended by Scott Guthrie! :) (see here)

Archives

More About Me

Who was here

In this article I would like to present simple application with MultiScaleImage control and generated images from Deep Zoom Composer application. I hope my English is enough to understand this text but just in case I will put a lot of pictures. I will show you how to create application with very deep zoom and put it inside Silverlight 2.0.

First we have to generate project with images, therefore we have to download Deep Zoom Composer application. This process has 3 steps:

  1. "Add Image…"

    Create new project ("File"->"New Project…") and import images ("Add Image…"). Choose for example 3 images, not too much. Please, check if they are not too big (greater than 2MB).

  2. "Compose"

    Now we go to another step by clicking "Compose" button in the top of the screen.

    Then, drag and drop images. Take first one, resize and fit it to the screen.



    Zoom in image and place another one.

    And do the same to others pictures. Zoom it, and put image in that place.

  3. "Export"

    OK, so we created images, let's "Export" this to Visual Studio.

    All we have to do, is set path for our project ("Export Location"), add Name and choose if it will be exported to "deep image collection" (it generate more files and from my view it work slower).

    After this step we should have in our output something like this:


We need only folder with images and file "info.bin", in my example this is folder "deepzoomcomposerek".

OK, we have images from Deep Zoom Composer application. Let's put this to Silverlight 2.0 (If you haven't installed Silverlight Tools Beta 1 for Visual Studio 2008, you can download it here).

First, create new project in Visual Studio 2008.


I chose option "Generate an HTML test page..." because I don't need html files to add javascript to web page, I will create single silverlight project and use key down.

Now, build your project and copy folder with images (in my code this is "deepzoomcomposerek") from output (Deep Zoom Composer) to ClientBin folder (Visual Studio project). You should see something like this:

In Page.xaml file add code:

<UserControl x:Class="DeepZoomComposer.Page"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Width="1024" Height="768">
    <Grid x:Name="LayoutRoot" Background="White">
        <MultiScaleImage Canvas.Top="10" Canvas.Left="10"
     
  x:Name="wg_net_ZoomObject" ViewportWidth="1.0" Height="768"
        Width="1024" Source="/deepzoomcomposerek/info.bin" />
    </Grid>
</UserControl>

Now you should be able to run your project and see your images.

Let’s add mouse and key control. We have to add events to MultiScaleImage in Page.xaml:

<UserControl x:Class="DeepZoomComposer.Page"
    xmlns="http://schemas.microsoft.com/client/2007"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    KeyDown="UserControl_KeyDown" MouseLeave="UserControl_MouseLeave"
    Width="1024" Height="768">

    <Grid x:Name="LayoutRoot" Background="White">
        <MultiScaleImage Canvas.Top="10" Canvas.Left="10" x:Name="wg_net_ZoomObject"
            ViewportWidth
="1.0"  Height="768" Width="1024" Source="/deepzoomcomposerek/info.bin" 

             MouseLeftButtonDown="wg_net_ZoomObject_MouseLeftButtonDown"
            
MouseLeftButtonUp="wg_net_ZoomObject_MouseLeftButtonUp"

                 MouseMove="wg_net_ZoomObject_MouseMove"   />

    </Grid>
</UserControl>

and implementation to Page.cs:

bool dragInProgress = false;  //global variables
Point dragOffset;
Point currentPosition;


      private void UserControl_KeyDown(object sender, KeyEventArgs e)
      {
            Point p = wg_net_ZoomObject.ElementToLogicalPoint(new Point((wg_net_ZoomObject.Width / 2),
((wg_net_ZoomObject.Width / wg_net_ZoomObject.AspectRatio) / 2)));
            switch (e.Key)
            {
                case Key.Q:
                    wg_net_ZoomObject.ZoomAboutLogicalPoint(1.1, p.X, p.Y);
                    break;
                case Key.E:
                    wg_net_ZoomObject.ZoomAboutLogicalPoint(0.9, p.X, p.Y);
                    break;
                case Key.Left:
                case Key.A:
                    wg_net_ZoomObject.ViewportOrigin =
                        new Point(wg_net_ZoomObject.ViewportOrigin.X - 0.1,
                        wg_net_ZoomObject.ViewportOrigin.Y);
                    break;
                case Key.Right:
                case Key.D:
                    wg_net_ZoomObject.ViewportOrigin =
                        new Point(wg_net_ZoomObject.ViewportOrigin.X + 0.1,
                        wg_net_ZoomObject.ViewportOrigin.Y);
                    break;
                case Key.Up:
                case Key.W:
                    wg_net_ZoomObject.ViewportOrigin = new Point(wg_net_ZoomObject.ViewportOrigin.X,
                      wg_net_ZoomObject.ViewportOrigin.Y - 0.1);
                    break;
                case Key.Down:
                case Key.S:
                    wg_net_ZoomObject.ViewportOrigin = new Point(wg_net_ZoomObject.ViewportOrigin.X,
                      wg_net_ZoomObject.ViewportOrigin.Y + 0.1);
                    break;
                default:
                    break;
            }
        }

    private void UserControl_MouseLeave(object sender, MouseEventArgs e)
    {
            dragInProgress = false;
    }

    private void wg_net_ZoomObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
            dragInProgress = true;
            dragOffset = e.GetPosition(this);
            currentPosition = wg_net_ZoomObject.ViewportOrigin;
     }

    private void wg_net_ZoomObject_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
            dragInProgress = false;
    }

    private void wg_net_ZoomObject_MouseMove(object sender, MouseEventArgs e)
    {
            if (dragInProgress)
            {
                Point newOrigin = new Point();
                newOrigin.X = currentPosition.X -
                    (((e.GetPosition(wg_net_ZoomObject).X - dragOffset.X)
                    / wg_net_ZoomObject.ActualWidth) * wg_net_ZoomObject.ViewportWidth);
                newOrigin.Y = currentPosition.Y -
                    (((e.GetPosition(wg_net_ZoomObject).Y - dragOffset.Y)
                    / wg_net_ZoomObject.ActualHeight) * wg_net_ZoomObject.ViewportWidth);
                wg_net_ZoomObject.ViewportOrigin = newOrigin;
           
}
     }
 
Now you can run application and “deep zoom” in your images. As you can see in code, you can zoom in/zoom out your images with Q and E or move them with W, S, A, D and arrows.

Very good resources:

Source code:

  • mirror 1 (if it stop working, please let me know)

Working demo:

FIN

I hope you enjoy this article, it was my first in English and I think the last one on this blog. There is a plenty good blogs in English and I don’t want to just copy them. So if you have any question about articles wrote in polish, send me email and I will try to help you.

 

Jacek Ciereszko

polish blog: http://jacekciereszko.pl/

posted on Tuesday, March 25, 2008 12:50 PM

Feedback

# re: Silverlight 2.0 application with MultiScaleImage control and Deep Zoom Composer. 4/8/2008 3:22 AM wahy
hi, how can i reset the position of the zoomed object (deepzoom)? So after clicking on the image and zoom it, i want to have a reset button which will reset the dimension and x and y location.

thanks

# re: Silverlight 2.0 application with MultiScaleImage control and Deep Zoom Composer. 4/10/2008 2:19 AM Frederick Badion
How can I do the "permalinking" of the images that is displayed in the deep zoom? (just like the HardRock sample in which every picture has a permalink and it could identify each picture)

# re: Silverlight 2.0 application with MultiScaleImage control and Deep Zoom Composer. 4/13/2008 9:57 AM Jacek Ciereszko
You wrote:
"How can I do the "permalinking" of the images that is displayed in the deep zoom? (just like the HardRock sample in which every picture has a permalink and it could identify each picture):"

Answer:
As I know, HardRock's project had collection in DeepZoomCompser, therefore every image is rendered separately, not like in my example, as a one high resolution image. If you do collection, you will have something like MultiScaleImageItem which can give you all needed information. To do Collection, during “Export part” in Deep Zoom Composer, select "Create Collection" option.

I hope It helped.


# re: Silverlight 2.0 application with MultiScaleImage control and Deep Zoom Composer. 4/13/2008 10:09 AM Jacek Ciereszko
You wrote:
"hi, how can i reset the position of the zoomed object (deepzoom)? So after clicking on the image and zoom it, i want to have a reset button which will reset the dimension and x and y location.
thanks "

Answer:
Add button to Page.xaml, for example:
…</Grid>
<Button Content="Reset" Click="Button_Click" Width="80" Height="50" />
</Canvas>…
And implement Click event in Page.xaml.cs:
private void Button_Click(object sender, RoutedEventArgs e)
{
wg_net_ZoomObject.ViewportWidth = 1.0;
wg_net_ZoomObject.ViewportOrigin = new Point(0, 0);

}
That’s all :)


# re: Silverlight 2.0 application with MultiScaleImage control and Deep Zoom Composer. 4/14/2008 1:52 AM wahy
thanks i'll try that out

# re: Silverlight 2.0 application with MultiScaleImage control and Deep Zoom Composer. 5/27/2008 6:37 AM Hery
Hi Jacek,

In your article, you created deepzoom app using deepzoom composer.

My question is, is it possible to create deepzoom app programmatically? say i have dynamic collection of images.

Thanks..

# re: Silverlight 2.0 application with MultiScaleImage control and Deep Zoom Composer. 5/27/2008 5:27 PM Jacek Ciereszko
As far as I know, it is not possible to create collection of images without Deep Zoom Composer.

Jacek Ciereszko


Post Feedback

Title:
Name:
Email: (never displayed)
Url:
Comments: 
Please add 7 and 6 and type the answer here: