使用矩阵缩放时,从运动事件位置获取画布上的位置

时间:2016-03-25 03:04:40

标签: android canvas matrix motionevent scaletransform

我正在创建一个绘图应用程序,我有一个使用画布绘制的视图。我使用矩阵缩放图像,当图像放大并且有触摸事件时,我尝试获取矩阵的逆矩阵,然后使用逆矩阵映射点以获得点上的点来自运动事件点的画布,但它不匹配它应该如何并且想知道我做错了从屏幕触摸位置获取画布位置。

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

1 个答案:

答案 0 :(得分:0)

找到答案。我的提取方法需要像这样

 @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();   
 }

我不确定为什么我需要单独翻译和缩放画布,以便逆矩阵从触摸点给出正确的画布点,我猜测

canvas.drawBitmap(bm, drawMatrix, mBitmapPaint); 

将矩阵值舍入为整数,因为在绘制画布时,我通过映射逆矩阵上的点得到的画布点略有偏差。