Glide로 가져온 이미지 Width, Height 구하기

Posted by ITPangPang
2016. 9. 25. 01:08 안드로이드(android)/오픈소스관련


Glide로 가져온 이미지

Width, Height 구하기



ㆍ 이번글에서는 Glide로 가져온 이미지가 어떤

    크기로 뿌려지는지 알아보도록 하겠습니다.


ㆍ 이 부분은 제가 처음에 Glide 쓸 때 헤매던 부분인데

    영어가 좀 약해서 그런가 아무리 구글링을 해봐도

    원하는 궁금증을 풀지 못해서 직접 테스트하면서

    이해하고 넘어간 부분입니다.


ㆍ 이미지를 ImageView에 뿌려줄때 원하는 크기로 뿌려야되는데

    wrap_content를 써도 안되고 Glide에 override를 써도 잘 안됩니다.

    (물론 안되는건 아니고.. 원하는 크기로 가져오는 방법은 아마 다음글에서 쓰지 않을까 생각됩니다)


ㆍ 이번글은 거의 테스트위주의 내용이라서 그냥 슥~ 한번 읽어보면 될 것 같습니다.



먼저 테스트이미지는

간단하게 각 dpi별

런쳐아이콘으로 준비했습니다

테스트 에뮬레이터가

xhdpi이므로 해당 폴더를 하나

만들어서 넣어줬습니다


자, 그럼 이제 테스트를

진행해보겠습니다


먼저 Glide를 쓰기전에 이미지를 그냥 xml에서

붙여서 앱을 실행시켰을때 사진의 크기를

구해보도록 하겠습니다


xml로

ImageView를 만든후에

이미지를 넣어보도록 하겠습니다

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
>
<ImageView
android:id="@+id/iv_md"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_md"
/>
<ImageView
android:id="@+id/iv_hd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_hd"
/>
<ImageView
android:id="@+id/iv_xhd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_xhd"
/>
<ImageView
android:id="@+id/iv_xxhd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_xxhd"
/>
<ImageView
android:id="@+id/iv_xxxhd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_xxxhd"
/>
</LinearLayout>


width와 height를 

wrap_content로 써줍니다


이 상태에서 앱을 실행하면

각 사이즈에 맞게 이미지가

ImageView에 set되서

출력됩니다



각 이미지의 크기를

알아보기 위해서

ImageView의 크기를

로그로 찍어보겠습니다


public class MainActivity extends AppCompatActivity
{
ImageView iv_md;
ImageView iv_hd;
ImageView iv_xhd;
ImageView iv_xxhd;
ImageView iv_xxxhd;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

iv_md = (ImageView) findViewById(R.id.iv_md);
iv_hd = (ImageView) findViewById(R.id.iv_hd);
iv_xhd = (ImageView) findViewById(R.id.iv_xhd);
iv_xxhd = (ImageView) findViewById(R.id.iv_xxhd);
iv_xxxhd = (ImageView) findViewById(R.id.iv_xxxhd);

new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
Log.d("ITPANGPANG","mdpi("+iv_md.getWidth()+" x "+iv_md.getHeight()+")");
Log.d("ITPANGPANG","hdpi("+iv_hd.getWidth()+" x "+iv_hd.getHeight()+")");
Log.d("ITPANGPANG","xhdpi("+iv_xhd.getWidth()+" x "+iv_xhd.getHeight()+")");
Log.d("ITPANGPANG","xxhdpi("+iv_xxhd.getWidth()+" x "+iv_xxhd.getHeight()+")");
Log.d("ITPANGPANG","xxxhdpi("+iv_xxxhd.getWidth()+" x "+iv_xxxhd.getHeight()+")");
}
}, 1000);
}
}


이런식으로 각 이미지뷰의 

Width와 Height를

가져와봤습니다.


조금 있다가 Glide도

똑같이 테스트해볼때

load 되는 시간이 있을 수 있어서


앱 실행후에

postDelayed로 1초뒤에 크기를

구하도록 코드를 작성하였습니다


결과를 보면


이미지의 실제크기

그대로 ImageView에 set되서

출력된 것을 확인 할 수 있습니다.


다음은 Glide를 사용해서 이미지를

불러오도록 하겠습니다


기존에 xml 파일에서

src만 전부 제거하도록

