Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Get correct coordinates with scaled and translated canvas

I am writing an Android (Xamarin) application which is able to zoom and pan an image. A user can also click on a position on the image. I need those coordinates on the image for later use.

The following code is zooming and panning the image:

protected override void OnDraw(Canvas canvas)
{
    base.OnDraw(canvas);

    _maxX = canvas.Width;
    _maxY = canvas.Height;

    canvas.Translate(_posX, _posY);

    if (_scaleDetector.IsInProgress)
        canvas.Scale(_scaleFactor, _scaleFactor, _scaleDetector.FocusX, _scaleDetector.FocusY);
    else
        canvas.Scale(_scaleFactor, _scaleFactor, _lastGestureX, _lastGestureY);
}

So far so good, now I have some MotionEvent in use, which is a LongPressListener. I wrote the following code to translate the coordinates from the MotionEvent to the coordinates on the image:

var actualX = e.GetX() - (_parent._posX / _parent._scaleFactor);
var actualY = e.GetY() - (_parent._posY / _parent._scaleFactor);

e in this case is the frame of the image. The frame holds an image (which is _parent), the user can drag the image. _parent._posX/Y are changed when that happens. The user can also zoom the image, that's the _scaleFactor.

So, when a user taps anywhere in e, I need to translate those coordinates to the image coordinates.

Those two lines of code works, but when the user zooms in, the coordinates are off as you can see in the attached image:

Screen recording

The red dots represent the calculated positions. As you can see, if a user zooms in the coordinates gets more off. What's wrong in this calculation?

like image 837
gi097 Avatar asked May 14 '18 14:05

gi097


1 Answers

Try to do this :-

  var actualX = (e.GetX() - _parent._posX) / _parent._scaleFactor;

  var actualY = (e.GetY() - _parent._posY) / _parent._scaleFactor;
like image 88
Amol Jindal Avatar answered Nov 04 '22 01:11

Amol Jindal