Deep Zoom Viewer Sample Code

,

The sample code for this section is located in the DeepZoomView page and DeepZoomViewModel class, in the downloadable sample code.

The sample allows the selection of a Deep Zoom image, via a ListPicker control. The interface harnesses touch for zooming and panning of the MultiScaleImage control (see Figure 7.11).

Image

FIGURE 7.11 Selecting a Deep Zoom image to explore.

For information on the ListPicker control, see Chapter 9, “Enriching the User Experience with the Windows Phone Toolkit Controls.” For information on touch, see Chapter 12, “Processing Touch Input.”

The view contains a grid with a ListPicker, which is data bound to an ObservableCollection of custom DeepZoomSource objects. Each DeepZoomSource holds the name and URL of a Deep Zoom image. When the user selects a different item from the ListPicker, the SelectedItem property of the ListPicker is updated, which updates the DeepZoomSource viewmodel property. See the following excerpt:

<Grid Grid.Row="1">
    <toolkit:ListPicker ItemsSource="{Binding DeepZoomSources}"
        SelectedItem="{Binding DeepZoomSource, Mode=TwoWay}">
        <toolkit:ListPicker.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}"
            Style="{StaticResource PhoneTextTitle2Style}"
            Foreground="{StaticResource PhoneContrastForegroundBrush}"
            Margin="12, 10, 12, 10" />
            </DataTemplate>
        </toolkit:ListPicker.ItemTemplate>
    </toolkit:ListPicker>
</Grid>

The MultiScaleImage is located in a second Grid and has its Source property bound to the Url property of the viewmodel’s DeepZoomSource property. Thus, changing the item in the ListPicker switches the Deep Zoom image.

For the sake of simplicity, the logic for zooming and dragging is placed in the view code-beside. A Windows Phone Toolkit GestureListener is placed in the Grid as shown to monitor touch gestures, so that we can respond by zooming and dragging the MultiScaleImage:

<Grid x:Name="ContentPanel" Grid.Row="2">
    <toolkit:GestureService.GestureListener>
        <toolkit:GestureListener
        PinchStarted="OnPinchStarted"
        PinchDelta="OnPinchDelta"
        DragStarted="OnDragStarted"
        DragDelta="OnDragDelta" />
    </toolkit:GestureService.GestureListener>
    <MultiScaleImage x:Name="multiScaleImage"
        Source="{Binding DeepZoomSource.Url}" />
</Grid>

The view contains a method called Zoom, which uses the MultiScaleImage.ZoomAboutLogicalPoint to zoom in or out of the image. We constrain the zoom level to be greater than, or equal to, half the initial size of the image, as shown:

double zoomLevel = 1;

void Zoom(double level, Point point)
{
    const double minimumZoomLevel = 0.5;
    if (level < minimumZoomLevel)
    {
        level = minimumZoomLevel;
    }

    multiScaleImage.ZoomAboutLogicalPoint(
        level / zoomLevel, point.X, point.Y);

    zoomLevel = level;
}

When the user performs a pinch gesture, it is handled in the view by recording the current zoom level of the MultiScaleImage control. The center position of the touch gesture is determined relative to the MultiScaleImage. The center point is calculated automatically using the two touch points involved in the pinch gesture. We then convert this pixel location to a logical location, which results in a value between 0 and 1. See the following excerpt:

void OnPinchStarted(object sender, PinchStartedGestureEventArgs e)
{
    pinchStartLevel = zoomLevel;
    Point pinchStartPoint = e.GetPosition(multiScaleImage);
    pinchLogicalStartPoint
        = multiScaleImage.ElementToLogicalPoint(pinchStartPoint);
}

When the user moves his fingers together or apart, the OnPinchDelta handler is called. We then call the Zoom method, passing it the new zoom level and the gesture reference point, like so:

void OnPinchDelta(object sender, PinchGestureEventArgs e)
{
    Zoom(e.DistanceRatio * pinchStartLevel, pinchLogicalStartPoint);
}

To allow the user to drag the image, we respond to the DragStarted and DragDelta events of the Toolkit’s GestureListener. This involves recording the touch location relative to the MultiScaleImage and the location of the top-left corner of the control, the ViewportOrigin:

void OnDragStarted(object sender, DragStartedGestureEventArgs e)
{
    dragStartPoint = e.GetPosition(multiScaleImage);
    dragStartViewportOrigin = multiScaleImage.ViewportOrigin;
}

As the user performs a drag motion, the OnDragDelta handler is called. Here we determine the relative distance from the initial touch point to the current touch location and reposition the MultiScaleImage using its ViewportOrigin property. The ViewportWidth property is a logical property with a value between 0 and 1:

void OnDragDelta(object sender, DragDeltaGestureEventArgs e)
{
    Point touchPoint = e.GetPosition(multiScaleImage);
    double visibleSize
        = multiScaleImage.ActualWidth / multiScaleImage.ViewportWidth;
    Point newPoint = dragStartViewportOrigin;
    newPoint.X += (dragStartPoint.X - touchPoint.X) / visibleSize;
    newPoint.Y += (dragStartPoint.Y - touchPoint.Y) / visibleSize;
    multiScaleImage.ViewportOrigin = newPoint;
}

The sample allows the user to zoom in via a double tap. To achieve this, we subscribe to the DoubleTap event of the Toolkit’s GestureListener. In the handler, the location of the touch point relative to the MultiScaleImage is calculated. This point is then translated to a logical point, which acts as a reference point to perform the zoom. The zoom level is set to twice the existing zoom level, as shown:

void OnDoubleTap(object sender, GestureEventArgs e)
{
    Point tapPoint = e.GetPosition(multiScaleImage);
    Point logicalPoint = multiScaleImage.ElementToLogicalPoint(tapPoint);
    Zoom(zoomLevel * 2, logicalPoint);
}

Figure 7.12 shows the MultiScaleImage displaying the Deep Zoom image generated at the beginning of this section.

Image

FIGURE 7.12 Viewing a Deep Zoom image from the sample app.

By performing a pinch gesture, or by double tapping, the user is able to zoom in to explore the image in greater detail (see Figure 7.13).

Image

FIGURE 7.13 Zooming in on a composite Deep Zoom image.

Deep Zoom technology on the phone makes viewing high resolution imagery viable and allows you to leverage the built-in touch support of the phone to unlock exploration of visually rich content.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.212.211