안녕세계

[안드로이드] DpToPx & PxToPx 본문

[안드로이드] DpToPx & PxToPx

Junhong Kim 2017. 8. 10. 17:34
728x90
반응형

안드로이드 개발을 하다보면 Pixel  → DP로 또는 DP → PX 로 바꿔줘야할 경우가 있습니다.

Android에 dp를 px로 변환식이 필요한 이유는, JAVA에서는 dp를 이용해서 View의 크기를 바꿀 수 없기 때문입니다.


* 해상도 별로 1dp의 px 값은 아래와 같이 다르게 보입니다

ldpi(=120dpi)

1dp = 0.75px

0.75 density

 

mdpi(=160dpi)

1dp = 1.00px

1.00 density

Baseline

hdpi(=240dpi)

1dp = 1.50px

1.50 density

 

xdpi(=320dpi)

1dp = 2.00px

2.00 density


xxdpi(=480dpi)

1dp = 3.00px

3.00 density

 

xxxdpi(=640dpi)

1dp = 4.00px

4.00 density



* DP (DIP, Density Independent Pixel)

Android에서 다양한 단말 화면 크기를 서포트하기 위해 만든 단위입니다.

자신이 만든 레이아웃이 다양한 단말에서 동일하게 보이기 위해서는 dp를 써야합니다.


안드로이드는 160dpi(mdpi)를 Baseline으로 생각하므로,

480 x 320 (160dpi) LCD => dp로 480 x 320

480 x 800 (160dpi) LCD => dp로 480 x 800


480 x 800 (240dp) LCD => dp로 320 x 533 (= 480 / 1.5, 800 / 1.5)

dp = px / ( hdpi / mdpi )

dp = px / (density / 160)


dp를 px로 나타낸다면

px = dp * (density / 16)


* density 구하기

단말 화면의 density를 알기 위해서는 WindowManager를 쓰면 됩니다.

DisplayMetrics outMetrics = new DisplayMetrics();

DisplayMetrics outMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
int px = dp * outMetrics.densityDpi;

outMetrics.densityDi 변수는 (density / 160) 의 결과 값이 들어 있습니다.

그러므로 px = dp * outMetrics.density 입니다.


ps. Google Developer Site에서는 반올림 처리를 합니다 (보다 정확한 px 값을 얻기 위해 필요)

int px = (dp * outMetrics.density + 0.5);


* PxToDp & DpToPx 계산 방법

px = dp * (dpi / 160)

   = dp * density


dp = px / (dpi / 160)

   = px / density


위에서 160은 mdpi 값 입니다. 예로 hdpi에서 1dp는 1.5 physical px와 같습니다


dp로 뷰의 크기를 지정하면 해상도(화면의 밀도)가 다르더라도 항상 동일한 크기로 표시됩니다.

XML 코드에서는 px과 dp를 선택적으로 사용할 수 있지만, JAVA 코드에서는 무조건 PX로 인식합니다.

그러므로 px을 dp로 바꿔주는 작업(px이 dp가 되는것이 아니라 px 값에 대한 dp 비율에 대한 px 값이 나오는 것) 을 한뒤

densitiy를 알맞은 수에 곱하고 다시 px로 변환 시킵니다.


* dpi와 density 구하는 방법

DisplayMetrics displayMetrics= new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);


int dpi = displayMetrics.densityDpi;
float density = displayMetrics.density;

* Dp To Px (1)

public int dpToPx(Context context, float dp){
int px = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics());
return px;
}

Dp To Px (2)

public float dpToPx(Context context, float dp) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, dm);
}

* Px To Dp

public float pxToDp(Context context, float px) {

// 해상도 마다 다른 density 를 반환. xxxhdpi는 density = 4
float density = context.getResources().getDisplayMetrics().density;

if (density == 1.0) // mpdi (160dpi) -- xxxhdpi (density = 4)기준으로 density 값을 재설정 한다
density *= 4.0;
else if (density == 1.5) // hdpi (240dpi)
density *= (8 / 3);
else if (density == 2.0) // xhdpi (320dpi)
density *= 2.0;

return px / density; // dp 값 반환
}

참고

[1] http://blog.naver.com/dd00oo/20200626376

[2] http://stackoverflow.com/questions/4605527/converting-pixels-to-dp

[3] http://hashcode.co.kr/questions/44/px-dp-dip-sp%EC%9D%98-%EC%B0%A8%EC%9D%B4%EC%A0%90%EC%9D%B4-%EB%AD%94%EA%B0%80%EC%9A%94

[4] http://gyuha.tistory.com/438

[5] http://blog.naver.com/dythmall/30096162077

728x90
반응형
Comments