android – How to convert coordinates of the image view to the coordinates of the bitmap?-ThrowExceptions

Exception or error:

In my app I need to let users to check the eyes at some photo.
In OnTouchListener.onTouch(…) I get the coordinates of the ImageView.

How can I convert this coordinates to the point at the bitmap that was touched?

How to solve:

Okay, so I’ve not tried this, but giving it a bit of thought, here’s what I’ve got as a suggestion:

ImageView imageView = (ImageView)findViewById(R.id.imageview);
Drawable drawable = imageView.getDrawable();
Rect imageBounds = drawable.getBounds();

//original height and width of the bitmap
int intrinsicHeight = drawable.getIntrinsicHeight();
int intrinsicWidth = drawable.getIntrinsicWidth();

//height and width of the visible (scaled) image
int scaledHeight = imageBounds.height();
int scaledWidth = imageBounds.width();

//Find the ratio of the original image to the scaled image
//Should normally be equal unless a disproportionate scaling
//(e.g. fitXY) is used.
float heightRatio = intrinsicHeight / scaledHeight;
float widthRatio = intrinsicWidth / scaledWidth;

//do whatever magic to get your touch point
//MotionEvent event;

//get the distance from the left and top of the image bounds
int scaledImageOffsetX = event.getX() - imageBounds.left;
int scaledImageOffsetY = event.getY() - imageBounds.top;

//scale these distances according to the ratio of your scaling
//For example, if the original image is 1.5x the size of the scaled
//image, and your offset is (10, 20), your original image offset
//values should be (15, 30). 
int originalImageOffsetX = scaledImageOffsetX * widthRatio;
int originalImageOffsetY = scaledImageOffsetY * heightRatio;

Give this idea a try and see if it works for you.

###

this works for me at least with API 10+:

final float[] getPointerCoords(ImageView view, MotionEvent e)
{
    final int index = e.getActionIndex();
    final float[] coords = new float[] { e.getX(index), e.getY(index) };
    Matrix matrix = new Matrix();
    view.getImageMatrix().invert(matrix);
    matrix.postTranslate(view.getScrollX(), view.getScrollY());
    matrix.mapPoints(coords);
    return coords;
}

###

besides considering the offset due to padding (margin is part of the layout, it’s space outside the view and doesn’t have to be considered), if the image is scaled you can get the image matrix (ImageView.getImageMatrix()) to scale coordinates.

EDIT:
You can get x/y scaling factor and translation amount getting the values array and using respective index constants:

float[] values;
matrix.getValues(values);

float xScale = values[Matrix.MSCALE_X];

note that translation doesn’t include padding, you still would have to consider that separately. translation is used for instance in FIT_CENTER scaling when there’s some “blank” space.

###

I’d say you probably need to offset the coordinates from the ImageView with any padding or margins in the layout to get the correct coordinates of the BitMap.

###

To add to kcoppock’s answer, I just want to add that:

//original height and width of the bitmap
int intrinsicHeight = drawable.getIntrinsicHeight();
int intrinsicWidth = drawable.getIntrinsicWidth();

may return an answer you’re not expecting. These values depend on the dpi of the drawable folder you load the image from. For instance, you might get a different value if you load the image from /drawable vs /drawable-hdpi vs /drawable-ldpi.

###

Get floor Width and height

float floorWidth = floorImage.getWidth();
float floorHeight = floorImage.getHeight();

Calculate protionate value

float proportionateWidth = bitmapWidth / floorWidth;
float proportionateHeight = bitmapHeight / floorHeight;

Your X & Y

float x = 315;
float y = 119;

Multiple with PropotionateValue

x = x * proportionateWidth;
y = y * proportionateHeight;

Leave a Reply

Your email address will not be published. Required fields are marked *