ピクセルをdpに変換する


827

解像度がのPantechデバイス用にピクセル単位で指定された高さと幅でアプリケーションを作成しました480x800

G1デバイスの高さと幅を変換する必要があります。
それをdpに変換すると問題が解決し、両方のデバイスに同じ解決策が提供されると思いました。

ピクセルをdpに変換する簡単な方法はありますか?
助言がありますか?


1
(たとえば、Photoshopからスプライトをエクスポートするために)1回限りの変換を行う場合は、ここに気の利いたコンバータがあります。
Paul Lammertsma 2014


回答:


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

332
注:上記はDIPをピクセルに変換しています。元の質問は、ピクセルをディップに変換する方法を尋ねました!
Eurig Jones

12
ここでOPに本当の答えだ:stackoverflow.com/questions/6656540/...
QIX

119
それが質問に実際に答えないときに答えがいかに役立つかはおかしい-_-質問の質問が欲しいと思ったとき、私はそうではないことに気付きました!すばらしい答えです。質問があります。の最後のパラメータを取得するにはどうすればよいapplyDimensionですか?だけでもいいgetResource().getDisplayMetrics()ですか、それとも他に何かありますか?
2012

11
注:比較的高価な操作。より高速なアクセスのために値をキャッシュしてください
Entreco

8
Contextオブジェクトにアクセスできない場合Resources.getSystem().getDisplayMetrics()
Farshad Tahmasbi 2017年

871
/**
 * 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);
}

8
ほとんどのメソッドは整数値を期待するため、int Math.round(px)を返す価値があるかもしれません
Raj Labana

3
@MuhammadBabarこれは、160 dpi(mdpi)が他の密度が計算されるベースライン密度であるためです。たとえば、hdpiはmdpiの密度の1.5倍であると考えられています。これは、実際には240 dpiの別の言い方です。すべての密度については、以下のZsolt Safranyの回答を参照してください。
2015

19
@TomTasche:(Resource.getSystem()強調鉱山)のドキュメントから:「システムリソースのみ(アプリケーションリソースなし)へのアクセスを提供し、現在の画面に対して構成されていないディメンション単位を使用できない、変更されない)グローバル共有リソースオブジェクトを返すオリエンテーションなどに基づく)。」
Vicky Chijwani

2
開発者は、値を天井/床に選択できます。開発者に制御権を与えることをお勧めします。
Muhammad Nabeel Arif

7
私はdeveloper.android.com/reference/android/util/…のDisplayMetrics.DENSITY_DEFAULT代わりに160f
推奨

285

なるべく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;
}

5
これはすべてのデバイスで機能するわけではありません!この回答の結果とTypedValue.applyDimensionを使用した結果の結果は、OnePlus 3Tでは異なります(おそらく、OnePlusにはOSにカスタムスケーリングが組み込まれているためです)。TypedValue.applyDimensionを使用すると、デバイス間で一貫した動作が発生します。
Ben De La Haye

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

density 等しい

  • .75オンldpi120dpi)
  • 1.0オンmdpi160dpi;ベースライン)
  • 1.5オンhdpi240dpi)
  • 2.0オンxhdpi320dpi)
  • 3.0オンxxhdpi480dpi)
  • 4.0オンxxxhdpi640dpi)

このオンラインコンバーターを使用するをて、dpi値をいじってください。

編集:dpiバケットとの間に1対1の関係はないようdensityです。以下のように見えますNexus 5Xビーイングがxxhdpi持っているdensityの値2.625(の代わりに3)。Device Metricsをご覧ください。


3
「xxhdpiであるNexus 5Xの密度値は(3ではなく)2.6のようです」-技術的には、Nexus 5Xは420dpiで、Nexus 6 / 6Pは560dpiであり、どちらも標準のバケットの1つに直接着陸しません。 tvdpi(213dpi)を搭載したNexus 7。したがって、それらをxxdpiおよびxxxhdpiとしてリストしているサイトは茶番です。グラフは正しく、これらのデバイスは「特別な」dpiバケットに基づいて適切にスケーリングされます。
Steven Byle 2016

108

あなたはこれを使うことができます.. コンテキストなし

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

@Stanが述べたように、システムが密度を変更すると、このアプローチを使用すると問題が発生する可能性があります。そのことに注意してください!

個人的には、コンテキストを使用してそれを行っています。それは私があなたと共有したかったちょうど別のアプローチです


11
これは使いたくないかもしれません。getSystem()のドキュメント-「システムリソースのみ(アプリケーションリソースなし)へのアクセスを提供し、現在の画面用に構成されていない(寸法単位を使用できない、方向に基づいて変更されない)グローバル共有リソースオブジェクトを返す」
スタン

@Stanが言っていることを補足すると、これは危険であり、特にデバイスのフォームファクターが非常に複雑になってきている場合は、使用しないでください。
Saket

93

ディメンションXMLを使用できる場合、それは非常に簡単です。

あなたのres/values/dimens.xml

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

次に、Javaで:

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

pxからdpは画面密度に依存するため、OPがどのようにして120を取得したかは、すべての異なる画面サイズでpxからdpメソッドをテストしない限りわかりません。
John61590 2017

75

Android開発ガイドによると:

px = dp * (dpi / 160)

しかし、ピクセルで記述されたデザインを受け取ったときに、これを逆に実行したいことがよくあります。そう:

dp = px / (dpi / 160)

240dpiのデバイスを使用している場合、この比率は1.5(前述のとおり)であるため、60pxのアイコンはアプリケーションで40dpに相当します。



7
160は一定、ベッド回答
user25

2
@ user25いい答えですね。Android画面でドキュメントを読んでいないのですか?Androidの画面密度について話すとき、160はあらゆる場所で共通の定数です。ドキュメントからの引用:「中密度(mdpi)画面(〜160dpi)(これはベースライン密度です)」。さあ、男
mykolaj

70

Contextエレガントな静的メソッドなし:

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

24
Resources.getSystem()javadocは、「システムリソースのみ(アプリケーションリソースなし)へのアクセスを提供し、現在の画面に対して構成されていない(寸法単位を使用できない、方向に基づいて変更されないなど)グローバル共有リソースオブジェクトを返す」と述べています。これは、たとえそれが何らかの方法で機能したとしても、これを行うべきではないと言っています。
オースティンマホニー2014

私は@AustynMahoneyのコメントを読んだだけで、この答えは当初考えていたほど素晴らしいものではないことに気づきましたが、私は賛成投票を取り消すことができません!ああ!
Vicky Chijwani

45

ために DP to Pixel

に値を作成します dimens.xml

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

その値を次のpixelように取得します。

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

39

したがって、次の公式を使用して、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);
}

4
これはdpをピクセルに変換しますが、メソッドを呼び出しましたconvertToDp
Qwertie、2007

4
+ 0.5fはここで説明されています-> developer.android.com/guide/practices/…。最も近い整数に切り上げるために使用されます。

唯一の正しい答え。ソースdeveloper.android.com/guide/practices/…を
user25 '28

web.archive.org/web/20140808234241/http://developer.android.com/…問題のコンテンツがまだ含まれているリンクについて
caw

39

Kotlinを使用しているユーザー向け:

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

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

使用法:

64.toPx
32.toDp

Resource.getSystem()のドキュメントから:「システムリソースのみ(アプリケーションリソースなし)へのアクセスを提供し、現在の画面用に構成されていない(次元単位を使用できない、に基づいて変更されないグローバル共有リソースオブジェクトを返すオリエンテーションなど)。」
HendraWD 2018

@HendraWDドキュメントは紛らわしいかもしれません、それが言及している次元単位はアプリケーションレベルのdimensリソースです。displayMetricsはアプリケーションレベルのリソースではありません。これはシステムリソースであり、正しい値を返します。このコードは、すべてのProdアプリで正常に機能しています。問題はありませんでした。
ガンハン2018

33

Android SDKにはデフォルトのユーティリティがあります:http : //developer.android.com/reference/android/util/TypedValue.html

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

これを使用する必要があります。おまけとしてSPも行います。
マークルヌーフ2014年

2
resultPixint型である必要があります。int resultPix = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,1,getResources().getDisplayMetrics())
vovahost 2015

27

kotlin-extensionを使用すると、より良い

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

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

更新:

そのためのdisplayMetricsの一部であるグローバル共有リソース、我々は使用することができますResources.getSystem()

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

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

4
なぜそれをIntの拡張として追加するのですか?責任はInt型で何もする必要はありません。
htafoya

19

これにより、dpからピクセルへの変換が行われます。

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

これにより、dpへの変換ピクセルが得られます。

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

19

コトリン

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

ジャワ

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

12

おそらく値/ディメンション内にディメンションがある場合、おそらく最良の方法は、getDimension()メソッドから直接ディメンションを取得することです。これにより、ピクセル値に既に変換されたディメンションが返されます。

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

これをよりよく説明するために、

getDimension(int resourceId) 

既にピクセルに変換された寸法をFLOATとして返します。

getDimensionPixelSize(int resourceId)

同じを返しますが、intに切り捨てられるため、AS AN INTEGERになります。

参照してくださいAndroidの参照を


9
dpをピクセルに変換します。
public static int dp2px(Resources resource, int dp) {
    return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,   dp,resource.getDisplayMetrics());
}
ピクセルをdpに変換します。
  public static float px2dp(Resources resource, float px)  {
    return (float) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, px,resource.getDisplayMetrics());
}

ここで、resourceはcontext.getResources()です。


8
ピクセルをdpに変換していないため、答えは間違っています-ピクセルをピクセルに変換しています!
Yaroslav 2016年

px2dpが間違っている-同じ値をピクセル単位で返します。
natario 2018年

8

このような:

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

コンテキストに依存、浮動小数点値を返す、静的メソッド

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


8

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()

使用法:

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

ここで拡張機能の使用が大好きです。私はこの関数を「変換するfunction name」と読みますが、この場合は逆です。各関数の意図を明確にするために、関数の名前を更新して、それぞれdpToPxおよびpxToDpを読み取ることができます。
Maxwell

Resource.getSystem()のドキュメントから:「システムリソースのみ(アプリケーションリソースなし)へのアクセスを提供し、現在の画面用に構成されていない(次元単位を使用できない、に基づいて変更されないグローバル共有リソースオブジェクトを返すオリエンテーションなど)。」
HendraWD 2018

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

2
これは、この質問に対する他の多くの回答でカバーされているものと同じではありませんか?
TZHX

7

パフォーマンスが重要なアプリケーションを開発する場合は、次の最適化クラスを検討してください。

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

160fとは何ですか?なぜそれを使うのですか、なぜそれは160なのですか?
dephinera

160 => 160dpi。これは、数式のためにメジャーを変換するためのものです
xAqweRx

6

ピクセルをdpに変換するには、TypedValueを使用します

ドキュメントが言及したように:動的に型付けされたデータ値のコンテナ。

そしてapplyDimensionメソッドを使用します:

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

次のように、次元を保持するアンパックされた複素数データ値を最終的な浮動小数点値に変換します。

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

お役に立てれば幸いです。


6

これは私にとってそれがどのように機能するかです:

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

幅についても同じことができます。



4

ピクセルと同じようにdpを使用する必要があります。それだけです。独立したピクセルを表示します。中密度の画面と同じ数値を使用すると、高密度の画面でサイズが魔法のように正しくなります。

ただし、レイアウトデザインのfill_parentオプションが必要なようです。ビューまたはコントロールを親コンテナの残りのすべてのサイズに拡張する場合は、fill_parentを使用します。


実際に私の問題は、私のアプリケーションは、高密度の画面にコードされ、今では、低密度画面に変換する必要があります...
Indhu

中密度画面のピクセルを変更し(エミュレータで中密度画面を設定できます)、ピクセルをdpに置き換えます。ただし、fill_parentおよび複数のレイアウトを使用して、より柔軟なアプリケーションを作成できます。
Michael Lowman、2011年

最後に、すべてのpxを手動でdpに変更する以外に選択肢はありませんでした。:(
Indhu

1
少なくとも次回は最初にdpを使用し、何も変更する必要はありません:)ほとんどの場合、絶対的な配置を必要としないレイアウトを使用することは可能ですが。
Michael Lowman、2011年

それが私の最初のアプリだったので..私はこの間違いを犯しました...私は二度とそれをすることは決してないでしょう... :)
Indhu

4

PXDPは異なりますが似ています。

DP画面の物理サイズのみを考慮した場合の解像度です。使用DPすると、レイアウトが他の同様のサイズの画面に異なるサイズで拡大縮小されますpixel密度の。

pixelsただし、実際に必要な場合もありますが、コードでディメンションを処理するときはpixels、変換しない限り、常にrealを処理します。

Androidデバイスでは、通常のサイズのhdpi画面800x480 is 533x320DP(と思います)。に変換DPpixels /1.5、元に戻し*1.5ます。これは1画面サイズの場合のみで、dpiデザインによって異なります。私たちのアーティストは私に与えてくれpixelsます、そして私DPは上の1.5方程式で変換します。


3

Integer値が必要な場合は、Math.round()を使用すると、floatが最も近い整数に丸められます。

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

3

最良の答えは、Androidフレームワーク自体にあります。この等式を使用してください...

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

(dpをpxに変換)


2

これは私のために働きます(C#):

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

この質問への回答ではありませんが、C#の場合は機能します。ありがとう
Yekmer Simsek 16年

2

コトリン

   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;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.