Search code examples
androideventscanvasimageviewtouch-event

onTouch event coordinates and imageview draw coordinates mismatch


I have:

                    imageView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            //Choose which motion action has been performed
            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    //Get X, Y coordinates from the ImageView
                    int X = (int) event.getX();


                    int Y = (int) event.getY();

and

                        BitmapFactory.Options myOptions = new BitmapFactory.Options();
                    myOptions.inDither = true;
                    myOptions.inScaled = false;
                    myOptions.inPreferredConfig = Bitmap.Config.ARGB_8888;// important
                    myOptions.inPurgeable = true;

                    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.lithuania,myOptions);
                    Paint paint = new Paint();
                    paint.setAntiAlias(true);
                    paint.setColor(Color.BLUE);


                    Bitmap workingBitmap = Bitmap.createBitmap(bitmap);
                    Bitmap mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true);


                    Canvas canvas = new Canvas(mutableBitmap);
                    canvas.drawCircle(40, 160, 15, paint);


                    imageView.setAdjustViewBounds(true);
                    imageView.setImageBitmap(mutableBitmap);

Any idea, how to make relation between those coordinates? Cause now my onTouch coordinates and drawing coordinates has to be different in order to represent it correctly to user.

Searched here, but seems no one have a correct answer. Any help will be appreciated :)

red one is my finger

EDIT

                    float xRatio = (float)bitmap.getWidth() / imageView.getWidth();
                    float xPos = event.getX() * xRatio;
                    float yPos = event.getY() * xRatio;

                    Canvas canvas = new Canvas(mutableBitmap);
                    canvas.drawCircle(xPos, yPos, 15, paint);

Working like a charm!


Solution

  • I have tested your code, the issue is that your bitmap has different dimensions then your imageView. You need to determine the difference in sizes and adjust accordingly. For example the image I used was 1800x1800 and my imageView was 900x900 so I had to multiple my X and Y coordinates by 2 to get the correct position

    int xRatio = bitmap.getWidth() / imageView.getWidth();
    int xPos = event.getX() * xRatio;
    

    Here is a more robust version which takes into account bitmaps that are smaller then the target view:

                int xRatio, yRatio;
                int xPos, yPos;
                if (mutableBitmap.getWidth() >= ib.getWidth()) {
                    xRatio = mutableBitmap.getWidth() / ib.getWidth();
                    xPos = (int) Math.floor(xRatio * event.getX());
                } else {
                    xRatio = ib.getWidth() / mutableBitmap.getWidth();
                    xPos = (int) Math.floor(xRatio*event.getX()-((ib.getWidth() - mutableBitmap.getWidth())/2));
                }
    
                if (mutableBitmap.getHeight() >= ib.getHeight()) {
                    yRatio = mutableBitmap.getHeight() / ib.getHeight();
                    yPos = (int)Math.floor(event.getY()*yRatio);
                } else {
                    yRatio = ib.getHeight() / mutableBitmap.getHeight();
                    yPos = (int) Math.floor(yRatio*event.getY()-((ib.getHeight() - mutableBitmap.getHeight())/2));
                }