我正在创建一个绘图应用程序,我有一个使用画布绘制的视图。我使用矩阵缩放图像,当图像放大并且有触摸事件时,我尝试获取矩阵的逆矩阵,然后使用逆矩阵映射点以获得点上的点来自运动事件点的画布,但它不匹配它应该如何并且想知道我做错了从屏幕触摸位置获取画布位置。
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;
}
}
答案 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);
将矩阵值舍入为整数,因为在绘制画布时,我通过映射逆矩阵上的点得到的画布点略有偏差。