19

I have made an application which displays Images .Now I want to implement zoom in and zoom out feature(by using two fingertip's) as in native windows phone photo viewer application.Any idea on how to proceed .

Thanks in Advance.

AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
Vaysage
  • 1,326
  • 2
  • 15
  • 30

3 Answers3

29

Perhaps the most expedient approach would be to include the Silverlight for Windows Phone Toolkit. This contains a GestureService that will help with pinch and rotate touch gestures. You could apply it to an image like this:-

 <Image Source="someSourceUrl" RenderTransformOrigin="0.5, 0.5" CacheMode="BitmapCache">
     <Image.RenderTransform>
         <CompositeTransform x:Name="transform" />
     </Image.RenderTransform>
     <toolkit:GestureService.GestureListener>
         <toolkit:GestureListener PinchStarted="OnPinchStarted" PinchDelta="OnPinchDelta" />
     </toolkit:GestureService.GestureListener>
 </Image>

Then in code-behind:-

    private void OnPinchStarted(object sender, PinchStartedGestureEventArgs e)
    {
        initialAngle = transform.Rotation;
        initialScale = transform.ScaleX;
    }

    private void OnPinchDelta(object sender, PinchGestureEventArgs e)
    {
        transform.Rotation = initialAngle + e.TotalAngleDelta;
        transform.ScaleX = initialScale * e.DistanceRatio;
        transform.ScaleY = initialScale * e.DistanceRatio;
    }
Daniel Ballinger
  • 13,187
  • 11
  • 69
  • 96
AnthonyWJones
  • 187,081
  • 35
  • 232
  • 306
  • Thanks for the answer.But i am dynamically loading images in code.So is it possible to do the above procedure completely in code? – Vaysage Jan 13 '11 at 09:20
  • 1
    @Vaysage: You can still use this with dynamically loaded images. Typically with dynamic images you would assign a new instance of `BitmapImage` to the `Source` property of the existing `Image` control rather than unloading and loading instances of an `Image` element. It would be at this point that you would also set the Rotation on the transform to 0 as well as the ScaleX and ScaleY to 1. – AnthonyWJones Jan 13 '11 at 11:04
  • I extended this with drag control, and now I am able to drag the image out of the window (both with drag and pinch) any ideas how to awoid this? – Igor Meszaros Feb 02 '12 at 13:29
  • Just curious. Where are "initialScale" and "initialAngle" defined and what types are they? – Pretzel Mar 13 '12 at 18:15
  • 1
    @Pretzel: You would define them as fields in the host Page and they would be the same type as `Rotation` and `ScaleX` respectively, doubles I think. – AnthonyWJones Mar 13 '12 at 18:18
  • Yeah, I just figured that out. They are indeed Doubles. Thanks! :) – Pretzel Mar 13 '12 at 18:27
  • Could you also use this when there are Paths defined ( to get some elements on the image clickabe )? – Depechie Apr 30 '12 at 13:25
  • The GestureListener has been removed in the latest version http://phone.codeplex.com/releases/view/96743 – D.Rosado Mar 07 '13 at 15:51
  • Odd enought is still available in that version – D.Rosado Mar 07 '13 at 16:25
  • This is not a good solution, because the scale centers on the center of the image, if you select two points with your fingers and pinch, those two points are not beneath your fingers in the end. – msbg Mar 24 '13 at 02:42
5

Check out Laurent Bugnion's multitouch sample - http://multitouch.codeplex.com/

AarthiR
  • 92
  • 1
0

if you want simple image viewer that supports multi-touch, I recommend you to use WebBrowser control to display image.

It supports multi-touch zoom and smooth scrolling as well by default. But you must have to copy file to isolated storage from project folder. Here's how I've done:

<Grid x:Name="LayoutRoot" Background="Transparent">
    <phone:WebBrowser 
        Name="MyWebBrowserControl"
        HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0" />
</Grid>

IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();

        // if image file does not exist in isolated storage, copy it to there~!
        if (!isf.FileExists(filename))
        {
            StreamResourceInfo sr = Application.GetResourceStream(new Uri(filename, UriKind.Relative));
            using (BinaryReader br = new BinaryReader(sr.Stream))
            {
                byte[] data = br.ReadBytes((int)sr.Stream.Length);

                using (BinaryWriter bw = new BinaryWriter(isf.OpenFile(filename, FileMode.OpenOrCreate)))
                {
                    bw.Write(data);
                    bw.Close();
                }

                br.Close();
            }
        }

        Dispatcher.BeginInvoke(() => { MyWebBrowserControl.Navigate(new Uri(filename, UriKind.Relative)); });

※ You must set the Build Action of image file to Content

Joon Hong
  • 1,337
  • 15
  • 23
  • I have no proof, but I believe the WebBrowser control would a be a resource intensive control to use if you were only using it to view an image. That said, if it gets the job done... – Daniel Ballinger Aug 02 '12 at 08:37
  • @DanielBallinger // I already made application and published(with this way). Of course, I know there is pros and cons. It's very easy to implement zoom-able image viewer while it could be resource-intensive. Decision is yours. – Joon Hong Sep 05 '13 at 01:37
  • This is a valid approach for some use cases and doesn't deserve to be dismissed out of hand. – kevinstueber Sep 28 '13 at 18:57