如何在 canvas 或 ImageView android 上获得正确的坐标 Zoom In

How to get right coordinates Zoom In on canvas or ImageView android

基本上我想在缩放图像时在 imageView 上画线。 问题是我不知道如何在放大

时获得触摸事件的正确坐标

这是我的代码:

    public boolean onTouch(View v, MotionEvent event) {
    ImageView view = (ImageView) v;
    view.setScaleType(ImageView.ScaleType.MATRIX);

    // Handle touch events here...
    switch (event.getAction() & MotionEvent.ACTION_MASK) {

        case MotionEvent.ACTION_DOWN: //first finger down only
            savedMatrix.set(matrix);
            if (draw) {
                if (i == 1) {
                    startX = event.getX();
                    startY = event.getY();

                    i = 2;
                } else if (i == 2) {
                    endX = event.getX();
                    endY = event.getY();                        
                    onDraw();
                    i = 3;

                } else if (i == 3) {

                    startX = event.getX();
                    startY = event.getY();

                    onDraw();
                    i = 2;
                }
            } else {
                start.set(event.getX(), event.getY());
                Log.d(TAG, "mode=DRAG");
                mode = DRAG;
            }

            break;
        case MotionEvent.ACTION_UP: //first finger lifted
        case MotionEvent.ACTION_POINTER_UP: //second finger lifted
            if (!draw) {
                mode = NONE;
                Log.d(TAG, "mode=NONE");
            }
            break;
        case MotionEvent.ACTION_POINTER_DOWN: //second finger down
            if (!draw) {
                oldDist = spacing(event);
                Log.d(TAG, "oldDist=" + oldDist);
                if (oldDist > 10f) {
                    savedMatrix.set(matrix);
                    midPoint(mid, event);

                }
            }
            break;
        case MotionEvent.ACTION_MOVE:
            if (!draw) {
                if (mode == DRAG) {
                    matrix.set(savedMatrix);

                    matrix.getValues(matrixValues);
                    matrixX = matrixValues[2];
                    matrixY = matrixValues[5];
                    width = matrixValues[0] * (view.getDrawable().getIntrinsicWidth());
                    height = matrixValues[4] * (view.getDrawable().getIntrinsicHeight());

                    dx = event.getX() - start.x;
                    dy = event.getY() - start.y;
                    //if image will go outside left bound
                    if (matrixX + dx > 0) {
                        dx = -matrixX;
                    }
                    //if image will go outside right bound
                    if (matrixX + dx + width < view.getWidth()) {
                        dx = view.getWidth() - matrixX - width;
                    }

                    //if image will go oustside top bound
                    if (matrixY + dy > 0) {
                        dy = -matrixY;
                    }
                    //if image will go outside bottom bound
                    if (matrixY + dy + height < view.getHeight()) {
                        dy = view.getHeight() - matrixY - height;
                    }
                    matrix.postTranslate(dx, dy);

                }
                break;
            }
    } //perform the transformation.

    view.setImageMatrix(matrix);
    return true; // indicate event was handled

}

private float spacing(MotionEvent event) {
    float x = event.getX(0) - event.getX(1);
    float y = event.getY(0) - event.getY(1);
    return (float) Math.sqrt(x * x + y * y);
}

private void midPoint(PointF point, MotionEvent event) {
    float x = event.getX(0) + event.getX(1);
    float y = event.getY(0) + event.getY(1);
    point.set(x / 2, y / 2);
}

private void sizeScreen() {
    DisplayMetrics displaymetrics = new DisplayMetrics();
    getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
    screenHeight = displaymetrics.heightPixels;
    screenWidth = displaymetrics.widthPixels;
}

这里是缩放的方法

@Override
public void onClick(View v) { // Parameter v stands for the imageView that was clicked.

    matrix.set(savedMatrix);
    float[] values = new float[9];
    matrix.getValues(values);

    switch (v.getId()) {

        case (R.id.bt_zoom_in):
            if (!draw) {
                scale = scale + 0.1f;
                if (scale > MAX_ZOOM) {
                    scale = MAX_ZOOM;
                } else if (scale < MIN_ZOOM) {
                    scale = MIN_ZOOM;
                }


            }
            break;
        case R.id.bt_zoom_out:
            if (!draw) {
                scale = scale - 0.1f;
                if (scale > MAX_ZOOM) {
                    scale = MAX_ZOOM;
                } else if (scale < MIN_ZOOM) {
                    scale = MIN_ZOOM;
                }
                //matrix.setScale(scale, scale, mid.x, mid.y);
                //imageView.setImageMatrix(matrix);
            }
            break;

        case R.id.bt_draw:
            if (draw) {
                draw = false;
                bt_draw.setText("Draw");

            } else {
                draw = true;
                bt_draw.setText("Finish");

            }
            break;
    }
    matrix.setScale(scale, scale, mid.x, mid.y);
    imageView.setImageMatrix(matrix);

}

这是绘制方法

public void onDraw() {
    Bitmap lineABmp = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
    Bitmap lineAMutBmp = lineABmp.copy(Bitmap.Config.ARGB_8888, true);
    Bitmap copy = Bitmap.createBitmap(lineAMutBmp);
    Canvas c = new Canvas(copy);

    Paint pnt = new Paint();
    pnt.setColor(Color.rgb(27, 163, 156));
    pnt.setStrokeWidth(7);

    c.drawLine(startX, startY, endX, endY, pnt);
    imageView.setImageBitmap(copy);

}
}

终于用这个 link 我用了安德烈斯的答案

public boolean onTouch(View v, MotionEvent event) {
    ...
    float []m = new float[9];
    matrix.getValues(m);
    float transX = m[Matrix.MTRANS_X] * -1;
    float transY = m[Matrix.MTRANS_Y] * -1;

    // Handle touch events here...
    switch (event.getAction() & MotionEvent.ACTION_MASK) {

        case MotionEvent.ACTION_DOWN: //first finger down only
            savedMatrix.set(matrix);
            if (draw) {
                if (i == 1) {
                    startX = Math.abs((event.getX() + transX) / scale);
                    startY = Math.abs((event.getY() + transY) / scale);

                    i = 2;
                } else if (i == 2) {
                    endX = Math.abs((event.getX() + transX) / scale);
                    endY = Math.abs((event.getY() + transY) / scale);

                    onDraw();
                    i = 3;

                } else if (i == 3) {

                    startX = Math.abs((event.getX() + transX) / scale);
                    startY = Math.abs((event.getY() + transY) / scale);

                    onDraw();
                    i = 2;
                }
            } else {
                ..
            }

            break;
        case MotionEvent.ACTION_UP: //first finger lifted
        case MotionEvent.ACTION_POINTER_UP: //second finger lifted
            ...
            break;
        case MotionEvent.ACTION_POINTER_DOWN: //second finger down
            ...
            break;
        case MotionEvent.ACTION_MOVE:
            ...
                break;
            }
    } //perform the transformation.

    view.setImageMatrix(matrix);
    return true; // indicate event was handled

}