Cómo aplicar zoom, arrastre y rotación a una imagen en Android

¿Alguien puede decirme el tutorial para aplicar el zoom, arrastrar y rotar sobre una imagen en la aplicación de Android?

Intenta con el siguiente código que funciona para mí.

float[] lastEvent = null; float d = 0f; float newRot = 0f; private Matrix matrix = new Matrix(); private Matrix savedMatrix = new Matrix(); public static String fileNAME; public static int framePos = 0; private float scale = 0; private float newDist = 0; // Fields private String TAG = this.getClass().getSimpleName(); // We can be in one of these 3 states private static final int NONE = 0; private static final int DRAG = 1; private static final int ZOOM = 2; private int mode = NONE; // Remember some things for zooming private PointF start = new PointF(); private PointF mid = new PointF(); float oldDist = 1f; public boolean onTouch(View v, MotionEvent event) { ImageView view = (ImageView) v; // 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; lastEvent = null; break; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); if (oldDist > 10f) { savedMatrix.set(matrix); midPoint(mid, event); mode = ZOOM; } lastEvent = new float[4]; lastEvent[0] = event.getX(0); lastEvent[1] = event.getX(1); lastEvent[2] = event.getY(0); lastEvent[3] = event.getY(1); d = rotation(event); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode = NONE; lastEvent = null; 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 && event.getPointerCount() == 2) { float newDist = spacing(event); matrix.set(savedMatrix); if (newDist > 10f) { float scale = newDist / oldDist; matrix.postScale(scale, scale, mid.x, mid.y); } if (lastEvent != null) { newRot = rotation(event); float r = newRot - d; matrix.postRotate(r, view.getMeasuredWidth() / 2, view.getMeasuredHeight() / 2); } } break; } view.setImageMatrix(matrix); return true; } 

// Para rotar la imagen en multi-touch.

 private float rotation(MotionEvent event) { double delta_x = (event.getX(0) - event.getX(1)); double delta_y = (event.getY(0) - event.getY(1)); double radians = Math.atan2(delta_y, delta_x); return (float) Math.toDegrees(radians); } 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); } 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); } 

Aquí está el código completo para pellizcar y panoramizar (Touch.java con algunas modificaciones que se pueden usar prácticamente)

 public class Touch implements OnTouchListener { // These matrices will be used to move and zoom image public static Matrix matrix = new Matrix(); public static 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; private static final float MAX_ZOOM = (float) 3; private static final float MIN_ZOOM = 1; int mode = NONE; // Remember some things for zooming PointF start = new PointF(); PointF mid = new PointF(); float oldDist = 1f; int width,height; @Override public boolean onTouch(View v, MotionEvent event) { ImageView view = (ImageView) v; Rect bounds = view.getDrawable().getBounds(); width = bounds.right - bounds.left; height = bounds.bottom - bounds.top; // Dump touch event to log dumpEvent(event); // 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; } //---------------------------------------------------- limitZoom(matrix); limitDrag( matrix); //---------------------------------------------------- view.setImageMatrix(matrix); return true; // indicate event was handled } /** Show an event in the LogCat view, for debugging */ private void dumpEvent(MotionEvent event) { String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" }; StringBuilder sb = new StringBuilder(); int action = event.getAction(); int actionCode = action & MotionEvent.ACTION_MASK; sb.append("event ACTION_").append(names[actionCode]); if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) { sb.append("(pid ").append( action >> MotionEvent.ACTION_POINTER_ID_SHIFT); sb.append(")"); } sb.append("["); for (int i = 0; i < event.getPointerCount(); i++) { sb.append("#").append(i); sb.append("(pid ").append(event.getPointerId(i)); sb.append(")=").append((int) event.getX(i)); sb.append(",").append((int) event.getY(i)); if (i + 1 < event.getPointerCount()) sb.append(";"); } sb.append("]"); } /** 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); } private void limitZoom(Matrix m) { float[] values = new float[9]; m.getValues(values); float scaleX = values[Matrix.MSCALE_X]; float scaleY = values[Matrix.MSCALE_Y]; if(scaleX > MAX_ZOOM) { scaleX = MAX_ZOOM; } else if(scaleX < MIN_ZOOM) { scaleX = MIN_ZOOM; } if(scaleY > MAX_ZOOM) { scaleY = MAX_ZOOM; } else if(scaleY < MIN_ZOOM) { scaleY = MIN_ZOOM; } values[Matrix.MSCALE_X] = scaleX; values[Matrix.MSCALE_Y] = scaleY; m.setValues(values); } private void limitDrag(Matrix m) { float[] values = new float[9]; m.getValues(values); float transX = values[Matrix.MTRANS_X]; float transY = values[Matrix.MTRANS_Y]; float scaleX = values[Matrix.MSCALE_X]; float scaleY = values[Matrix.MSCALE_Y]; //--- limit moving to left --- float minX = (-width + 0) * (scaleX-1); float minY = (-height + 0) * (scaleY-1); //--- limit moving to right --- float maxX=minX+width*(scaleX-1); float maxY=minY+height*(scaleY-1); if(transX>maxX){transX = maxX;} if(transXmaxY){transY = maxY;} if(transY 

compruebe que esto puede ser útil para usted Gire la imagen de arrastre de zoom en la vista de la imagen de Android

acercar y arrastrar imágenes usando la matriz en Android

Acabo de publicar una nueva biblioteca de gestos sofisticados para bitbucket.

Podrás manipular cualquier imagen con él.

Puede encontrar el repository aquí: https://bitbucket.org/warwick/hacergestov3

Puede ver la aplicación de demostración de Youtube aquí: https://youtu.be/0CoX5WUL6_8

O descargue la aplicación de demostración desde Google Play Store aquí: https://play.google.com/store/apps/details?id=com.WarwickWestonWright.HacerGestoV3Demo

La biblioteca tiene un uso simple y permite el uso simultáneo de los cuatro gestos clásicos: Rotar, Pellizcar / Escalar, Mover y Arrojar.