简体   繁体   中英

Android How to get original coordinates back after transformation of bitmap with drawMatrix

i have following problem. I have a bitmap and on this bitmap certain draw operations can be done. Like drawing a line, arrwow, etc.

This works pretty well, but the bitmap can be zoomed, dragged and rotated. For this a drawMatrix is used. Everything this works pretty good but, for drawing i need the original coordinates so that the drawings come in the right size, etc.

I can get this original coordinates with the following function. But it doesn't work with rotations. Does anybody have an idea, how to solve this?

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

This is how scaling is performed

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

eg This is the draw function of a 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);
}

Wow pskink thanks a lot! That was the answer! To get the orignal coordinates back, use:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM