By Indhu


2011-01-05 15:04:27 8 Comments

I have created my application with the height and width given in pixels for a Pantech device whose resolution is 480x800.

I need to convert height and width for a G1 device. I thought converting it into dp will solve the problem and provide same solution for both devices.

Is there any easy way to convert pixels to dp? Any suggestions?

30 comments

@Alexander 2019-10-07 14:13:16

private fun toDP(context: Context,value: Int): Int {
    return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
        value.toFloat(),context.resources.displayMetrics).toInt()
}

@JarsOfJam-Scheduler 2019-08-08 09:01:38

The best answer comes from the Android framework itself: just use this equality...

public static int dpToPixels(final DisplayMetrics display_metrics, final float dps) {
    final float scale = display_metrics.density;
    return (int) (dps * scale + 0.5f);
}

(converts dp to px)

@Maher Abuthraa 2016-08-09 03:42:47

You can use this .. without Context

public static int pxToDp(int px) {
    return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}

public static int dpToPx(int dp) {
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

As @Stan mentioned .. using this approach may cause issue if system changes density. So be aware of that!

Personally I am using Context to do that. It's just another approach I wanted to share you with

@Stan 2017-02-16 10:09:49

You might not want to use this. Documentation for getSystem() - "Return a global shared Resources object that provides access to only system resources (no application resources), and is not configured for the current screen (can not use dimension units, does not change based on orientation, etc)."

@Saket 2019-08-05 17:50:09

Seconding what @Stan is saying: this is dangerous and you shouldn't be using it, especially now when device form factors are becoming so complex.

@beigirad 2019-03-03 12:04:26

using kotlin-extension makes it better

fun Int.toPx(context: Context): Int = (this * context.resources.displayMetrics.density).toInt()

fun Int.toDp(context: Context): Int = (this / context.resources.displayMetrics.density).toInt()

UPDATE:

Because of displayMetrics is part of global shared Resources, we can use Resources.getSystem()

fun Int.toPx(): Int = (this * Resources.getSystem().displayMetrics.density).toInt()

fun Int.toDp(): Int = (this / Resources.getSystem().displayMetrics.density).toInt()

@htafoya 2019-10-30 16:34:25

Why would you add it as an extension of Int, the responsibility doesn't have to do anything with the Int type.

@Khemraj 2018-09-21 13:35:21

Kotlin

fun convertDpToPixel(dp: Float, context: Context): Float {
    return dp * (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}

fun convertPixelsToDp(px: Float, context: Context): Float {
    return px / (context.resources.displayMetrics.densityDpi.toFloat() / DisplayMetrics.DENSITY_DEFAULT)
}

Java

public static float convertDpToPixel(float dp, Context context) {
    return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}

public static float convertPixelsToDp(float px, Context context) {
    return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}

@Muhammad Nabeel Arif 2012-03-05 08:09:39

/**
 * This method converts dp unit to equivalent pixels, depending on device density. 
 * 
 * @param dp A value in dp (density independent pixels) unit. Which we need to convert into pixels
 * @param context Context to get resources and device specific display metrics
 * @return A float value to represent px equivalent to dp depending on device density
 */
public static float convertDpToPixel(float dp, Context context){
    return dp * ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}

/**
 * This method converts device specific pixels to density independent pixels.
 * 
 * @param px A value in px (pixels) unit. Which we need to convert into db
 * @param context Context to get resources and device specific display metrics
 * @return A float value to represent dp equivalent to px value
 */
public static float convertPixelsToDp(float px, Context context){
    return px / ((float) context.getResources().getDisplayMetrics().densityDpi / DisplayMetrics.DENSITY_DEFAULT);
}

@Raj Labana 2015-07-07 10:23:15

Might be worth returning an int Math.round(px) as most methods expect an integer value

@Stephen 2015-08-02 02:52:15

@MuhammadBabar This is because 160 dpi (mdpi) is the baseline desity from which other densities are calculated. hdpi for instance is considered to be 1.5x the density of mdpi which is really just another way of saying 240 dpi. See Zsolt Safrany's answer below for all densities.

@Vicky Chijwani 2015-08-17 20:39:50

@TomTasche: From the docs for Resource.getSystem() (emphasis mine): "Return a global shared Resources object that provides access to only system resources (no application resources), and is not configured for the current screen (can not use dimension units, does not change based on orientation, etc)."

@Martin Pfeffer 2015-10-24 20:56:50

pixel returns float? I don't think there is "a half of a pixel"... :)

@Muhammad Nabeel Arif 2015-10-24 23:04:21

Developer have a choice to ceil/floor the value. It is better to give control to developer.

@milcaepsilon 2016-01-18 13:56:58

I would recommand DisplayMetrics.DENSITY_DEFAULT instead of 160f developer.android.com/reference/android/util/…

@Gokhan Arik 2016-03-02 20:11:40

This won't give the correct result. (metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT) will return an int. It needs to be cast to double or float.

@Livven 2016-04-05 10:22:21

@VickyChijwani Resources.getSystem().getDisplayMetrics().densityDpi still seems to work.

@Livven 2016-04-05 10:24:00

Instead of (float)metrics.densityDpi / DisplayMetrics.DENSITY_DEFAULT you could also just use metrics.density.

@Vicky Chijwani 2016-05-10 16:57:40

@Livven I know it works, but that's beside the point, which was that the implementation can change / stop working at any time because the documentation doesn't match what we expect.

@Livven 2016-05-11 09:55:05

@VickyChijwani Fair enough. I often find that when the documentation doesn't match the behavior it's because the documentation is outdated or simply not properly maintained, rather than the actual behavior being unintended. With some, maybe even most frameworks, relying only on the documentation would pretty much prevent you from getting any work done or even cause bugs.

@user25 2016-08-28 13:41:58

what is that??? I convert 3dp to px using it and I get 1564.5px??. it's better to use developer.android.com/guide/practices/…

@Gatunox 2016-09-25 20:39:44

HAHAHAAHAA. Pixels as a FLOAT , that's good... I am wondering, How can you paint 1,5 pixels, LOL

@Lorne Laliberte 2017-03-10 18:53:41

@Gatuox You can in fact paint fractions of pixels. Look up antialiasing techniques. You draw adjacent pixels at varying levels of alpha to approximate the fractions.

@Pants 2018-08-31 00:51:25

With App Widgets I get two different results when using context.getResources().getDisplayMetrics() and Resources.getSystem().getDisplayMetrics()

@younes 2018-10-04 09:28:16

kotlin

   fun spToPx(ctx: Context, sp: Float): Float {
    return sp * ctx.resources.displayMetrics.scaledDensity
}

fun pxToDp(context: Context, px: Float): Float {
    return px / context.resources.displayMetrics.density
}

fun dpToPx(context: Context, dp: Float): Float {
    return dp * context.resources.displayMetrics.density
}

java

   public static float spToPx(Context ctx,float sp){
    return sp * ctx.getResources().getDisplayMetrics().scaledDensity;
}

public static float pxToDp(final Context context, final float px) {
    return px / context.getResources().getDisplayMetrics().density;
}

public static float dpToPx(final Context context, final float dp) {
    return dp * context.getResources().getDisplayMetrics().density;
}

@mr5 2018-09-20 10:23:26

For Xamarin.Android

float DpToPixel(float dp)
{
    var resources = Context.Resources;
    var metrics = resources.DisplayMetrics;
    return dp * ((float)metrics.DensityDpi / (int)DisplayMetricsDensity.Default);
}

Making this a non-static is necessary when you're making a custom renderer

@Manthan Patel 2018-09-10 17:54:07

  ((MyviewHolder) holder).videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
                @Override
                public void onPrepared(final MediaPlayer mediaPlayer) {
                    mediaPlayer.setLooping(true);
                    ((MyviewHolder) holder).spinnerView.setVisibility(View.GONE);
                    mediaPlayer.setOnVideoSizeChangedListener(new MediaPlayer.OnVideoSizeChangedListener() {
                        @Override
                        public void onVideoSizeChanged(MediaPlayer mp, int width, int height) {
                /*
                 * add media controller
                 */
                            MediaController controller = new MediaController(mContext);
                            float density = mContext.getResources().getDisplayMetrics().density;
                            float px = 55 * density;
//                        float dp = somePxValue / density;
                            controller.setPadding(0, 0, 0, (int) (px));

                            ((MyviewHolder) holder).videoView.setMediaController(controller);


                        }
                    });
                }
            });

