2013-05-22 2 views
0

멀티 터치 이벤트에서 이미지를 회전하고 크기를 조정하고 이동하려는 경우 작동하는 것처럼 보이지만 완벽하게 작동하지 않습니다. 내 잘못된 코드를 수정하고 싶습니다. 그래서 제발 도와주세요. 내 코드는안드로이드에서 멀티 터치를 사용하여 회전 및 크기 조정 및 이동

public class ImageControl extends Activity { 
    DragView dragView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     dragView = new DragView(this); 
     setContentView(dragView); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Inflate the menu; this adds items to the action bar if it is present. 
     getMenuInflater().inflate(R.menu.image_control, menu); 
     return true; 
    } 
    class DragView extends ImageView 
    { 
     private Bitmap bitmap; 

       private float width; 
     private float height; 

     private float startX=0; 
     private float startY=0; 

     private float userX=0; 
     private float userY=0; 

     private Paint paint; 

     private float oldDistance = 1f; 
     private float newDistance = 1f; 

     private Rect rect; 

     static final int NONE = 0; 
     static final int DRAG = 1; 
     static final int ZOOM = 2; 
     int mode = NONE;  

     private int lastAngle=0; 

     private int thisAngle=0; 

     private int deltaAngle; 

     private int angle; 

     int rotateX, rotateY; 

     private Matrix mat; 

     private float x1; 
     private float y1; 

     public DragView(Context context){ 
      super(context); 
      init(); 
      setImage(context); 
     } 
     private void init(){ 
      paint = new Paint(); 
      paint.setColor(Color.RED); 
      paint.setStyle(Paint.Style.STROKE); 
      paint.setAntiAlias(true); 
      mat = new Matrix(); 
     } 
     private void setImage(Context context){ 
      bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.android); 
      width = bitmap.getWidth(); 
      height = bitmap.getHeight(); 
     } 
     public void onDraw(Canvas canvas){ 
      if(bitmap!=null) 
      { 
       canvas.drawBitmap(bitmap, mat, null); 
       canvas.drawRect(userX, userY, userX+width, userY+height, paint); 
      } 
     } 
     public Rect getRect(){ 
      rect = new Rect(); 
      rect.set((int)userX, (int)userY, (int)(userX+width), (int)(userY+height)); 
      return rect; 
     } 
     public void setXY(float x, float y){ 
      startX = x; 
      startY= y; 

     } 
     public boolean onTouchEvent(MotionEvent event){ 
      x1 = event.getX(0); 
      y1 = event.getY(0); 
      int act = event.getAction(); 
      switch(act&MotionEvent.ACTION_MASK){ 
      case MotionEvent.ACTION_DOWN: 
       setXY(x1, y1); 
       mode=DRAG; 
       break; 
      case MotionEvent.ACTION_MOVE: 
       if(mode==ZOOM){ 
        newDistance = spacing(event); 
        float scale2 = FloatMath.sqrt(((newDistance-oldDistance)*(newDistance-oldDistance)) 
          /(height*height+width*width)); 
        float scale = newDistance/oldDistance; 
        if(newDistance - oldDistance > 0){ 
         setZoom(scale, scale2); 
        }else if(oldDistance - newDistance > 0){ 
         setZoom(scale, -scale2); 
        } 
        setRotate(event, x1, y1); 
       } 
       else if(mode==DRAG){ 
        setLastXY(x1-startX, y1-startY); 
        setXY(x1, y1); 
       } 
       break; 
      case MotionEvent.ACTION_UP: 
      case MotionEvent.ACTION_POINTER_UP: 
       mode = NONE; 
       break; 
      case MotionEvent.ACTION_POINTER_DOWN: 
        mode = ZOOM; 
        float value = spacing(event); 
        oldDistance = value; 
        newDistance = value; 
        break; 
      case MotionEvent.ACTION_CANCEL: 
      default: 
        break; 
      } 
      return true; 
     } 
     private void setLastXY(float x, float y){ 
      userX += x; 
      userY += y; 
      mat.setTranslate(userX, userY); 
      invalidate(); 
     } 
     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 setZoom(float scale, float scale2){ 

      userY=userY-(height*scale2/2); 
      userX=userX-(width*scale2/2); 
      height=height*(1+scale2); 
      width=width*(1+scale2); 
      Log.d("ZoomTAG", "scale:"+scale); 
      mat.postScale(scale, scale, userX+width/2, userY+height/2); 
      oldDistance = newDistance; 
      invalidate(); 
     } 
     private void setRotate(MotionEvent event, float x1, float y1){ 
      float x2 = event.getX(1); 
      float y2 = event.getY(1); 
      thisAngle = (int)Math.toDegrees(Math.atan2(-(y2-y1), x2-x1)); 
      if(lastAngle==0){ 
       lastAngle=thisAngle; 
      } 
      deltaAngle = thisAngle-lastAngle; 
      angle += -deltaAngle; 
      lastAngle = thisAngle; 
      float minX = Math.min(x1, x2); 
      float minY = Math.min(y1, y2); 
      rotateX = (int)minX + (Math.abs((int)(x1-x2))/2); 
      rotateY = (int)minY + (Math.abs((int)(y1-y2))/2); 
      Log.d("TAG", "Angle : " + angle); 
      mat.postRotate(angle, userX+width/2, userY+height/2); 
      invalidate(); 
     } 
    } 
} 
+2

당신은 조금 더보다 구체적으로해야합니다. 의도 한대로 작동하지 않는 것은 무엇입니까? – britzl

+0

Ok ~ 멀티 터치로 이미지의 크기를 조정하면 움직이는 것보다 이미지가 너무 빨리 회전하고 이미지를 옮길 때 이미지가 원래 크기로 돌아갑니다. 도움을 위해 미리 감사드립니다! – user2361625

답변

0

가장 좋은 방법은 어떤 품질의 손실없이 (크기 조정, 회전) 변경을위한 매트릭스를 사용하는가이다. Try something like this 및 ACTION_DOWN을주의 깊게보고 ACTION_MOVE :

import android.app.Activity; 
import android.graphics.Matrix; 
import android.graphics.PointF; 
import android.os.Bundle; 
import android.util.FloatMath; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 
import android.widget.ImageView; 

public class MultiTouch extends Activity implements OnTouchListener { 

// these matrices will be used to move and zoom image 
private Matrix matrix = new Matrix(); 
private Matrix savedMatrix = new Matrix(); 
// 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(); 
private float oldDist = 1f; 
private float d = 0f; 
private float newRot = 0f; 
private float[] lastEvent = null; 

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

public boolean onTouch(View v, MotionEvent event) { 
    // handle touch events here 
    ImageView view = (ImageView) v; 
    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); 
       float dx = event.getX() - start.x; 
       float dy = event.getY() - start.y; 
       matrix.postTranslate(dx, dy); 
      } 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); 
       } 
       if (lastEvent != null && event.getPointerCount() == 3) { 
        newRot = rotation(event); 
        float r = newRot - d; 
        float[] values = new float[9]; 
        matrix.getValues(values); 
        float tx = values[2]; 
        float ty = values[5]; 
        float sx = values[0]; 
        float xc = (view.getWidth()/2) * sx; 
        float yc = (view.getHeight()/2) * sx; 
        matrix.postRotate(r, tx + xc, ty + yc); 
       } 
      } 
      break; 
    } 

    view.setImageMatrix(matrix); 
    return true; 
} 

/** 
* 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); 
} 

/** 
* Calculate the degree to be rotated by. 
* 
* @param event 
* @return Degrees 
*/ 
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); 
} 

}

관련 문제