【问题标题】:Android Difficulty in placing points after focused canvas.scale operationAndroid 集中canvas.scale操作后放点困难
【发布时间】:2013-03-13 09:34:21
【问题描述】:

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

让我给你一点背景:

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

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

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

我想使用

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

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

【问题讨论】:

  • 仍在努力解决这个问题。

标签: android view bitmap scaling gesture


【解决方案1】:

我为此苦苦挣扎了一个多星期,尝试了各种解决方案,然后才发现虽然我不完全理解它;)但有工作的好处。您需要一个捏缩放(或其他)图像视图的工作实现,从中可以得出当前的比例和平移值。

我认为这个问题的难点在于有两个问题需要解决: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();
}

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-28
    • 2021-11-17
    • 2012-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多