开发者

How to apply zoom, drag and rotation to an image in Android [closed]

开发者 https://www.devze.com 2023-03-18 12:17 出处:网络
Closed. This question is seeking recommendations for books, tools, software libraries, and more. It does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed. This question is seeking recommendations for books, tools, software libraries, and more. It does not meet Stack Overflow guidelines. It is not currently accepting answers.
开发者_如何学JAVA

We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.

Closed 5 years ago.

Improve this question

Can somebody tell me the tutorial to apply zoom, drag and rotate on an image in android application?


Try with below code its working for me.

    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;
            }

//For rotate image on 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);
    }


Here is the complete code for pinch zoom and pan (Touch.java with some modifications that can be used practically)

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(transX<minX){transX = minX;}
        if(transY>maxY){transY = maxY;}
        if(transY<minY){transY = minY;}
        values[Matrix.MTRANS_X] = transX;
        values[Matrix.MTRANS_Y] = transY; 
        m.setValues(values);
    }

}
0

精彩评论

暂无评论...
验证码 换一张
取 消