簡體   English   中英

如何在ImageView中在Android中將OnTouchEvent坐標轉換/縮放到位圖畫布上

[英]How to translate/scale OnTouchEvent coordinates onto bitmap canvas in Android in ImageView

我正在嘗試將OnTouchListener設置為要執行大量自定義繪圖的ImageView。 問題:我的X值不可用,並且我不斷地將觸摸記錄在左邊。 Y值還可以,所以我算法的問題在哪里?

我正在使用的畫布是400像素寬和300像素高。 我沒有對ImageView進行任何特殊縮放,我只是依賴於標准ImageView行為,它將根據自身行為進行縮放以適合屏幕。 用戶觸摸屏幕的地方應該會出現小綠點,但它們在Nexus 5上的位置離左側太遠了。我的數學對Y值正確但對X值錯誤嗎? 我同時要求x比例尺和y比例尺,因此即使ImageView更改了寬高比,我也應該考慮這一點,對嗎?

public class FullscreenActivity extends AppCompatActivity {

    private ImageView drawingImageView;
    private Canvas canvas;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        int mUIFlag = View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_LOW_PROFILE
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
        getWindow().getDecorView().setSystemUiVisibility(mUIFlag);
        setContentView(R.layout.activity_fullscreen);

        drawingImageView = (ImageView) this.findViewById(R.id.game_map_fixed_id);
        Bitmap bitmap = Bitmap.createBitmap(Map.width, Map.height, Bitmap.Config.ARGB_8888);
        canvas = new Canvas(bitmap);
        drawingImageView.setImageBitmap(bitmap);
        drawingImageView.setOnTouchListener(mapOnTouchListener);
    }

    View.OnTouchListener mapOnTouchListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            float[] bounds = new float[6];
            bounds = getBitmapPositionInsideImageView(drawingImageView);

            float x = event.getX() / bounds[4] - bounds[0];
            float y = event.getY() / bounds[5] - bounds[1];

            Paint paint = new Paint();
            paint.setStyle(Paint.Style.FILL_AND_STROKE);
            paint.setColor(Color.GREEN);
            canvas.drawCircle(x, y, 1, paint);
            return false;
        }
    };

    public static float[] getBitmapPositionInsideImageView(ImageView imageView) {
        float[] rect = new float[6];

        if (imageView == null || imageView.getDrawable() == null)
            return rect;

        // Get image dimensions
        // Get image matrix values and place them in an array
        float[] f = new float[9];
        imageView.getImageMatrix().getValues(f);

        // Extract the scale values using the constants (if aspect ratio maintained, scaleX == scaleY)
        final float scaleX = f[Matrix.MSCALE_X];
        final float scaleY = f[Matrix.MSCALE_Y];

        rect[4] = scaleX;
        rect[5] = scaleY;

        // Get the drawable (could also get the bitmap behind the drawable and getWidth/getHeight)
        final Drawable d = imageView.getDrawable();
        final int origW = d.getIntrinsicWidth();
        final int origH = d.getIntrinsicHeight();

        // Calculate the actual dimensions
        final int actW = Math.round(origW * scaleX);
        final int actH = Math.round(origH * scaleY);

        rect[2] = actW;
        rect[3] = actH;

        // Get image position
        // We assume that the image is centered into ImageView
        int imgViewW = imageView.getWidth();
        int imgViewH = imageView.getHeight();

        float left = (imgViewW - actW)/2;
        float top = (imgViewH - actH)/2;

        rect[0] = left;
        rect[1] = top;

        return rect;
    }
}

錯誤在於從getBitmapPositionInsideImageView接收信息后計算點數。

        float x = event.getX() / bounds[4] - bounds[0];
        float y = event.getY() / bounds[5] - bounds[1];

應該

        float x = (event.getX() - bounds[0]) / bounds[4];
        float y = (event.getY() - bounds[1]) / bounds[5];

我在垂直軸上沒有任何問題的原因是因為圖像的頂部或底部沒有填充,這意味着bounds [5]始終為零,從而將誤差隱藏在該方程式中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM