Android drawMatrix转换位图后如何取回原始坐标
Android How to get original coordinates back after transformation of bitmap with drawMatrix
我有以下问题。我有一个位图,在这个位图上可以完成某些绘制操作。比如画线、箭头等等
效果很好,但位图可以缩放、拖动和旋转。为此,使用了 drawMatrix。这一切都很好,但是,为了绘图,我需要原始坐标,以便绘图大小合适,等等。
我可以用下面的函数得到这个原始坐标。但它不适用于轮换。有没有人知道如何解决这个问题?
/**
* When we have moved or zoomed we need the original image coordinates calculated from
* the screen coordinates. This function gives that back
*/
private Point translateScreenCoordsToOriginalImageCoords(MotionEvent e) {
float[] m = new float[9];
drawMatrix.getValues(m);
float transX = m[Matrix.MTRANS_X] * -1;
float transY = m[Matrix.MTRANS_Y] * -1;
float scaleX = m[Matrix.MSCALE_X];
float scaleY = m[Matrix.MSCALE_Y];
// TODO function does not work when rotated by 90 degree
if (scaleX == 0.0) {
scaleX = -1.0f;
scaleY = -1.0f;
}
int lastTouchX = (int) ((e.getX() + transX) / scaleX);
int lastTouchY = (int) ((e.getY() + transY) / scaleY);
lastTouchX = Math.abs(lastTouchX);
lastTouchY = Math.abs(lastTouchY);
return new Point(lastTouchX, lastTouchY);
}
缩放是这样进行的
/**
* Scale the canvas by
*
* @param scaleFactor e.g 2 is double
* @param focusX the center x point
* @param focusY the center y point
*
* @return true if scaling is performed
*/
private boolean doScale(float scaleFactor, int focusX, int focusY) {
if (this.scaleBoundaries(scaleFactor))
return false;
Matrix transformationMatrix = new Matrix();
// Zoom focus is where the fingers are centered
transformationMatrix.postTranslate(-focusX, -focusY);
transformationMatrix.postScale(scaleFactor, scaleFactor);
transformationMatrix.postTranslate(focusX, focusY);
drawMatrix.postConcat(transformationMatrix);
invalidate();
return true;
}
例如这是 Line
的绘制函数
@Override
public void draw(Canvas c, Matrix drawMatrix, boolean translateCoordiantes) {
float pts[] = new float[] {this.start.x, this.start.y, this.end.x, this.end.y};
if (translateCoordiantes)
drawMatrix.mapPoints(pts);
c.drawLine(pts[0], pts[1], pts[2], pts[3], this.paint);
}
哇 pskink 非常感谢!这就是答案!要取回原始坐标,请使用:
private Point translateCoordinatesBack(MotionEvent event) {
Matrix inverse = new Matrix();
drawMatrix.invert(inverse);
float[] pts = {event.getX(), event.getY()};
inverse.mapPoints(pts);
return new Point((int) pts[0], (int) pts[1]);
}
我有以下问题。我有一个位图,在这个位图上可以完成某些绘制操作。比如画线、箭头等等
效果很好,但位图可以缩放、拖动和旋转。为此,使用了 drawMatrix。这一切都很好,但是,为了绘图,我需要原始坐标,以便绘图大小合适,等等。
我可以用下面的函数得到这个原始坐标。但它不适用于轮换。有没有人知道如何解决这个问题?
/**
* When we have moved or zoomed we need the original image coordinates calculated from
* the screen coordinates. This function gives that back
*/
private Point translateScreenCoordsToOriginalImageCoords(MotionEvent e) {
float[] m = new float[9];
drawMatrix.getValues(m);
float transX = m[Matrix.MTRANS_X] * -1;
float transY = m[Matrix.MTRANS_Y] * -1;
float scaleX = m[Matrix.MSCALE_X];
float scaleY = m[Matrix.MSCALE_Y];
// TODO function does not work when rotated by 90 degree
if (scaleX == 0.0) {
scaleX = -1.0f;
scaleY = -1.0f;
}
int lastTouchX = (int) ((e.getX() + transX) / scaleX);
int lastTouchY = (int) ((e.getY() + transY) / scaleY);
lastTouchX = Math.abs(lastTouchX);
lastTouchY = Math.abs(lastTouchY);
return new Point(lastTouchX, lastTouchY);
}
缩放是这样进行的
/**
* Scale the canvas by
*
* @param scaleFactor e.g 2 is double
* @param focusX the center x point
* @param focusY the center y point
*
* @return true if scaling is performed
*/
private boolean doScale(float scaleFactor, int focusX, int focusY) {
if (this.scaleBoundaries(scaleFactor))
return false;
Matrix transformationMatrix = new Matrix();
// Zoom focus is where the fingers are centered
transformationMatrix.postTranslate(-focusX, -focusY);
transformationMatrix.postScale(scaleFactor, scaleFactor);
transformationMatrix.postTranslate(focusX, focusY);
drawMatrix.postConcat(transformationMatrix);
invalidate();
return true;
}
例如这是 Line
的绘制函数@Override
public void draw(Canvas c, Matrix drawMatrix, boolean translateCoordiantes) {
float pts[] = new float[] {this.start.x, this.start.y, this.end.x, this.end.y};
if (translateCoordiantes)
drawMatrix.mapPoints(pts);
c.drawLine(pts[0], pts[1], pts[2], pts[3], this.paint);
}
哇 pskink 非常感谢!这就是答案!要取回原始坐标,请使用:
private Point translateCoordinatesBack(MotionEvent event) {
Matrix inverse = new Matrix();
drawMatrix.invert(inverse);
float[] pts = {event.getX(), event.getY()};
inverse.mapPoints(pts);
return new Point((int) pts[0], (int) pts[1]);
}