@prasobh 2011-06-13 05:56:57

// Converts 14 dip into its equivalent px
float dip = 14f;
Resources r = getResources();
float px = TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_DIP,
    dip,
    r.getDisplayMetrics()
);

@Eurig Jones 2012-03-13 16:34:17

Note: The above is converting DIPs to Pixels. The original question asked how to convert pixels to Dips!

@qix 2012-04-07 01:34:32

Here's a real answer to the OP: stackoverflow.com/questions/6656540/…

@Andy 2012-08-04 03:30:25

Its funny how the answer is more helpful when it doesn't really answer the question -_- I thought I wanted what the question asked then I realized I didn't! So great answer. I do have a question. How can I obtain the last paramter for applyDimension? Can I just do getResource().getDisplayMetrics(), or is there something else?

@Entreco 2014-12-04 12:15:38

NOTE: relatively expensive operation. Try to cache the values for quicker acces

@box 2015-12-17 09:34:28

This is not the right way to make conversion from px to dp. Check @Mike Keskinov's answer.

@DemonGyro 2016-01-05 16:30:41

I haven't tried it, but it's logically possible to convert from pixels to DP by using this code by doing the following: float pixelsPerDp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, r.getDisplayMetrics()); return dp / pixelsPerDp;

@Aksiom 2016-10-31 23:04:21