하겠습니다

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
>
<ImageView
android:id="@+id/iv_md"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/iv_hd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/iv_xhd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/iv_xxhd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/iv_xxxhd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>


이제 Glide를 이용해서

각 ImageView에 이미지를

set시켜보도록

하겠습니다


public class MainActivity extends AppCompatActivity
{
ImageView iv_md;
ImageView iv_hd;
ImageView iv_xhd;
ImageView iv_xxhd;
ImageView iv_xxxhd;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

iv_md = (ImageView) findViewById(R.id.iv_md);
iv_hd = (ImageView) findViewById(R.id.iv_hd);
iv_xhd = (ImageView) findViewById(R.id.iv_xhd);
iv_xxhd = (ImageView) findViewById(R.id.iv_xxhd);
iv_xxxhd = (ImageView) findViewById(R.id.iv_xxxhd);


Glide.with(this).load(R.drawable.ic_md).into(iv_md);
Glide.with(this).load(R.drawable.ic_hd).into(iv_hd);
Glide.with(this).load(R.drawable.ic_xhd).into(iv_xhd);
Glide.with(this).load(R.drawable.ic_xxhd).into(iv_xxhd);
Glide.with(this).load(R.drawable.ic_xxxhd).into(iv_xxxhd);



new Handler().postDelayed(new Runnable()
{
@Override
public void run()
{
Log.d("ITPANGPANG","mdpi("+iv_md.getWidth()+" x "+iv_md.getHeight()+")");
Log.d("ITPANGPANG","hdpi("+iv_hd.getWidth()+" x "+iv_hd.getHeight()+")");
Log.d("ITPANGPANG","xhdpi("+iv_xhd.getWidth()+" x "+iv_xhd.getHeight()+")");
Log.d("ITPANGPANG","xxhdpi("+iv_xxhd.getWidth()+" x "+iv_xxhd.getHeight()+")");
Log.d("ITPANGPANG","xxxhdpi("+iv_xxxhd.getWidth()+" x "+iv_xxxhd.getHeight()+")");
}
}, 1000);
}
}


이런식으로 넣어보면 되겠죠?


이제 앱을 실행시켜서

결과를 보겠습니다



????

결과는 아주 최악으로

나옵니다.


이미지 크기가 지멋대로

출력되서 나옵니다


총 5개의 이미지를

불러왔는데 공간이 모잘라서

2개의 이미지만 나오고

3개는 짤렸습니다..


코드에서 이미지뷰 크기를

로그로 찍어봤으니 결과를

확인해보도록 하겠습니다


기존 원본이미지와의

크기차이가 너무 심합니다.


이런 결과가 원래 나왔어야되는데...


어떤 기준으로 위와 같은 결과가

나왔는지 지금부터 테스트를

해보도록 하겠습니다.


맨땅에 헤딩 테스트 시작!!


결과를 보면

 width값 720은

고정인데 Height값만

다른것을 알 수 있습니다.


720.. 너무 익숙한 숫자입니다

평범한 xhdpi 디바이스의 width값..

720입니다


근데 혹시 아닐수도 있으니

확인 바로 해보면 되겠죠!


앱을 실행할때 디바이스의

Width, Height 값을 가져와보겠습니다.


super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

DisplayMetrics displayMetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
int deviceWidth = displayMetrics.widthPixels;
int deviceHeight = displayMetrics.heightPixels;

Log.d("ITPANGPANG","(Width x Height) = "+"("+deviceWidth+" x "+deviceHeight+")");


디바이스의 Width, Height값을 

구한 후에 결과를 보겠습니다.


이 디바이스의 화면

크기는 (720 x 1184)입니다


보통 (720 x 1280)인데 왜

height값이 1184이냐면

1280-1184 = 96


96의 값은 위의 에뮬레이터 사진을

보면 소프트웨어 키가 있습니다

그 부분이 96px을 차지하고 있습니다


혹시 확인하고 싶으면

아래코드를 추가시켜서 확인하면

됩니다

@SuppressLint("NewApi")
private int getSoftButtonsBarHeight()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
{
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
int usableHeight = metrics.heightPixels;
getWindowManager().getDefaultDisplay().getRealMetrics(metrics);
int realHeight = metrics.heightPixels;
if (realHeight > usableHeight)
return realHeight - usableHeight;
else
return 0;
}
return 0;
}



