gpt4 book ai didi

Android 聚焦canvas.scale 操作后难以放置点

转载 作者:行者123 更新时间:2023-12-05 00:07:31 24 4
gpt4 key购买 nike

这是我关于 stackoverflow 的第一个问题,所以请放轻松。

让我给你一些背景知识:

我创建了一个应用程序来处理 View 中的位图(本例中的图像是设施的 map ),我使用位图上点的实际 x 和 y 坐标在 map 上放置点。我跟踪位图左上角相对于屏幕左上角的偏移量,方法是根据手势对图像位置所做的更改修改此偏移量值。这实际上非常适合平移,这使我可以轻松地将屏幕坐标(从长按手势)转换为位图上的实际坐标。有了这个,我在 map 上画了一个圆圈,并允许用户创建一个我推送到数据库的“兴趣点”。

问题出现在处理缩放的时候。我正在用一个简单的
缩放 canvas.scale(scalefastor,scalefactor);在绘制中。使用此缩放时,实际缩放比例是相对于图像的左上角进行的,因此捏合缩放并不直观,因为您尝试放大的实际位置很快就会跑到屏幕外。然而,以这种方式缩放图像不会影响图像的实际偏移,因此我的点放置仍然准确。我使用以下简单的数学来完成这个:

bitmapXCoordinate = (event.getX() - xOffset) /scaleFactor;

我想用

canvas.scale(scalefactor, scalefactor, gestureFocusX, gestureFocusY);

为了使缩放对用户直观,但这对位图的实际矩阵进行了转换,因此我的点放置不再起作用。似乎位图上的点现在以某种方式相对于比例尺的焦点,并且所有放置的点都关闭并趋向于该焦点。我知道我需要考虑矩阵上的这种转换才能正确放置我的点,但显然,这需要比我更聪明的人。解决方案可能很简单,但我已经为此工作了好几天试图解释这个新的抵消,但我无法取得任何真正的进展。对此解决方案的任何见解都将不胜感激。

最佳答案

我为此苦苦挣扎了一个多星期,尝试了各种解决方案,然后我发现了一些东西,虽然我不完全理解它 ;),但对工作有好处。您将需要一个双指缩放(或其他) ImageView 的有效实现,您可以从中获取当前的缩放和平移值。

我认为这个问题的困难在于有两个问题需要解决:1,解码对可能缩放和平移的图像的点击,以及 2,渲染存储的点击位置。

无论如何,到代码。注册触摸:

private Float[] getNormalizedTouchLocation(MotionEvent event) {
float xpos = getOffsetX();
float ypos = getOffsetY();
float scale = getScaleFactor();

Drawable drawable = getDrawable();
Rect image_bounds = drawable.getBounds();

Matrix matrix = new Matrix(getImageMatrix());

matrix.postScale(scale, scale, mPivotX, mPivotY);
matrix.postTranslate(xpos, ypos);

RectF image_rect = new RectF(image_bounds);

matrix.mapRect(image_rect);

float x = ((event.getX() - image_rect.left) / scale);
float y = ((event.getY() - image_rect.top) / scale);

return new Float[]{x, y};
}

然后渲染:

public void onDraw(Canvas canvas) {
// Ensure parent leaves the canvas *unscaled* and *untranslated*.
super.onDraw(canvas);

float xpos = getOffsetX();
float ypos = getOffsetY();
float scale = getScaleFactor();

canvas.save();

Matrix matrix = canvas.getMatrix();
matrix.postScale(scale, scale, mPivotX, mPivotY);
matrix.postTranslate(xpos, ypos);

Drawable drawable = getDrawable();
Rect image_bounds = drawable.getBounds();

RectF image_rect = new RectF(image_bounds);

Matrix image_matrix = new Matrix(getImageMatrix());
image_matrix.postScale(scale, scale, mPivotX, mPivotY);
image_matrix.postTranslate(xpos, ypos);

image_matrix.mapRect(image_rect);

// mPoints is a list of float[2] coordinates.
for (Float[] coord: mPoints) {

// Draw a bitmap centered on each touch position.
float x = (scale * coord[0] + image_rect.left) - mBitmap.getWidth() / 2;
float y = (scale * coord[1] + image_rect.top) - mBitmap.getHeight() / 2;

canvas.drawBitmap(mBitmap, x, y, mPaint);
}

canvas.restore();
}

希望这对你有用!显然,这里的解决方案只能正确渲染以相同屏幕分辨率等在相同渲染尺寸图像上注册的点 - 它可能会被修改为存储图像宽度/高度的分数,以用于跨图像/分辨率工作的解决方案。

关于Android 聚焦canvas.scale 操作后难以放置点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15381482/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com