Please don't use this if you want to load a dp value from your dimens.xml, because the getResource().getDimension() already does that for you. If you want to directly round the base value and cast it to an int then use the getDimensionPixelSize() instead of getDimension().

@Farshad Tahmasbi 2017-06-23 03:15:38

If have no access to Context object use Resources.getSystem().getDisplayMetrics()

@Venki WAR 2018-05-02 06:02:02

This should give you the conversion dp to pixels:

public static int dpToPx(int dp)
{
    return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}

This should give you the conversion pixels to dp:

public static int pxToDp(int px)
{
    return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}

@Hitesh Sahu 2018-04-24 02:38:33

If you want Integer values then using Math.round() will round the float to the nearest integer.

public static int pxFromDp(final float dp) {
        return Math.round(dp * Resources.getSystem().getDisplayMetrics().density);
    }

@Son Nguyen 2016-01-06 09:05:20

To convert dp to px this code can be helpful :

public static int dpToPx(Context context, int dp) {
       final float scale = context.getResources().getDisplayMetrics().density;
       return (int) (dp * scale + 0.5f);
    }

@Alex 2013-10-16 01:39:53

If you can use the dimensions XML it's very simple!

In your res/values/dimens.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="thumbnail_height">120dp</dimen>
    ...
    ...
</resources>

Then in your Java:

getResources().getDimensionPixelSize(R.dimen.thumbnail_height);

@John61590 2017-07-21 20:35:11

Since px to dp depends on screen density, I don't know how the OP got 120 in the first place, unless he or she tested the px to dp method on all different screen sizes.

@Gunhan 2017-08-25 17:04:06

For anyone using Kotlin:

val Int.toPx: Int
    get() = (this * Resources.getSystem().displayMetrics.density).toInt()

val Int.toDp: Int
    get() = (this / Resources.getSystem().displayMetrics.density).toInt()

Usage:

64.toPx
32.toDp

@HendraWD 2018-09-05 15:35:34

From the docs for Resource.getSystem(): "Return a global shared Resources object that provides access to only system resources (no application resources), and is not configured for the current screen (can not use dimension units, does not change based on orientation, etc)."

@Gunhan 2018-09-05 15:58:05

@HendraWD The docs may be confusing, the dimension units it is mentioning is your application level dimens resources. displayMetrics is not an application level resource. It is a system resource and it returns the correct values. This code is working fine on all of my Prod apps. Never had an issue.

@Saeed Masoumi 2017-08-10 13:46:45

More elegant approach using kotlin's extension function

/**
 * Converts dp to pixel
 */
val Int.dpToPx: Int get() = (this * Resources.getSystem().displayMetrics.density).toInt()

/**
 * Converts pixel to dp
 */
val Int.pxToDp: Int get() = (this / Resources.getSystem().displayMetrics.density).toInt()

Usage:

println("16 dp in pixel: ${16.dpToPx}")
println("16 px in dp: ${16.pxToDp}")

@Slava 2017-08-16 10:17:31

16.px Actually, means, not 16 and not px, lol.

@Maxwell 2017-08-17 17:04:34

Love the use of extension here. I read the functions as "convert to function name" which I realize is backwards in this case. To clarify each function's intent, the names of the functions could be updated to read dpToPx and pxToDp, respectively.

@HendraWD 2018-09-05 15:35:43

From the docs for Resource.getSystem(): "Return a global shared Resources object that provides access to only system resources (no application resources), and is not configured for the current screen (can not use dimension units, does not change based on orientation, etc)."

