Converting Pixels to Dp
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...
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 the same solution for both devices.
Is there any easy way to convert pixels to dp?
Any suggestions?
35 Answers
Java code:
// Converts 14 dip into its equivalent px
float dip = 14f;
Resources r = getResources();
float px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dip,
r.getDisplayMetrics()
);
Kotlin code:
val dip = 14f
val r: Resources = resources
val px = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dip,
r.displayMetrics
)
Kotlin extension:
val Number.toPx get() = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
this.toFloat(),
Resources.getSystem().displayMetrics)
/**
* 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);
}
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;
}
float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;
density equals
.75onldpi(120dpi)1.0onmdpi(160dpi; baseline)1.5onhdpi(240dpi)2.0onxhdpi(320dpi)3.0onxxhdpi(480dpi)4.0onxxxhdpi(640dpi)
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.
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
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);
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.
Without Context, elegant static methods:
public static int dpToPx(int dp)
{
return (int) (dp * Resources.getSystem().getDisplayMetrics().density);
}
public static int pxToDp(int px)
{
return (int) (px / Resources.getSystem().getDisplayMetrics().density);
}
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()
val Float.toPx get() = this * Resources.getSystem().displayMetrics.density
val Float.toDp get() = this / Resources.getSystem().displayMetrics.density
val Int.toPx get() = (this * Resources.getSystem().displayMetrics.density).toInt()
val Int.toDp get() = (this / Resources.getSystem().displayMetrics.density).toInt()
PS: According to @EpicPandaForce's comment:
You should not be using Resources.getSystem() for this, because it does not handle foldables and Chrome OS devices.
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);
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
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);
}
There is a default util in android SDK:
float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
Must Read
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)
}