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?
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?
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.
xImageOffsetX
and yImageOffset
are not defined, by using them you mean scaledImageOffsetX
and scaledImageOffsetY
?thks in advance, and sorry for bothering you on an old question! ;) –
Telegenic ImageView
is put in correspondence with a pixel of the Bitmap
. But how does this solution take into consideration the fact that there may be more pixels than points of the ImageView
?Shouldn't the correspondence be one to many being there more pixels than points?I hope I made the question understandable, if not tell me (if you have time ;D) and I can try to explain myself better! And thks anyway! ;D –
Telegenic 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;
}
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.
xImageOffsetX
and yImageOffset
are not defined, by using them you mean scaledImageOffsetX
and scaledImageOffsetY
?thks in advance, and sorry for bothering you on an old question! ;) –
Telegenic ImageView
is put in correspondence with a pixel of the Bitmap
. But how does this solution take into consideration the fact that there may be more pixels than points of the ImageView
?Shouldn't the correspondence be one to many being there more pixels than points?I hope I made the question understandable, if not tell me (if you have time ;D) and I can try to explain myself better! And thks anyway! ;D –
Telegenic 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.
matrix.mapPoints()
converts the bitmap point to the ImageView's point. Currently I've set ImageViews scale type to "FitXY" and use something like this: xCoord = (xCoord / imagView.getWidth())*bitmap.getWidth();
–
Dilative 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;
As I came accross this question and tried it out myself, here is my solution. It seems to work with stretched and centered images.
class MyEditableImageView(context: Context, attrs: AttributeSet) :
androidx.appcompat.widget.AppCompatImageView(context, attrs) {
override fun onTouchEvent(event: MotionEvent): Boolean {
val image = drawable.toBitmap().copy(Bitmap.Config.ARGB_8888, true)
val xp = (event.x - imageMatrix.values()[Matrix.MTRANS_X]) / imageMatrix.values()[Matrix.MSCALE_X]
val yp = (event.y - imageMatrix.values()[Matrix.MTRANS_Y]) / imageMatrix.values()[Matrix.MSCALE_Y]
if (xp >= 0 && xp < image.width && yp >= 0 && yp < image.height) {
doSomethingOnImage(image, xp, yp)
setImageBitmap(image)
}
return super.onTouchEvent(event)
}
...
}
© 2022 - 2024 — McMap. All rights reserved.