@asadnwfp 2015-12-11 10:22:31

For DP to Pixel

Create a value in dimens.xml

<dimen name="textSize">20dp</dimen>

Get that value in pixel as:

int sizeInPixel = context.getResources().getDimensionPixelSize(R.dimen.textSize);

@HaMMeReD 2011-08-25 04:36:43

PX and DP are different but similar.

DP is the resolution when you only factor the physical size of the screen. When you use DP it will scale your layout to other similar sized screens with different pixel densities.

Occasionally you actually want pixels though, and when you deal with dimensions in code you are always dealing with real pixels, unless you convert them.

So on a android device, normal sized hdpi screen, 800x480 is 533x320 in DP (I believe). To convert DP into pixels /1.5, to convert back *1.5. This is only for the one screen size and dpi, it would change depending on design. Our artists give me pixels though and I convert to DP with the above 1.5 equation.

@Zsolt Safrany 2012-02-14 09:56:14

float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;

density equals

  • .75 on ldpi (120 dpi)
  • 1.0 on mdpi (160 dpi; baseline)
  • 1.5 on hdpi (240 dpi)
  • 2.0 on xhdpi (320 dpi)
  • 3.0 on xxhdpi (480 dpi)
  • 4.0 on xxxhdpi (640 dpi)

Use this online converter to play around with dpi values.

EDIT: It seems there is no 1:1 relationship between dpi bucket and density. It looks like the Nexus 5X being xxhdpi has a density value of 2.625 (instead of 3). See for yourself in the Device Metrics.

@Steven Byle 2016-09-22 16:50:13

"It looks like the Nexus 5X being xxhdpi has a density value of 2.6 (instead of 3)" - Technically the Nexus 5X is 420dpi and the Nexus 6/6P is 560dpi, neither land directly in one of the standard buckets, just like the Nexus 7 with tvdpi (213dpi). So the site listing those as xxdpi and xxxhdpi is a farce. Your chart IS correct, and those devices will properly scale based one their "special" dpi buckets.

@Pavel 2013-03-19 09:19:27

In case you developing a performance critical application, please consider the following optimized class:

public final class DimensionUtils {

    private static boolean isInitialised = false;
    private static float pixelsPerOneDp;

    // Suppress default constructor for noninstantiability.
    private DimensionUtils() {
        throw new AssertionError();
    }

    private static void initialise(View view) {
        pixelsPerOneDp = view.getResources().getDisplayMetrics().densityDpi / 160f;
        isInitialised = true;
    }

    public static float pxToDp(View view, float px) {
        if (!isInitialised) {
            initialise(view);
        }

        return px / pixelsPerOneDp;
    }

    public static float dpToPx(View view, float dp) {
        if (!isInitialised) {
            initialise(view);
        }

        return dp * pixelsPerOneDp;
    }
}

@Pavel 2014-04-06 11:42:46

It makes sence only if you do convertations really frequently. In my case I do.

@definera 2015-12-12 13:09:35

What is 160f? Why do you use it, why is it 160?

@xAqweRx 2016-01-21 09:05:40

160 => 160dpi and this is for converting measures because of formula

@Michael Zhang 2016-08-07 05:16:17

This workds for me (C#):

int pixels = (int)((dp) * Resources.System.DisplayMetrics.Density + 0.5f);

@Yekmer Simsek 2016-10-05 10:55:13

Not an answer to this question but for C# it works. Thanks

@Kai Wang 2016-07-21 20:39:14

A lot of great solutions above. However, the best solution I found is google's design:

https://design.google.com/devices/

Density

@Prince Gupta 2016-05-13 11:06:06

To convert dp to pixel.

public static int dp2px(Resources resource, int dp) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,   dp,resource.getDisplayMetrics());
}
To convert pixel to dp.
  public static float px2dp(Resources resource, float px)  {
    return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics());
}

where resource is context.getResources().

@Yaroslav 2016-06-27 15:03:06

The answer is wrong, because you are not converting pixels to dp - you are converting pixels to pixels!

@natario 2018-10-16 06:22:48

The px2dp is wrong - will return the same value in pixels.

@Temi Mide Adey 2013-07-02 14:20:25

This is how it works for me:

DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
int  h = displaymetrics.heightPixels;
float  d = displaymetrics.density;
int heightInPixels=(int) (h/d);

You can do the same for the width.

@Sibin 2015-04-22 06:45:17

