简体   繁体   中英

Zoom an image in WP8.1

I have an full screen image using this code:

  <phone:PhoneApplicationPage
      x:Class="solution.FullScreenViewer"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
      xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      FontFamily="{StaticResource PhoneFontFamilyNormal}"
      FontSize="{StaticResource PhoneFontSizeNormal}"
      Foreground="{StaticResource PhoneForegroundBrush}"
      SupportedOrientations="PortraitOrLandscape" Orientation="Portrait"
      mc:Ignorable="d"
      shell:SystemTray.IsVisible="True">


      <Image Name="img" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"Stretch="Uniform"/>

  </phone:PhoneApplicationPage>

This is just a part of an bigger project. I wanted to implement te feture to open an image in full screen after clicking on it so I made another Page with just one image and nothing else. I am loading the image from C# using this code:

  protected override void OnNavigatedTo(NavigationEventArgs e)
  {
      string context = this.NavigationContext.QueryString["context"];
      img.Source = new BitmapImage(new Uri(context, UriKind.RelativeOrAbsolute));
      base.OnNavigatedTo(e);
  }

Now I would like to add an option to zoom the picture, but I don't know how. I have tried too Google it but the only thing I found was using a ZoomMode in a ScroolViewer which is not working for me (it says that the member ZoomMode is not recognized).

Is there any other solution to zoom in?

Instead of the image you are using you could use a Grid that has another Grid inside it. On the second grid use Grid.RenderTransform to resize the content of it (the image within the grid) with the scale transform. You can use the ManipulationDelta event to track when to zoom in or out.

Using that you can just zoom the picture in, but that is not really nice because you are focused just to the top left corner of the image. To avoid that you can enable the user to scroll the image by adding the translate transform in the image render transform tag. You can see how to do that in the code below:

<Grid x:Name="LayoutRoot" ManipulationDelta="LayoutRoot_ManipulationDelta">
    <Grid x:Name="ContentPanel">
        <Grid x:Name="imageGrid">
            <Grid.RenderTransform>
                <ScaleTransform x:Name="ImageTransform" />
            </Grid.RenderTransform>
            <Image x:Name="img" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Stretch="Uniform" Source="/Resources/Logo/CTK .png"
                ManipulationDelta="img_ManipulationDelta"
                ManipulationCompleted="img_ManipulationCompleted">
                <Image.RenderTransform>
                    <TranslateTransform x:Name="PanTransform"/>
                </Image.RenderTransform>
                <Image.Resources>
                    <Storyboard x:Name="Pan">
                        <DoubleAnimation x:Name="PanAnimation"
                        Storyboard.TargetName="PanTransform"
                        Storyboard.TargetProperty="X" Duration="0:0:1">
                            <DoubleAnimation.EasingFunction>
                                <CircleEase EasingMode="EaseOut" />
                            </DoubleAnimation.EasingFunction>
                        </DoubleAnimation>
                    </Storyboard>
                </Image.Resources>
            </Image>
        </Grid>
    </Grid>
</Grid>

And this is the C# code for the scaling and translating:

    private void LayoutRoot_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
    {
        if (e.DeltaManipulation.Scale.X > 0.0 && e.DeltaManipulation.Scale.Y > 0.0)
        {
            // Scale in the X direction
            double tmp = ImageTransform.ScaleX * ((e.DeltaManipulation.Scale.X + e.DeltaManipulation.Scale.Y) / 2);

            if (tmp < 1.0)
                tmp = 1.0;
            else if (tmp > 4.0)
                tmp = 4.0;

            ImageTransform.ScaleX = tmp;

            // Scale in the Y direction
            tmp = ImageTransform.ScaleY * ((e.DeltaManipulation.Scale.X + e.DeltaManipulation.Scale.Y) / 2);

            if (tmp < 1.0)
                tmp = 1.0;
            else if (tmp > 4.0)
                tmp = 4.0;

            ImageTransform.ScaleY = tmp;
        }
    }

    private void img_ManipulationDelta(object sender, System.Windows.Input.ManipulationDeltaEventArgs e)
    {
        // First make sure we're translating and not scaling (one finger vs. two)
        if (e.DeltaManipulation.Scale.X == 0.0 && e.DeltaManipulation.Scale.Y == 0.0)
        {
            Image photo = sender as Image;
            TranslateTransform transform = photo.RenderTransform as TranslateTransform;

            // Compute the new X component of the transform
            double x = transform.X + e.DeltaManipulation.Translation.X;
            double y = transform.Y + e.DeltaManipulation.Translation.Y;

            // Apply the computed value to the transform
            transform.X = x;
            transform.Y = y;
        }
    }

    private void img_ManipulationCompleted(object sender, System.Windows.Input.ManipulationCompletedEventArgs e)
    {
        if (e.IsInertial)
        {
            Image photo = sender as Image;

            // Compute the inertial distance to travel
            double dx = e.FinalVelocities.LinearVelocity.X / 10.0;
            double dy = e.FinalVelocities.LinearVelocity.Y / 10.0;
            TranslateTransform transform = photo.RenderTransform as TranslateTransform;

            double x = transform.X + dx;
            double y = transform.Y + dy;

            // Apply the computed value to the animation
            PanAnimation.To = x;

            // Trigger the animation
            Pan.Begin();
        }
    } 

You should be able to zoom at an application scale like this:

public static void ZoomToRatio(double ratio)
{
   ScaleTransform transform = new ScaleTransform()
   {
      ScaleX = ratio,
      ScaleY = ratio,
   };

   double height = 0.0;
   double width = 0.0;

   if (ratio < 1.0)
   {
      height = Application.Current.Host.Content.ActualHeight * ratio;
      width = Application.Current.Host.Content.ActualWidth * ratio;
   }
   else
   {
      height = Application.Current.Host.Content.ActualHeight / ratio;
      width = Application.Current.Host.Content.ActualWidth / ratio;          
   }

   Application.Current.RootVisual.SetValue(Canvas.HeightProperty, height);
   Application.Current.RootVisual.SetValue(Canvas.WidthProperty, width);

   Application.Current.RootVisual.RenderTransform = transform;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM