Reputation: 7701
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:
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?
Upvotes: 8
Views: 1153
Reputation: 7701
I managed to fix it using a Matrix
:
private float[] TranslateCoordinates(float[] coordinates)
{
var matrix = new Matrix(Matrix);
matrix.PreScale(_scaleFactor, _scaleFactor);
matrix.PreTranslate(_posX, _posY);
matrix.Invert(matrix);
matrix.MapPoints(coordinates);
return coordinates;
}
The float[]
contains the values of MotionEvent
's GetX()
and GetY()
.
Upvotes: 0
Reputation: 1691
I think your problem is because the Canvas is not getting updated, try using Canvas.UpdateLayout
after zooming.
Upvotes: 0
Reputation: 106
Try to do this :-
var actualX = (e.GetX() - _parent._posX) / _parent._scaleFactor;
var actualY = (e.GetY() - _parent._posY) / _parent._scaleFactor;
Upvotes: 3