问题
I am using code found in Hello Android, 3rd Edition for Pinch to Zoom functionality. After using this the pinch to zoom works fine, but after zooming i want to get the absolute click position on the image view.
Here is my code
package org.example.touch;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.os.Bundle;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.GridView;
import android.widget.ImageView;
public class Touch extends Activity implements OnTouchListener {
private static final String TAG = "Touch";
private static final float MIN_ZOOM = 1.0f;
private static final float MAX_ZOOM = 5.0f;
// These matrices will be used to move and zoom image
Matrix matrix = new Matrix();
Matrix savedMatrix = new Matrix();
// We can be in one of these 3 states
static final int NONE = 0;
static final int DRAG = 1;
static final int ZOOM = 2;
int mode = NONE;
// Remember some things for zooming
PointF start = new PointF();
PointF mid = new PointF();
float oldDist = 1f;
ImageView image2;
image2 = (ImageView)this.findViewById(R.id.imageView2);
image2.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
ImageView view = (ImageView) image2;
// Handle touch events here...
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
savedMatrix.set(matrix);
start.set(event.getX(), event.getY());
mode = DRAG;
break;
case MotionEvent.ACTION_POINTER_DOWN:
oldDist = spacing(event);
if (oldDist > 10f) {
savedMatrix.set(matrix);
midPoint(mid, event);
mode = ZOOM;
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
mode = NONE;
break;
case MotionEvent.ACTION_MOVE:
if (mode == DRAG) {
matrix.set(savedMatrix);
matrix.postTranslate(event.getX() - start.x, event.getY() - start.y);
}
else if (mode == ZOOM) {
float newDist = spacing(event);
if (newDist > 10f) {
matrix.set(savedMatrix);
float scale = newDist / oldDist;
matrix.postScale(scale, scale, mid.x, mid.y);
}
}
break;
}
view.setImageMatrix(matrix);
}
/** Determine the space between the first two fingers */
private float spacing(MotionEvent event) {
float x = event.getX(0) - event.getX(1);
float y = event.getY(0) - event.getY(1);
return FloatMath.sqrt(x * x + y * y);
}
/** Calculate the mid point of the first two fingers */
private void midPoint(PointF point, MotionEvent event) {
float x = event.getX(0) + event.getX(1);
float y = event.getY(0) + event.getY(1);
point.set(x / 2, y / 2);
}
回答1:
You can use the matrix that is currently applied to the imageview to map points to/from the original default points.
//points from a touch/click event on the zoomed/translated imageview
float X;
float Y;
float initialPoints = new float[]{X, Y};
//invert the matrix and map points back
if(transformMatrix.invert(inverseTransformMatrix))
inverseTransformMatrix.mapPoints(initialFocalPoints);
initialPoints
now contains the original points, i.e where the click point would be if no matrix was applied to the imageview
EDIT: should have added this in there somewhere so you know what they are.
Matrix inverseTransformMatrix = new Matrix();
Matrix transformMatrix = new Matrix();
回答2:
Apply the below logic
float[] values = new float[9];
matrix.getValues(values);
calculate scalefactor before pinchzoom;
scaleX=values[0];
scaleY=vales[4];
Now calculate the relative touch coordinates according to iamge after pinch zoom
float relativeX = ((event.getX() - values[2])*sacleX) / values[0];
float relativeY = ((event.getY() - values[5])*scaleY) / values[4];
来源:https://stackoverflow.com/questions/11519132/android-find-absolute-click-position-on-the-imageview-after-zooming-using-pinc