如何在 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
}
基本上我想在缩放图像时在 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
}