programing

픽셀을 dp로 변환

telebox 2023. 6. 1. 22:41
반응형

픽셀을 dp로 변환

저는 해상도가 다음과 같은 팬택 기기에 대해 픽셀 단위의 높이와 너비로 애플리케이션을 만들었습니다.480x800.

나는 G1 기기의 높이와 너비를 변환해야 합니다.
저는 dp로 변환하면 문제가 해결되고 두 기기 모두 동일한 솔루션을 제공할 수 있다고 생각했습니다.

픽셀을 dp로 쉽게 변환할 수 있는 방법이 있습니까?
좋은 의견이라도 있나?

Java 코드:

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

코틀린 코드:

 val dip = 14f
 val r: Resources = resources
 val px = TypedValue.applyDimension(
     TypedValue.COMPLEX_UNIT_DIP,
     dip,
     r.displayMetrics
 )

코틀린 확장:

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

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

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

온라인 변환기를 사용하여 dpi 값을 재생합니다.

편집: 사이에 1:1 관계가 없는 것 같습니다.dpi와 양동이density은 보기에은처럼 .Nexus 5Xxxhdpi을 가지고 있습니다.density의 값2.625)로 표시됨)3). 장치 메트릭에서 직접 확인하십시오.

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

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

개인적으로 저는 그것을 하기 위해 컨텍스트를 사용하고 있습니다.다른 접근법을 소개해 드리려고 합니다

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

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

코틀린을 사용하면 더 좋아집니다.

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

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: @EpicPandaForce의 논평에 따르면:

리소스를 사용하면 안 됩니다.접이식 및 Chrome OS 장치를 처리하지 않으므로 getSystem()을 사용합니다.

위해서DP to Pixel

값생위에서 합니다.dimens.xml

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

가오기에서 .pixel다음과 같이:

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

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

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

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

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

코틀린

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

이렇게 하면 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);
}

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

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

더 잘 설명하자면,

getDimension(int resourceId) 

이미 픽셀로 변환된 치수를 플로트로 반환합니다.

getDimensionPixelSize(int resourceId)

동일하지만 잘린 int를 정수로 반환합니다.

Android 참조

다음과 같이:

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

코틀린:

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

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

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

입력된 값을 사용하여 픽셀을 dp로 변환합니다.

문서에서 언급했듯이 동적으로 입력된 데이터 값을 위한 컨테이너입니다.

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

도움이 되길 바랍니다.

다음과 같은 방식으로 작동합니다.

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

너비에 대해서도 동일하게 할 수 있습니다.

위의 많은 훌륭한 해결책.하지만 제가 찾은 가장 좋은 해결책은 구글의 디자인입니다.

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

밀도

코틀린의 확장 기능을 이용한 보다 우아한 접근 방식

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

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()입니다.

픽셀을 사용하는 것처럼 dp를 사용해야 합니다.이것이 바로 독립적인 픽셀을 표시하는 것입니다.중간 밀도 화면에서 사용하는 것과 동일한 숫자를 사용하면 고밀도 화면에서 크기가 마법처럼 정확해집니다.

그러나 레이아웃 설계에 fill_parent 옵션이 필요한 것 같습니다.뷰 또는 컨트롤을 상위 컨테이너의 나머지 모든 크기로 확장하려면 fill_parent를 사용합니다.

PX그리고.DP다르지만 유사합니다.

DP화면의 실제 크기만 고려할 때의 해상도입니다.를 할 때DP 레이아웃이 의 화면으로 됩니다.pixel밀도

가끔 당신이 정말로 원하는 것은pixels하지만, 그리고 코드에서 차원을 다룰 때 당신은 항상 실제를 다루고 있습니다.pixels당신이 그것들을 변환하지 않는 한.

Android 기기에서 일반 크기hdpi화면.800x480 is 533x320DP(나는 믿습니다.)변환하기DP안으로pixels /1.5다시 변환하기 위해*1.5이것은 오직 하나의 화면 크기와dpi디자인에 따라 달라질 수 있습니다.우리 아티스트들이 주는.pixels하지만 그리고 나는 개종합니다.DP상기와 같이1.5등식

정수 값을 원하는 경우 Math.round()를 사용하면 플로트가 가장 가까운 정수로 반올림됩니다.

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

가장 좋은 대답은 Android 프레임워크 자체에서 나옵니다. 이 동일성을 사용하십시오.

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

(px에 추가 dp)

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

언급URL : https://stackoverflow.com/questions/4605527/converting-pixels-to-dp

반응형