2013-05-19 54 views
0

所以我一直在試圖創建一個程序,可以拖動,縮放和旋轉照片。我似乎遇到的一個大問題是,每當我嘗試旋轉照片時,它都會沿着角落旋轉,而不是圍繞中心旋轉。這意味着當我嘗試旋轉圖像時,它會很快離開我的手指。每當我嘗試旋轉imageview,它只能在軸上旋轉

我遇到的另一個大問題是,每次用兩根手指觸摸時,圖像都會重置爲完全直立,而不是我觸摸時保持的角度。

@Override 
protected void onDraw(Canvas canvas) { 


    canvas.save(); 
    //if(mode==DRAG) 
    canvas.translate(mPosX, mPosY); 
    if (myScale.isInProgress()) { 
     canvas.scale(mScaleFactor, mScaleFactor, myScale.getFocusX(), myScale.getFocusY()); 
    } 
    else{ 
     canvas.scale(mScaleFactor, mScaleFactor, mLastGestureX, mLastGestureY); 
    } 

    if (myScale.isInProgress()) { 
     canvas.rotate(degrees, myScale.getFocusX(), myScale.getFocusY()); 
    } 
    else{ 
     canvas.rotate(degrees, mLastGestureX, mLastGestureY); 
    } 
    //canvas.setMatrix(matrix); 
    //setImageMatrix(matrix); 
    super.onDraw(canvas); 
    canvas.restore(); 
    //canvas.drawBitmap(,matrix,new Paint()); 
} 













@Override 
public boolean onTouchEvent(MotionEvent event) { 
    super.onTouchEvent(event); 
    if(event.getPointerCount()>1){ 

     myScale.onTouchEvent(event); 
    } 
    switch (event.getAction() & MotionEvent.ACTION_MASK){ 
      case MotionEvent.ACTION_DOWN: { 
       savedMatrix.set(matrix); 

       final float x = event.getX(); 
       final float y = event.getY(); 
       mode=DRAG; 
       // Remember where we started 
       mLastTouchX = x; 
       mLastTouchY = y; 
       mActivePointerId = event.getPointerId(0); 
       lastEvent = null; 
       break; 
      } 
     case MotionEvent.ACTION_POINTER_DOWN: { 
      oldDist = spacing(event); 
      //savedMatrix.set(matrix); 
      //midPoint(mid, event); 
      Log.d("touchResponse: ", "mode=ZOOM"); 
      final float gx = myScale.getFocusX(); 
      final float gy = myScale.getFocusY(); 
      mLastGestureX=gx; 
      mLastGestureY=gy; 
      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_MOVE: { 
       final int pointerIndex = event.findPointerIndex(mActivePointerId); 
       final float x = event.getX(pointerIndex); 
       final float y = event.getY(pointerIndex); 


       // Calculate the distance moved 

      if(!myScale.isInProgress()&&mode==DRAG){ 
        // Move the object 
       float dx = x-mLastTouchX; 
       float dy = y-mLastTouchY; 
        mPosX+=dx; 
        mPosY+=dy; 


        // Remember this touch position for the next move event 


        // Invalidate to request a redraw 
        invalidate(); 

      } 
       mLastTouchX = x; 
       mLastTouchY = y; 
       if(event.getPointerCount()==2){ 
        if (lastEvent!=null){ 
        newRot=rotation(event); 
        degrees = newRot-d; 

        } 

       } 
       invalidate(); 
       break; 

      } 

     case MotionEvent.ACTION_UP: { 

     } 


     case MotionEvent.ACTION_POINTER_UP: { 
      // Extract the index of the pointer that left the touch sensor\ 
      mode=NONE; 
      mode = NONE; 
      lastEvent = null; 
      final int pointerIndex = (event.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) 
        >> MotionEvent.ACTION_POINTER_INDEX_SHIFT; 
      final int pointerId = event.getPointerId(pointerIndex); 
      if (pointerId == mActivePointerId) { 
       // This was our active pointer going up. Choose a new 
       // active pointer and adjust accordingly. 
       final int newPointerIndex = pointerIndex == 0 ? 1 : 0; 
       mLastTouchX = event.getX(newPointerIndex); 
       mLastTouchY = event.getY(newPointerIndex); 
       mActivePointerId = event.getPointerId(newPointerIndex); 
      } 
      invalidate(); 

      break; 
     } 

     } 

    return true; 
} 
















//this is a method i ripped from a tutoriaql 
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); 
} 

private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
    @Override 
    public boolean onScale(ScaleGestureDetector detector) { 

     mScaleFactor *= detector.getScaleFactor(); 

     // Don't let the object get too small or too large. 
     mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 10.0f)); 


     //matrix=temp; 

     invalidate(); 
     return true; 
    } 
} 

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)); 
    Log.d("Rotation ~~~~~~~~~~~~~~~~~", delta_x+" ## "+delta_y+" ## "+radians+" ## " 
      +Math.toDegrees(radians)); 
    return (float) Math.toDegrees(radians); 
} 

回答

0

如果要圍繞中心旋轉,則需要先轉到中心。這會將新原點設置爲圖像的中心,並且始終圍繞原點旋轉。