简体   繁体   English

如何在Android中正确地将像素坐标转换为画布坐标?

[英]How do I correctly translate pixel coordinates to canvas coordinates in Android?

I am capturing a MotionEvent for a long click in an Android SurfaceView using a GestureListener . 我捕捉MotionEvent用于在Android长时间点击SurfaceView使用GestureListener I then need to translate the coordinates of the MotionEvent to canvas coordinates, from which I can generate custom map coordinates (not Google Maps). 然后我需要将MotionEvent的坐标转换为画布坐标,从中我可以生成自定义地图坐标(而不是Google地图)。

From what I have read, I take that given MotionEvent e , e.getX() and e.getY() get pixel coordinates. 根据我的阅读,我认为给定e.getX() MotionEvent ee.getX()e.getY()得到像素坐标。 How can I convert these coordinates to the SurfaceView 's canvas coordinates? 如何将这些坐标转换为SurfaceView的画布坐标?

Here is my GestureListener for listening for long clicks: 这是我的GestureListener用于收听长时间点击:

/**
* Overrides touch gestures not handled by the default touch listener
*/
private class GestureListener extends GestureDetector.SimpleOnGestureListener {

  @Override
  public void onLongPress(MotionEvent e) {
     Point p = new Point();
     p.x =  (int) e.getX();
     p.y = (int) e.getY();
     //TODO translate p to canvas coordinates
  }
}

Thanks in advance! 提前致谢!

Edit: Does this have to do with screen size/resolution/depth and the canvas' Rect object? 编辑:这是否与屏幕尺寸/分辨率/深度和画布'Rect对象有关?

You might try using the MotionEvent.getRawX()/getRawY() methods instead of the getX()/getY() . 您可以尝试使用MotionEvent.getRawX()/getRawY()方法而不是getX()/getY()

// get the surfaceView's location on screen
int[] loc = new int[2];
surfaceView.getLocationOnScreen(loc);
// calculate delta
int left = e.getRawX()-loc[0];
int top = e.getRawY()-loc[1];

Well, you have the screen px from the display in x,y, and you can call the canvas px via: 好吧,你有x,y显示的屏幕px,你可以通过以下方式调用canvas px:

Canvas c = new Canvas();
int cx = c.getWidth();
int cy = c.getHeight();
...
Display display = getWindowManager().getDefaultDisplay(); 
int sx = display.getWidth();
int sy = display.getHeight();

Then, you can do the math to map the screen touch view , with the given px in both the view and the screen. 然后,您可以进行数学计算以在视图和屏幕中使用给定的px映射屏幕触摸视图。

canvasCoordX = p.x*((float)cx/(float)sx);
canvasCoordY = p.y*((float)cy/(float)sy);

See http://developer.android.com/reference/android/view/WindowManager.html for more info on the screen manager. 有关屏幕管理器的更多信息,请参阅http://developer.android.com/reference/android/view/WindowManager.html I think it needs to be initialized inside an activity to work. 我认为它需要在一个活动中初始化才能工作。

I recently came upon this problem while doing something very similiar and after some trial and error and lots of googling I ended up adapting this answer ( https://stackoverflow.com/a/9945896/1131180 ) : 我最近在做一些非常类似的事情时遇到了这个问题,经过一些试验和错误以及大量的谷歌搜索后我最终调整了这个答案( https://stackoverflow.com/a/9945896/1131180 ):

(e is a MotionEvent, so the best place to use this code would be in onTouch or onLongPress) (e是一个MotionEvent,因此使用此代码的最佳位置是onTouch或onLongPress)

mClickCoords = new float[2];

//e is the motionevent that contains the screen touch we
//want to translate into a canvas coordinate
mClickCoords[0] = e.getX();
mClickCoords[1] = e.getY();

Matrix matrix = new Matrix();
matrix.set(getMatrix());

//this is where you apply any translations/scaling/rotation etc.
//Typically you want to apply the same adjustments that you apply
//in your onDraw().

matrix.preTranslate(mVirtualX, mVirtualY);
matrix.preScale(mScaleFactor, mScaleFactor, mPivotX, mPivotY);

// invert the matrix, creating the mapping from screen 
//coordinates to canvas coordinates
matrix.invert(matrix); 

//apply the mapping
matrix.mapPoints(mClickCoords);

//mClickCoords[0] is the canvas x coordinate and
//mClickCoords[1] is the y coordinate.

There are some obvious optimizations that can be applied here but I think it is more clear this way. 有一些明显的优化可以在这里应用,但我认为这种方式更清晰。

If i understand correctly you have a canvas View inside surfaceview. 如果我理解正确你有一个画面查看里面的surfaceview。 If so try VIEW.getLeft() | getTop() 如果是这样,请尝试VIEW.getLeft() | getTop() VIEW.getLeft() | getTop() that returns the left | 返回左边的VIEW.getLeft() | getTop() | top position of the view relative to it's parent. 视图相对于其父级的顶部位置。

float x= e.getX() - canvasView.getLeft();
float y= e.getY() - canvasView.getTop();

如果你使用滚动,那么画布上的实际y是

float y = event.getY() + arg0.getScrollY();

What I do in these situations is just: 我在这些情况下所做的只是:

  1. put a listener on whatever View/ViewGroup whose coordinates you wanna get by click 将监听器放在任何View / ViewGroup上,通过单击获得其坐标
  2. Make it store them locally 让它在本地存储
  3. Whoever wants to access them should just request them via helper method. 谁想要访问它们应该只通过帮助方法请求它们。

And translation is done... 翻译完成了......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将归一化设备坐标转换为 Android 上 canvas 的像素坐标? - How to convert Normalized Device Coordinates to pixel coordinates for canvas on Android? Android:MotionEvent的x和y像素不会转换为图像坐标 - Android: MotionEvent's x and y pixel do not translate to image coordinates 如何在ImageView中在Android中将OnTouchEvent坐标转换/缩放到位图画布上 - How to translate/scale OnTouchEvent coordinates onto bitmap canvas in Android in ImageView 如何在画布上使用屏幕坐标进行绘制? - How do I draw with the screen coordinates on canvas? 如何将画布点转换为地图坐标 - How to translate Canvas Points to Map Coordinates 如何将像素位置(x和y坐标)从一个Android设备转换为其他Android设备? - How do I convert a pixel location (x and y coordinates) from one Android device to other Android devices? 给定一组向量(x / y坐标),我如何将其转换为PNG文件(android canvas缺陷)? - given a set of vectors (x/y coordinates ), how do i make that into a PNG file (android canvas deficiency)? 如何使MotionEvent的坐标与缩放画布的坐标相匹配? - How do I make the coordinates of MotionEvent match the ones of a scaled canvas? 如何在Android中计算缩放画布的坐标 - How to calculate coordinates of scaled canvas in Android 如何修复 Android 中缩放 canvas 的错误坐标 - how to fix the wrong coordinates of zoomed canvas in Android
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM