web-dev-qa-db-fra.com

Conversion de pixels en dp

J'ai créé mon application avec la hauteur et la largeur en pixels pour un appareil Pantech dont la résolution est de 480x800.

J'ai besoin de convertir la hauteur et la largeur d'un appareil G1. Je pensais que le convertir en dp résoudrait le problème et fournirait la même solution pour les deux appareils. 

Y a-t-il un moyen facile de convertir des pixels en dp? Aucune suggestion?

722
Indhu
// Converts 14 dip into its equivalent px
float dip = 14f;
Resources r = getResources();
float px = TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_DIP,
    dip,
    r.getDisplayMetrics()
);
950
prasobh
/**
 * 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);
}
779

De préférence dans une classe Util.Java 

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;
}
273
Mike Keskinov
float density = context.getResources().getDisplayMetrics().density;
float px = someDpValue * density;
float dp = somePxValue / density;

density est égal à

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

Utilisez ce convertisseur online pour jouer avec les valeurs dpi.

EDIT: Il semble qu’il n’y ait aucune relation 1: 1 entre dpi bucket et density. Il semble que le Nexus 5X étant xxhdpi ait une valeur density de 2.625 (au lieu de 3). Voyez vous-même dans les métriques Device .

182
Zsolt Safrany

Si vous pouvez utiliser les dimensions XML, c'est très simple!

Dans votre res/values/dimens.xml:

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

Puis dans votre Java:

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

Selon le Guide de développement Android:

px = dp * (dpi / 160)

Mais souvent, vous voudrez le faire à l’inverse lorsque vous recevez un dessin libellé en pixels. Alors:

dp = px / (dpi / 160)

Si vous utilisez un périphérique de 240 dpi, ce rapport est égal à 1,5 (comme indiqué précédemment), ce qui signifie qu'une icône de 60 pixels correspond à 40 pixels dans l'application.

77
Ricardo Magalhães

Vous pouvez l'utiliser .. sans contexte

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

Comme @Stan l'a mentionné…, l'utilisation de cette approche peut poser problème si le système change de densité. Alors soyez conscient de ça!

Personnellement, j'utilise le contexte pour le faire.

71
Maher Abuthraa

Sans Context, méthodes statiques élégantes:

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);
}
65
Adam Stelmaszczyk

Pour DP to Pixel

Créer une valeur dans dimens.xml

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

Obtenez cette valeur dans pixel comme:

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

Vous pouvez donc utiliser le formulateur suivant pour calculer la bonne quantité de pixels à partir d’une dimension spécifiée dans 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);
}
38
neeraj t

Il existe une utilisation par défaut dans le SDK Android: http://developer.Android.com/reference/Android/util/TypedValue.html

float resultPix = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
33
Kvant

Pour ceux qui utilisent 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
32
Gunhan

Cela devrait vous donner la conversion dp en pixels:

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

Cela devrait vous donner les pixels de conversion en dp:

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

Probablement le meilleur moyen de placer la dimension dans values ​​/ dimen est d’obtenir la dimension directement à partir de la méthode getDimension (), elle vous renverra la dimension déjà convertie en pixel.

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

Juste pour mieux expliquer cela, 

getDimension(int resourceId) 

renverra la dimension déjà convertie en pixel AS A FLOAT.

getDimensionPixelSize(int resourceId)

retournera le même mais tronqué à int, donc AS AN INTEGER.

Voir Référence Android

12
Lorenzo Barbagli

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);
}
9
Khemraj
public static int dp2px(Resources resource, int dp) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,   dp,resource.getDisplayMetrics());
}
  public static float px2dp(Resources resource, float px)  {
    return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics());
}

où ressource est context.getResources ().

9
Prince Gupta

en utilisant kotlin-extension le rend meilleur

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:

Parce que displayMetrics fait partie de Ressources partagées globales , nous pouvons utiliser Resources.getSystem()

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

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

comme ça:

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

dépendant du contexte, retourne la valeur float, méthode statique

de: https://github.com/Trinea/Android-common/blob/master/src/cn/trinea/Android/common/util/ScreenUtils.Java#L15

8
Trinea

Si vous développez une application critique en termes de performances, veuillez considérer la classe optimisée suivante:

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;
    }
}
7
Pavel
float scaleValue = getContext().getResources().getDisplayMetrics().density;
int pixels = (int) (dps * scaleValue + 0.5f);
6
Sibin

Voici comment cela fonctionne pour moi:

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

Vous pouvez faire la même chose pour la largeur.

6
Temi Mide Adey

Approche plus élégante en utilisant la fonction d'extension de Kotlin

/**
 * 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}")
6
Saeed Masoumi

Vous devriez utiliser dp comme vous le feriez en pixels. C'est tout ce qu'ils sont; afficher des pixels indépendants. Utilisez les mêmes chiffres que sur un écran de densité moyenne et la taille sera magiquement correcte sur un écran de densité élevée.

Cependant, il semble que vous ayez besoin de l'option fill_parent dans votre schéma de configuration. Utilisez fill_parent lorsque vous souhaitez que votre vue ou votre contrôle se développe sur toute la taille restante du conteneur parent.

5
Michael Lowman

pour convertir des pixels en dp, utilisez TypedValue

Comme mentionné dans la documentation: Conteneur pour une valeur de données dynamiquement typée. 

et utilisez la méthode applyDimension

public static float applyDimension (int unit, float value, DisplayMetrics metrics) 

qui convertit une valeur de données complexe non compressée contenant une dimension en valeur finale en virgule flottante, comme suit: 

Resources resource = getResources();
float dp = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 69, resource.getDisplayMetrics());

J'espère que cela pourra aider .

5
user957654

Beaucoup de bonnes solutions ci-dessus. Cependant, la meilleure solution que j'ai trouvée est la conception de Google:

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

 Density

4
Kai Wang

PX et DP sont différents mais similaires.

DP est la résolution lorsque vous ne factorisez que la taille physique de l'écran. Lorsque vous utilisez DP, votre mise en page sera adaptée à des écrans de taille similaire avec des densités pixel différentes.

De temps en temps, vous voulez réellement pixels cependant, et lorsque vous manipulez des dimensions dans du code, vous avez toujours affaire à de vrais pixels, sauf si vous les convertissez.

Donc, sur un appareil Android, écran de taille normale hdpi, 800x480 is 533x320 à DP (je crois). Pour convertir DP en pixels /1.5, reconvertir *1.5. Ceci est uniquement pour la taille d'écran et dpi, cela changerait en fonction de la conception. Nos artistes me donnent pixels cependant et je me convertis en DP avec l'équation 1.5 ci-dessus.

4
HaMMeReD

Si vous voulez Integer values, alors, en utilisant Math.round () arrondira le flottant à l'entier le plus proche.

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

Cela fonctionne pour moi (C #):

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

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

Pour le code Java natif de React, il existe déjà une classe util:

import com.facebook.react.uimanager.PixelUtil;

float dp = PixelUtil.toDIPFromPixel(somePixelValue);
0
zubko

La meilleure réponse provient du framework Android lui-même: utilisez simplement cette égalité ...

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

(convertit dp en px)

0

Pour Xamarin.Android

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

Rendre ceci non statique est nécessaire lorsque vous créez un moteur de rendu personnalisé

0
mr5