3

これは、stackoverflow に関する初めての質問ですので、お手柔らかにお願いします。

背景を少し説明しましょう。

ビュー内でビットマップを操作するアプリケーション (この場合の画像は施設のマップ) を作成し、ビットマップ上のポイントの実際の x 座標と y 座標を使用してマップ上にポイントを配置しました。ジェスチャによる画像配置の変更に基づいてこのオフセット値を変更することにより、画面の左上隅に対するビットマップの左上隅のオフセットを追跡します。これは実際にパン操作に非常にうまく機能しており、(長押しジェスチャからの) 画面座標をビットマップ上の実際の座標に簡単に変換できます。これにより、マップ上に円を描画し、ユーザーがデータベースにプッシュする「関心のあるポイント」を作成できるようにします。

ズームを扱うときに問題が発生します。
canvas.scale(scalefastor ,scalefactor); onDrawでシンプルにズームしています。このズームでは、実際のスケーリングは画像の左上隅に相対的であるため、ズームインしようとしている実際の場所が画面外にすばやく移動するため、ズームするピンチは直感的ではありません. ただし、この方法で画像をスケーリングしても、画像の実際のオフセットには影響しないため、ポイントの配置は依然として正確です。これを達成するために、次の簡単な計算を使用します。

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

使いたい

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

ズームをユーザーにとって直感的に保つために、これはビットマップの実際のマトリックスを変換するため、ポイントの配置は機能しなくなります。ビットマップ上のポイントは、何らかの形でスケールの焦点に相対的であり、配置されたすべてのポイントがずれており、この焦点に向かっているようです。ポイントを正しく配置するには、マトリックス上でこの変換を考慮する必要があることは承知していますが、明らかに、それには私よりも知的な個人が必要です。解決策はおそらく簡単ですが、私はこれに何日も取り組んできましたこの新しいオフセットを説明しようとしていますが、実際の進歩はありません。これに対する解決策についての洞察は大歓迎です。

4

1 に答える 1

0

私はこれに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();
}

これがうまくいくことを願っています!明らかに、ここでのソリューションは、同じ画面解像度などで同じレンダリング サイズの画像に登録されたポイントのみを正しくレンダリングします。おそらく、画像/解像度全体で機能するソリューションのために、画像の幅/高さの分数を保存するように修正できます。

于 2013-05-05T00:40:01.163 に答える