2016-03-25 15 views
1

Ich erstelle eine Zeichen-App, und ich habe eine Ansicht, die eine Leinwand zum Zeichnen verwendet. Ich skaliere das Bild mit einer Matrix, und wenn das Bild vergrößert wird und ein Berührungsereignis eintritt, versuche ich, die Inverse der Matrix zu erhalten und mappe die Punkte dann mit der inversen Matrix, um die Punkte auf der Leinwand zu erhalten Das motionevent zeigt, aber es stimmt nicht überein, wie es sollte, und frage mich, was ich falsch mache, um den Canvas-Ort vom Bildschirm Touch-Ort zu bekommen.Erhalte die Position auf der Leinwand von der Position des Bewegungsereignisses, wenn sie mit der Matrix skaliert wird

public class CustomDrawableView extends View { 
    private Paint mBitmapPaint; 
    private ShapeDrawable mDrawable; 
    private ScaleGestureDetector detector; 
    Matrix drawMatrix; 
    Bitmap bm; 

    @Override 
    protected void onDraw(Canvas canvas) { 
      super.onDraw(canvas); 
      canvas.save();   
      canvas.drawBitmap(bm, drawMatrix, mBitmapPaint);   
      mDrawable.draw(canvas); 
      canvas.restore();  
    } 
    public Pair<Float,Float> GetRealValues(float eventX, float eventY){   
     Matrix inverse = new Matrix(); 
     drawMatrix.invert(inverse); 
     float[] point = {eventX,eventY}; 
     inverse.mapPoints(point);  
     return new Pair<>(point[0],point[1]); 
    } 

    @Override 
    //reads motions and calls methods to set starting and ending points and to 
    //draw canvas depending on the motion 
    public boolean onTouchEvent(MotionEvent event) { 
     //get the canvas location from the MotionEvent location  
     Pair<Float,Float> realvals = GetRealValues(event.getX(),event.getY()); 
     //drawing mode where you can draw or zoom in on canvas 
      if(drawing) { 
       //not zooming mode where you draw on canvas 
       if (!zoom) { 
        switch (event.getAction() & MotionEvent.ACTION_MASK) {        
         case MotionEvent.ACTION_DOWN: 
          //do stuff 
          break;        
         case MotionEvent.ACTION_MOVE: 
          //do stuff 
          break; 
         case MotionEvent.ACTION_UP: 
          //do stuff 
          break; 
         case MotionEvent.ACTION_POINTER_UP: 
          break; 
        } 
     } 
     //zoom mode where you can scale the canvas 
      if (zoom) { 
       detector.onTouchEvent(event);       
       invalidate(); 
      } 
     }   
    return true; 
} 



    public class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
     private float MIN_ZOOM = 1f; 
     private float MAX_ZOOM = 10f;  

     @Override 
     public boolean onScale(ScaleGestureDetector detector) { 
      Matrix transformationMatrix = new Matrix(); 
      scaleFactor *= detector.getScaleFactor(); 
      float tscale = detector.getScaleFactor(); 
      if(scaleFactor < MIN_ZOOM || scaleFactor > MAX_ZOOM){ 
       float prescaleFactor = scaleFactor/tscale; 
       scaleFactor = Math.max(MIN_ZOOM, Math.min(scaleFactor, MAX_ZOOM)); 
       tscale = scaleFactor/prescaleFactor; 
      } 
      transformationMatrix.postScale(tscale, tscale);    
      drawMatrix.postConcat(transformationMatrix); 
      return true; 
    } 
} 

Antwort

0

Eine Antwort gefunden. Meine OnDraw Methode muss wie diese

@Override 
protected void onDraw(Canvas canvas) { 
    super.onDraw(canvas); 
     canvas.save();   
     float[] mvals = new float[9]; 
     drawMatrix.getValues(mvals); 
     canvas.translate(mvals[Matrix.MTRANS_X], mvals[Matrix.MTRANS_Y]); 
     canvas.scale(mvals[Matrix.MSCALE_X], mvals[Matrix.MSCALE_Y]); 
     canvas.drawBitmap(bm, 0, 0, mBitmapPaint); 
     mDrawable.draw(canvas); 
     canvas.restore(); 
} 

sein, die ich bin mir nicht sicher, warum ich brauche die Leinwand einzeln, um zu übersetzen und zu skalieren für die inverse Matrix mir die richtigen Leinwand Punkte aus den Berührungspunkten zu geben, ich m zu raten, dass

canvas.drawBitmap(bm, drawMatrix, mBitmapPaint); 

Runde der Matrixwerte zu ints, weil die Leinwand Punkte i aus Abbildung die Punkte auf der inversen Matrix bekam nur etwas weg waren, als die Leinwand, dass die Art und Weise zu ziehen.