2011-12-15 24 views
8

tôi muốn xoay và chia tỷ lệ hình ảnh trên sự kiện đa chạm, tôi có thể kéo, chia tỷ lệ hình ảnh nhưng tôi không thể hiểu được hình ảnh xoay. Tôi đang gặp vấn đề, vì vậy hãy giúp tôi càng sớm càng tốt. mã của tôi là cóxoay và chia tỷ lệ bằng cảm ứng đa điểm trong android

public class Touch extends Activity implements OnTouchListener { 
     private static final String TAG = "Touch"; 
     // These matrices will be used to move and zoom image 
     Matrix matrix = new Matrix(); 
    Matrix matrix1 = new Matrix(); 
    Matrix savedMatrix = new Matrix(); 
    Matrix savedMatrix2 = 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; 
    float oldscale =0; 
    // Remember some things for zooming 
    PointF start = new PointF(); 
    PointF mid = new PointF(); 
    float oldDist = 1f; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     ImageView view = (ImageView) findViewById(R.id.imageView2); 
     view.setOnTouchListener(this); 

     ImageView view1 = (ImageView) findViewById(R.id.imageView2); 
     view1.setOnTouchListener(this); 

     // ... 
     // Work around a Cupcake bug 
     matrix.setTranslate(1f, 1f); 
     matrix1.setTranslate(1f, 1f); 
     view.setImageMatrix(matrix); 
     view1.setImageMatrix(matrix1); 
    } 

    @Override 
    public boolean onTouch(View v, MotionEvent rawEvent) { 
     WrapMotionEvent event = WrapMotionEvent.wrap(rawEvent); 
     // ... 
     ImageView view = (ImageView) v; 

     // Dump touch event to log 
     dumpEvent(event); 

     // Handle touch events here... 
     double r = Math.atan2(event.getX() - 400/2, 
      400/2 - event.getY()); 
     int rotation = (int) Math.toDegrees(r); 
     float newRot = new Float(rotation); 

     switch (event.getAction() & MotionEvent.ACTION_MASK) { 

     case MotionEvent.ACTION_DOWN: 
     savedMatrix.set(matrix); 
     start.set(event.getX(), event.getY()); 
     Log.d(TAG, "mode=DRAG"); 
     mode = DRAG; 
     break; 
     case MotionEvent.ACTION_POINTER_DOWN: 
     oldDist = spacing(event); 
     Log.d(TAG, "oldDist=" + oldDist); 
     if (oldDist > 10f) { 
      savedMatrix.set(matrix); 
      midPoint(mid, event); 
      mode = ZOOM; 
      Log.d(TAG, "mode=ZOOM"); 

     } 
     break; 
     case MotionEvent.ACTION_UP: 
     case MotionEvent.ACTION_POINTER_UP: 
     mode = NONE; 
     Log.d(TAG, "mode=NONE"); 
     break; 
     case MotionEvent.ACTION_MOVE: 
      matrix.postRotate(15); 
     if (mode == DRAG) { 
      // ... 
      matrix.set(savedMatrix); 
      matrix.postTranslate(event.getX() - start.x, 
        event.getY() - start.y); 
     } 
     else if (mode == ZOOM) { 
      float newDist = spacing(event); 
      Log.d(TAG, "newDist=" + newDist); 
      if (newDist > 10f) { 
       matrix.set(savedMatrix); 
       float scale = newDist/oldDist; 
       matrix.postScale(scale, scale, mid.x, mid.y); 
       Log.e("scale | mid.x | mid.y", scale + " " +mid.x + " " + mid.y); 

      } 
     } 
     break; 
     } 
     view.setImageMatrix(matrix); 
     return true; // indicate event was handled 
    } 

    /** Show an event in the LogCat view, for debugging */ 
    private void dumpEvent(WrapMotionEvent 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("]"); 
     Log.d(TAG, sb.toString()); 
    } 

    /** Determine the space between the first two fingers */ 
    private float spacing(WrapMotionEvent 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, WrapMotionEvent event) { 
     // ... 
     float x = event.getX(0) + event.getX(1); 
     float y = event.getY(0) + event.getY(1); 
     point.set(x/2, y/2); 
    } 
} 

vì vậy hãy cung cấp cho tôi giải pháp chính xác cho vấn đề này.

Trả lời

10
float[] lastEvent = null; 
    float d = 0f; 
    float newRot = 0f; 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     ImageView view = (ImageView) v; 

     // 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()); 
    if (Constant.TRACE) Log.d(TAG, "mode=DRAG"); 
    mode = DRAG; 
    lastEvent = null; 
    break; 
    case MotionEvent.ACTION_POINTER_DOWN: 
    oldDist = spacing(event);   
    savedMatrix.set(matrix); 
    midPoint(mid, event); 
    mode = ZOOM; 
    if (Constant.TRACE) Log.d(TAG, "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; 
    if (Constant.TRACE) Log.d(TAG, "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 && event.getPointerCount()==2) { 
     float newDist = spacing(event); 
     if (Constant.TRACE) Log.d(TAG, "Count=" + event.getPointerCount()); 
     if (Constant.TRACE) Log.d(TAG, "newDist=" + newDist); 
     matrix.set(savedMatrix); 
     if (newDist > 10f) {    
      float scale = newDist/oldDist; 
      matrix.postScale(scale, scale, mid.x, mid.y); 
     } 
     if (lastEvent!=null){ 
      newRot = rotation(event); 
      if (Constant.TRACE) Log.d("Degreeeeeeeeeee", "newRot="+(newRot)); 
      float r = newRot-d; 
      matrix.postRotate(r, imgView.getMeasuredWidth()/2, imgView.getMeasuredHeight()/2); 
     } 
    } 
    break; 
    } 

    view.setImageMatrix(matrix); 
    return true; // indicate event was handled 

}

/** Determine the degree between the first two fingers */ 
    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);  
     if (Constant.TRACE) Log.d("Rotation ~~~~~~~~~~~~~~~~~", delta_x+" ## "+delta_y+" ## "+radians+" ## " 
         +Math.toDegrees(radians)); 
     return (float) Math.toDegrees(radians); 
    } 

Hãy thử mã này, nhưng hãy nhớ một số điện thoại cũ có vấn đề với vòng xoay ..

+0

ảnh vui nhộn. Nó làm việc cho tôi. – Santhosh

+1

Tôi đã thử đoạn mã trên, nó tốt nhưng hình ảnh không xoay quanh trục riêng của nó, nó cần phải xoay quanh điểm trung tâm của nó nhưng vì tỉ lệ được hiển thị ở vị trí sai. Cách tìm tọa độ tương đối cho nó. – strike

+0

@strike, bạn có thể lưu bản dịch hiện tại của hình ảnh và tính điểm trung tâm. Và đừng quên chia tỷ lệ. – someUser

Các vấn đề liên quan