code

픽셀을 dp로 변환

codestyles 2020. 9. 29. 07:50
반응형

픽셀을 dp로 변환


해상도가 480x800 인 팬택 장치의 높이와 너비를 픽셀 단위로 지정한 응용 프로그램을 만들었습니다.

G1 장치의 높이와 너비를 변환해야합니다. 나는 그것을 dp로 변환하면 문제가 해결되고 두 장치에 대해 동일한 솔루션을 제공 할 것이라고 생각했습니다.

픽셀을 dp로 변환하는 쉬운 방법이 있습니까? 어떤 제안?


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

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

가급적 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;
}

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

density 같음

  • .75켜짐 ldpi( 120dpi)
  • 1.0켜기 mdpi( 160dpi, 기준선)
  • 1.5켜짐 hdpi( 240dpi)
  • 2.0켜짐 xhdpi( 320dpi)
  • 3.0켜짐 xxhdpi( 480dpi)
  • 4.0켜짐 xxxhdpi( 640dpi)

온라인 변환기사용 하여 dpi 값을 가지고 놀 수 있습니다.

편집 : dpi버킷과 density. 등이 보이는 Nexus 5X존재가 xxhdpidensity2.625(대신을 3). 장치 메트릭 에서 직접 확인하십시오 .


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

이 .. 컨텍스트없이 사용할 수 있습니다.

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이 언급했듯이 ..이 접근 방식을 사용하면 시스템이 밀도를 변경하면 문제가 발생할 수 있습니다. 그러니 알아 두세요!

개인적으로 나는 그것을하기 위해 Context를 사용하고있다. 여러분과 공유하고 싶은 또 다른 접근 방식입니다.


Android 개발 가이드에 따르면 :

px = dp * (dpi / 160)

그러나 종종 픽셀로 표시된 디자인을받을 때 다른 방식으로 수행하고 싶을 것입니다. 그래서:

dp = px / (dpi / 160)

240dpi 장치를 사용하는 경우이 비율은 1.5 (앞서 언급 한 것과 같음)이므로 응용 프로그램에서 60px 아이콘이 40dp와 같습니다.


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

에 대한 DP to Pixel

값 생성 dimens.xml

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

해당 값을 다음 pixel과 같이 가져 옵니다 .

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

따라서 다음 공식을 사용하여 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);
}

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

Android SDK에는 기본 유틸리티가 있습니다. http://developer.android.com/reference/android/util/TypedValue.html

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

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

이것은 당신에게 픽셀로의 변환 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);
}

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

자바

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

아마도 값 / 차원 안에 차원이있는 경우 가장 좋은 방법은 getDimension () 메서드에서 직접 차원을 가져 오는 것입니다. 이미 픽셀 값으로 변환 된 차원을 반환합니다.

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

더 잘 설명하기 위해

getDimension(int resourceId) 

이미 픽셀로 변환 된 치수를 AS A FLOAT로 반환합니다.

getDimensionPixelSize(int resourceId)

동일하지만 int로 잘 리므로 INTEGER로 반환됩니다.

Android 참조 보기


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

여기서 리소스는 context.getResources ()입니다.


이렇게 :

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

컨텍스트에 따라, float 값 반환, 정적 메서드

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


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

성능이 중요한 애플리케이션을 개발하는 경우 다음 최적화 된 클래스를 고려하십시오.

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

to convert Pixels to dp use the TypedValue .

As the documentation mentioned : Container for a dynamically typed data value .

and use the applyDimension method :

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

which Converts an unpacked complex data value holding a dimension to its final floating point value like the following :

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

Hope that Helps .


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

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.


You should use dp just as you would pixels. That's all they are; display independent pixels. Use the same numbers you would on a medium density screen, and the size will be magically correct on a high density screen.

However, it sounds like what you need is the fill_parent option in your layout design. Use fill_parent when you want your view or control to expand to all the remaining size in the parent container.


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

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

밀도


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.

안드로이드 장치, 보통 크기에 따라서 hdpi화면 800x480 is 533x320DP(나는 믿는다). 변환하려면 DPpixels /1.5다시 변환 할 *1.5. 이것은 한 화면 크기에만 해당 dpi되며 디자인에 따라 변경 될 수 있습니다. 우리의 아티스트들은 저에게 주었고 pixels저는 DP위의 1.5방정식으로 변환합니다 .


이것은 나를 위해 일했습니다 (C #).

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

정수 값을 원하면 Math.round ()를 사용하면 부동 소수점을 가장 가까운 정수로 반올림합니다.

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

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
}

자바

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

Xamarin.Android의 경우

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

커스텀 렌더러를 만들 때 이것을 비 정적으로 만드는 것이 필요합니다.

참고 URL : https://stackoverflow.com/questions/4605527/converting-pixels-to-dp

반응형