web-dev-qa-db-fra.com

Comment convertir les coordonnées de la vue d'image en coordonnées du bitmap?

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é?

20
Alex

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.

31
kcoppock

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;
}

34
akonsu

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".

1
bigstones

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.

0
dbryson

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. 

0
AndyB

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;
0
Mohammad nabil