5

I have an image of a face (250px X 250px) that is in an absolute layout element. I currently get the user's touch coordinates and using some maths calculate what has been touched (eg the nose), then do something accordingly.

My question is how to scale this to fit the screen width available. If I set the image (in the xml) to fill_parent, the coordinates are way out. Can this be remedied by converting the touch coordinates to dips (if so, how), or will I need to get the screen width (again convert into dips) and sort out the coordinate problem using more maths?

Any and all help appreciated.

Rooneyl
  • 7,802
  • 6
  • 52
  • 81

4 Answers4

12

I have three useful functions in my library...

get Screen Density

public static float getDensity(Context context){
    float scale = context.getResources().getDisplayMetrics().density;       
    return scale;
}

convert Dip to Pixels.

public static int convertDiptoPix(int dip){
    float scale = getDensity();
    return (int) (dip * scale + 0.5f);
}

convert Pixels to Dips.

public static int convertPixtoDip(int pixel){
    float scale = getDensity();
    return (int)((pixel - 0.5f)/scale);
}
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
12

pixels = dps * (density / 160)

The (density / 160) factor is known as the density scale factor, and get be retrieved in Java from the Display Metrics object. What you should do is store the position of the nose etc in terms of dips (which are the same as pixels on a screen with density 160), and then convert dips to pixels depending on what screen you are running on:

final static int NOSE_POSITION_DP = 10;
final float scale = getContext().getResources().getDisplayMetrics().density;
final int nosePositionPixels = (int) (NOSE_POSITION_DP * scale + 0.5f);
Joseph Earl
  • 23,351
  • 11
  • 76
  • 89
  • extra question: if the nose is at 125,125 (based on 250px image), if I set the image as fill_parent and it scales to the screen width (say 480px) how would I go about setting the nose position in dips, as the original 125,125 would now be the left eye for example? – Rooneyl Apr 08 '11 at 07:44
  • try using dip instead in xml by setting height and width to 250dip of the image. – Abhi Apr 08 '11 at 07:46
  • In this case you'd have to introduce an extra scale factor to account for the fact the image doesn't just scale linearly with density (it also scales with screen-size in this case). In this case you could just use `nosePositionPixelsX = NOSE_POSITION_DP * (imageWidthInPixels/250)` – Joseph Earl Apr 08 '11 at 07:50
  • 4
    In `(NOSE_POSITION_DP * scale + 0.5f)`, is the 0.5f just a way to round up to next integer? – Thunder Rabbit Jun 21 '11 at 01:56
6

A very simple way of doing this.

int value = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 250, (mContext).getResources().getDisplayMetrics());
Ali Imran
  • 8,927
  • 3
  • 39
  • 50
5
public int getDip(int pixel)
{
        float scale = getBaseContext().getResources().getDisplayMetrics().density;
        return (int) (pixel * scale + 0.5f);
 }
Vinothkumar Arputharaj
  • 4,567
  • 4
  • 29
  • 36