96이라는 값이 잘 나왔습니다!


어쨋든!!

디바이스의 Width값이

Glide로 불러온 이미지크기에

영향이 있을 것 같은 예감이 팍팍 듭니다.


자 그럼 이미지 크기를 변경해서

확실히 알아보도록 하겠습니다


첫번째 실험



아이콘의 크기를 제가 강제로

변경해서 3가지 크기를 준비했습니다

1. 720 x 720

2. 720 x 360

3. 360 x 720


차례대로 실행시켜서

결과를 확인해보겠습니다


결과는

1. (720x720) => (720x720)

2. (720x360) => (720x360)

3. (360x720) => (592 x 1184)


위의 결과를 얻었습니다

1,2번은 이미지 크기 그대로값이 나왔는데

3번만 다른 결과를 얻었습니다


여기까지만 보면 어느정도

어떤식으로 이미지를 가져오는지

예측 가능합니다


Glide에서 이미지 로드시

가져오는 이미지크기 예측


1. 디바이스의 Width를 기준으로 이미지 Width도 가져온다

= 이 말은 이미지의 크기에 상관없이 무조건 

디바이스 width가 720이면 이미지 width도 720으로 맞춥니다.


2. width로 크기를 맞춘후 증가시킨 비율 그대로 height도 증가시킨다

= 이건 3번이미지의 결과를 보면 알 수 있습니다

3번 원본이미지의 width가 360입니다

그럼 Glide로 불러왔을때 

디바이스의 Width가 720이므로 이미지 Width도 720으로

맞춰줍니다. 그럼 2배 증가시켰죠?

그럼 원본이미지의 비율이 깨지지않도록

Height도 2배로 증가시켜줍니다


즉,

(360x720) => (720x1440)으로

이미지 크기가 변경되는 겁니다.


그럼 위 크기대로 불러오느냐?

그럴려고 봤더니 height의 값이 1440입니다

디바이스의 height는 1184인데 이미지의 height가

1440이므로 화면에 나타낼 수가 없습니다.

그러므로 다시 height 기준으로 축소작업을

하게 됩니다


1440 * x = 1184

이걸 구해보면

1184/1440 = 0.82222... 무한대


이제 이 배수를 Width에 적용시킵니다

720 x 0.822222 = 592

정확히 일치하게 됩니다!


자 그럼 이번에는 확대는

예상값 대로 나왔으니

축소도 동일하게 적용되는지

실험해보겠습니다


번째 실험


1. 1440 x 1440

2. 1440 x 720

3. 500 x 2368


Glide로 이미지를 로드했을때

이미지크기를 위의 방식대로 계산해서

예상해보겠습니다


1번.

디바이스 width가 720으로 이미지 width를

720으로 축소시킵니다. 

그럼 1440 -> 720 반값이 되므로

원본사진 비율을 유지시키지 위해서 height값도

나누기 2를 해줍니다

height를 나누기 2 했을때 1184가 넘지않으므로

리사이징 작업을 중지하게 됩니다

1번 결과 예상 = (720x720)


2번.

Width값 0.5배이므로

height도 적용

2번 결과 예상 = (720x360)


3번.

Width값이 720 넘지 않으므로

그대로 가져오려 했으나 height값이

1184가 넘으므로 height를 1184로

축소 시킨다.

2386 * x = 1184

x 값이 0.5이므로 Width도 그대로 적용

3번 결과 예상 = (250x1184)


이제 실제로 결과를 확인한후에

예상값과 비교해봅니다


어떤가요?

정확히 일치했습니다.


제가 처음 Glide쓸때 테스트해보고

이정도면 정확도가 어느정도 맞다고

생각해서 이해하고 넘어간 내용입니다.

혹시나 아닐수도 있지만.. 그렇다면 알려주세요 ㅠ



여기까지가

Glide를 사용했을때

로드되는 이미지 크기가

어떻게 결정되는가?


에 관한 테스트였습니다.

다음글에서는

그렇다면 원하는 크기대로

이미지를 불러오려면

어떻게 해야하는가?

에 대한 내용으로 글을 써보도록 하겠습니다


소프트웨어키 코드 참고사이트 

: http://stackoverflow.com/questions/29398929/how-get-height-of-the-status-bar-and-soft-key-buttons-bar