Dans mon application, je dois laisser les utilisateurs vérifier les yeux sur une photo. Dans OnTouchListener.onTouch (...), je récupère les coordonnées du ImageView.
Comment puis-je convertir ces coordonnées au point sur le bitmap qui a été touché?
D'accord, je n'ai donc pas essayé cela, mais réfléchissons-y un peu, voici ce que j'ai suggéré:
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;
Essayez cette idée et voyez si cela fonctionne pour vous.
cela fonctionne pour moi au moins avec 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;
}
en plus de considérer le décalage dû au bourrage (la marge fait partie de la mise en page, c'est un espace en dehors de la vue et ne doit pas être prise en compte), si l'image est redimensionnée, vous pouvez obtenir que la matrice d'image (ImageView.getImageMatrix()
) redimensionne les coordonnées.
EDIT: Vous pouvez obtenir le facteur de mise à l'échelle x/y et le montant de la traduction en obtenant le tableau de valeurs et en utilisant les constantes d'index correspondantes:
float[] values;
matrix.getValues(values);
float xScale = values[Matrix.MSCALE_X];
notez que la traduction n'inclut pas le rembourrage, vous devrez quand même considérer cela séparément. la traduction est utilisée par exemple dans la mise à l'échelle FIT_CENTER lorsqu'il existe un espace "vide".
Je dirais que vous devez probablement décaler les coordonnées de ImageView avec des marges de remplissage ou des marges dans la présentation pour obtenir les coordonnées correctes de la carte bitmap.
Pour ajouter à la réponse de kcoppock, je veux juste ajouter que:
//original height and width of the bitmap
int intrinsicHeight = drawable.getIntrinsicHeight();
int intrinsicWidth = drawable.getIntrinsicWidth();
peut renvoyer une réponse à laquelle vous ne vous attendez pas. Ces valeurs dépendent du dpi du dossier pouvant être dessiné dans lequel vous chargez l'image. Par exemple, vous pourriez obtenir une valeur différente si vous chargez l'image depuis/drawable vs/drawable-hdpi vs/drawable-ldpi.
Obtenir la largeur et la hauteur du sol
float floorWidth = floorImage.getWidth();
float floorHeight = floorImage.getHeight();
Calculer la valeur du protionate
float proportionateWidth = bitmapWidth / floorWidth;
float proportionateHeight = bitmapHeight / floorHeight;
Votre X & Y
float x = 315;
float y = 119;
Multiple avec PropotionateValue
x = x * proportionateWidth;
y = y * proportionateHeight;