Search code examples
windows-phone-7cameraphoto-gallery

Simulating the WP7 camera roll zoom and drag capabilities in app


I am attempting to have the user take a picture of something containing text so that the user can highlight the text they would like to have an OCR run against.

I have the picture part down and I am able to display the image. I then would like the user to be able to pinch to zoom and then swipe to move the picture just like the camera roll does for an individual photo. This would allow the user to see the text they would like to run the OCR against more clearly. Currently I only have the pinch zoom working but really badly.

private Popup popup = new Popup { IsOpen = true };
private Grid grid = new Grid { Width = 480, Height = 800 };
private Image backgroundImage = new Image
{
    Stretch = Stretch.Uniform,
    RenderTransformOrigin = new Point(.5, .5),
    RenderTransform = new CompositeTransform()
};

void OCRSelection_Loaded(object sender, RoutedEventArgs e)
{
   this.grid.Children.Add(this.backgroundImage);
   this.popup.Child = this.grid;
   var gl = GestureService.GetGestureListener(this.backgroundImage);
   gl.PinchStarted += new EventHandler<PinchStartedGestureEventArgs(gl_PinchStarted);
   gl.PinchDelta += new EventHandler<PinchGestureEventArgs>(gl_PinchDelta);
}

private void gl_PinchStarted(object sender, PinchStartedGestureEventArgs e)
{
    _oldFinger1 = e.GetPosition(this.backgroundImage, 0);
    _oldFinger2 = e.GetPosition(this.backgroundImage, 1);
    _oldScaleFactor = 1;
}

private void gl_PinchDelta(object sender, PinchGestureEventArgs e)
{
        var scaleFactor = e.DistanceRatio / _oldScaleFactor;

        var currentFinger1 = e.GetPosition(this.backgroundImage, 0);
        var currentFinger2 = e.GetPosition(this.backgroundImage, 1);

        var translationDelta = GetTranslationDelta(
            currentFinger1,
            currentFinger2,
            _oldFinger1,
            _oldFinger2,
            ImagePosition,
            scaleFactor);

        _oldFinger1 = currentFinger1;
        _oldFinger2 = currentFinger2;
        _oldScaleFactor = e.DistanceRatio;

        UpdateImage(scaleFactor, translationDelta);
}
private void UpdateImage(double scaleFactor, Point delta)
{
    TotalImageScale *= scaleFactor;
    ImagePosition = new Point(ImagePosition.X + delta.X, ImagePosition.Y + delta.Y);

    var transform = (CompositeTransform)this.backgroundImage.RenderTransform;
        transform.ScaleX = TotalImageScale;
        transform.ScaleY = TotalImageScale;
        transform.TranslateX = ImagePosition.X;
        transform.TranslateY = ImagePosition.Y;
    }

private Point GetTranslationDelta( Point currentFinger1, Point currentFinger2, Point oldFinger1, Point oldFinger2,
                                        Point currentPosition, double scaleFactor)
{
    var newPos1 = new Point(
        currentFinger1.X + (currentPosition.X - oldFinger1.X) * scaleFactor,
        currentFinger1.Y + (currentPosition.Y - oldFinger1.Y) * scaleFactor);

    var newPos2 = new Point(
        currentFinger2.X + (currentPosition.X - oldFinger2.X) * scaleFactor,
        currentFinger2.Y + (currentPosition.Y - oldFinger2.Y) * scaleFactor);

    var newPos = new Point(
        (newPos1.X + newPos2.X) / 2,
        (newPos1.Y + newPos2.Y) / 2);

    return new Point(
        newPos.X - currentPosition.X,
            newPos.Y - currentPosition.Y);
}

I found this code from WindowsPhoneGeek so I will not take 100% credit for it. I actually lose the picture when I zoom too far out and it goes crazy by bouncing to different margins when I zoom out as well. I believe this could be because I have to rotate the image 90 degrees.

I would like to also have the user move the picture with a drag gesture. Anyone ever done anything like this or have any tips?

Also, this is only my 2nd week working with WP7 so I may just be missing something simple. Thanks in advance.


Solution

  • There are some pre-existing behaviours at http://multitouch.codeplex.com/ which may be a simpler solution for your needs.