float scaleValue = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scaleValue + 0.5f);

@TZHX 2015-04-22 08:56:23

Is this not just the same as what's covered in many of the other answers to this question?

@Mike Keskinov 2012-08-27 18:34:02

Preferably put in a Util.java class

public static float dpFromPx(final Context context, final float px) {
    return px / context.getResources().getDisplayMetrics().density;
}

public static float pxFromDp(final Context context, final float dp) {
    return dp * context.getResources().getDisplayMetrics().density;
}

@Ben De La Haye 2018-08-20 07:52:48

This does not work on all devices! The result of this answer vs that of using TypedValue.applyDimension is not the same on a OnePlus 3T (probably because OnePlus have custom scaling built into the OS). Using TypedValue.applyDimension causes consistent behavior across devices.

@Lorenzo Barbagli 2014-10-31 14:37:52

Probably the best way if you have the dimension inside values/dimen is to get the dimension directly from getDimension() method, it will return you the dimension already converted into pixel value.

context.getResources().getDimension(R.dimen.my_dimension)

Just to better explain this,

getDimension(int resourceId) 

will return the dimension already converted to pixel AS A FLOAT.

getDimensionPixelSize(int resourceId)

will return the same but truncated to int, so AS AN INTEGER.

See Android reference

@neeraj t 2012-03-28 09:39:12

You can therefore use the following formulator to calculate the right amount of pixels from a dimension specified in dp

public int convertToPx(int dp) {
    // Get the screen's density scale
    final float scale = getResources().getDisplayMetrics().density;
    // Convert the dps to pixels, based on density scale
    return (int) (dp * scale + 0.5f);
}

@Qwertie 2012-07-03 22:33:17

This converts dp to pixels but you called your method convertToDp.

@Christopher Francisco 2014-05-14 13:12:58

why the +0.5f ?

@Bae 2014-08-05 09:29:46

+0.5f is explain here --> developer.android.com/guide/practices/… . It's used to round up to the nearest integer.

@user25 2016-08-28 13:41:02

the only right answer. you could add the source developer.android.com/guide/practices/…

@caw 2019-06-28 00:53:19

web.archive.org/web/20140808234241/http://developer.android.‌​com/… for a link that still has the content in question

@Ricardo Magalhães 2011-12-05 19:00:36

According to the Android Development Guide:

px = dp * (dpi / 160)

But often you'll want do perform this the other way around when you receive a design that's stated in pixels. So:

dp = px / (dpi / 160)

If you're on a 240dpi device this ratio is 1.5 (like stated before), so this means that a 60px icon equals 40dp in the application.

@Sachchidanand 2012-07-11 10:58:17

@user25 2016-08-28 13:15:17

160 is constant, bed answer

@mykolaj 2018-08-14 11:50:38

@user25 Great answer actually. Haven't you read any docs on android screens? 160 is a common constant all over the place when talking about android screen densities. Quote from docs: "medium-density (mdpi) screens (~160dpi). (This is the baseline density)". Come on, man

@Trinea 2014-02-14 08:43:56

like this:

public class ScreenUtils {

    public static float dpToPx(Context context, float dp) {
        if (context == null) {
            return -1;
        }
        return dp * context.getResources().getDisplayMetrics().density;
    }

    public static float pxToDp(Context context, float px) {
        if (context == null) {
            return -1;
        }
        return px / context.getResources().getDisplayMetrics().density;
    }
}

dependent on Context, return float value, static method

from: https://github.com/Trinea/android-common/blob/master/src/cn/trinea/android/common/util/ScreenUtils.java#L15

Related Questions

Sponsored Content

39 Answered Questions

[SOLVED] How to get screen dimensions as pixels in Android

26 Answered Questions

9 Answered Questions

18 Answered Questions

[SOLVED] Can the Android Layout folder contain subfolders?

6 Answered Questions

14 Answered Questions

[SOLVED] Ship an application with a database

6 Answered Questions

[SOLVED] Android: Background Image Size (in Pixel) which Support All Devices

  • 2012-10-23 05:51:23
  • Ahmed Nawaz
  • 162081 View
  • 101 Score
  • 6 Answer
  • Tags:   android graphics

1 Answered Questions

[SOLVED] Why does a higher pixel density device have less screen real estate? (Eclipse AVD)

1 Answered Questions

[SOLVED] Resolution from Size and pixels of an image

3 Answered Questions

[SOLVED] Android, images and dpi

Sponsored Content