Android: Grabbing pixel xy coordinates when image has been scaled or translated via Matrix.

So you have a view, that has an image.  You move around this image, scaling/translate the matrix to give the effect (I was using a view someone else created: https://github.com/MikeOrtiz/TouchImageView, gives a Map View that you create an image of, in a rough way of explaining it).

His code uses a matrix to alter the image to allow you to move around the screen.  This changes your coordinates, as you probably know because you’re looking at this.

So, the fix is easy, and just takes a bit of thinking, but it was still a pain to figure it out, and I couldn’t find any sources online about it, so I’ll put what I figured out below:

 matrix.getValues(m);
 float transX = m[Matrix.MTRANS_X] * -1;
 float transY = m[Matrix.MTRANS_Y] * -1;
 float scaleX = m[Matrix.MSCALE_X];
 float scaleY = m[Matrix.MSCALE_Y];
 lastTouchX = (int) ((event.getX() + transX) / scaleX);
 lastTouchY = (int) ((event.getY() + transY) / scaleY);
 lastTouchX = Math.abs(lastTouchX);
 lastTouchY = Math.abs(lastTouchY);

So, in general, matrix.getValues(m) stores some values you can access from the matrix you’ve been using. In the View I’m using, it has the matrix as a class variable that can be accessed when needed, along with a float matrix, so it worked fine.

Next four lines are just me grabbing some of the values from the matrix, you can look at the android doc here. They’re the constants up top. I multiplied the transX and transY by -1 as it returned a negative value, which I used a positive coordinate system.

Next, we add the translate to the actual MotionEvent’s x/y value. This gives us our total movement with touch, then divide by scale amount. This moves our position in regards to how much we’ve zoomed in and out.

The abs is just a backup, I don’t believe it’s needed, I was testing other things, but just in case, I’ll keep it there.

Advertisements