우리가 ImageView에 사진을 띄우고자 하는 경우는 여러가지 입니다.
1. 안드로이드 앱 안의 drawable폴더의 리소스를 보여주는 경우
2 .안드로이드 디바이스 안에 저장되어있는 사진을 보여주는 경우(갤러리 혹은 기타 내부 사진)
3. 이미지 URL을 로드해서 보여주고자 하는 경우
1,2번의 경우는 안드로이드 기기 내부의 리소스를 불러오는 작업이므로 예외사항도 적고 실제 구현도 복잡하지 않습니다.
그러나 3번처럼 이미지의 URL인 경우 http클라이언트를 이용해서 ImageView에 보여주어야 하는경우는 고려해야할 사항이 많습니다.
로딩 실패처리, 재시도처리, Out of Memory, 캐시,병렬처리, 디코딩, 이미지재활용 등등
요약하면, 이미지 로딩을 구현할 때는 HTTP 통신을 안정되게 구현하고, 비트맵으로 디코딩하면서 메모리가 넘치거나 새지 않도록 주의해야 한다. 네트워크 호출과 디코딩은 단순히 백그라운드 스레드에서 동작하는 것만으로는 충분하지 않고 더 적극적으로 병렬성을 활용해야 한다. 화면 회전, 전환, 스크롤 때 반복적인 요청이 가지 않도록 이미지를 캐시하고, 불필요해진 요청은 빠른 시점에 취소해서 더 나은 UI 반응을 제공하면서 자원을 절약해야 한다. 이 과제들을 모두 해결하려다 보면 처리 흐름은 복잡해지고, 비슷한 코드가 반복되기 쉽다.
Naver개발자 블로그 - Hello world
그래서 우리는 이러한 문제들을 미리 다 해결해둔 이미지로딩 라이브러리를 사용합니다.
이미지 로딩 라이브러리중 대표적으로 많이 쓰이고 있는 (혹은 좋은) 이미지 로딩 라이브러리는 아래와 같습니다.
1. Universal Image Loader(UIL)
- 아래 3개의 이미지로딩 라이브러리 이전에 가장 많이 쓰이던 라이브러리입니다.
- 가장 많이 쓰였었기때문에 기능이나 오류에 관련된 자료들을 많이 찾아 볼수 있습니다.
- 여러가지 Custom하게 변경할수있도록 많은 옵션을 제공합니다.
- 개인적으로도 개발하는 모든 앱에 UIL을 이용했었습니다.(현재는 모두 Glide 혹은 Picasso를 사용중)
- https://github.com/nostra13/Android-Universal-Image-Loader
DisplayImageOptions options = new DisplayImageOptions.Builder()
.cacheInMemory()
.cacheOnDisc()
...
.build();
ImageLoader.getInstance().displayImage(imageUrl, imageView, options);
2. Picasso
- UIL이후에 최근에 가장 널리 쓰이고있는 아미지로딩 라이브러리입니다.
- 제가 너무 좋아하는 Square에서 만든 라이브러리입니다.(Okhttp, Retrofit 등등의 라이브러리를 만든 회사)
- 별다른 설정 작업없이 직관적으로 함수를 호출하면 됩니다.
- http://square.github.io/picasso/
Picasso.with(context).load(imageUrl).resize(30, 30).into(imageView); }
3. Glide
- Google에서 개발해서 밀고있던 volly이후에 2014년에 공개된 라이브러리입니다.
- Bump앱을 구글이 인수하면서 bump앱에서 사용하던 이미지 라이브러리를 공개한것이 이 Glide입니다다.
- 기존의 Picasso에서 사용하는 함수 방식과 거의 비슷합니다(일부 함수를 빼고는 거의 똑같다고 봐도 좋습니다.)
- 개인적으로 성능이 제일 좋다고 생각하는 라이브러리입니다.(물론 저는 일부 기능에서는 Picasso를 사용합니다.)
- 다른 이미지 로딩라이브러리에는 없는 썸네일보기, GIF로딩, 동영상 스틸 보기 기능까지 지원합니다.
- https://github.com/bumptech/glide
Glide.with(this).load("http://www.selphone.co.kr/homepage/img/team/3.jpg").into(imageView);
4. Fresco
- facebook에서 공개한 이미지라이브러리입니다.
- 4개의 라이브러리중에서 가장 최근에 공개되었습니다(2015/03/26)
- 다만, 아직 최근에 공개된 라이브러리라서 레퍼런스도 적고 Fresco의 ImageView를 사용해아한다는것이 단점입니다.
- http://frescolib.org/index.html
<XML정의>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fresco="http://schemas.android.com/apk/res-auto">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/my_image_view"
android:layout_width="200dip"
android:layout_height="200dip"
fresco:placeholderImage="@drawable/my_drawable" />
</LinearLayout>
<뷰에서 사용>
Fresco.initialize(this);
setContentView(R.layout.activity_main);
SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.my_image_view);
simpleDraweeView.setImageURI(Uri.parse("http://www.url.com/image.png"));
Picasso와 Glide의 상세한 비교를 살펴보시려면 아래 포스팅을 참고하시면 좋습니다.
그중에서 제가 가장 자주 쓰고있는 Glide에 대해서 소개해드리겠습니다.
Glide
https://github.com/bumptech/glide
1. Gradle추가
compile 'com.github.bumptech.glide:glide:3.6.0'
2. 사용법
Glide.with(this).load("http://www.selphone.co.kr/homepage/img/team/3.jpg").into(imageView);
3. 유용한 함수
- override()
: 지정한 이미지의 크기만큼만 불러올수 있습니다. 이를 통해 이미지 로딩 속도를 최적화 할수있습니다.
- placeholder()
: 이미지를 로딩하는동안 처음에 보여줄 placeholder이미지를 지정할 수 있습니다.
- error()
이미지로딩에 실패했을경우 실패 이미지를 지정할 수 있습니다.
- thumbnail()
: 지정한 %비율 만큼 미리 이미지를 가져와서 보여줍니다.
0.1f로 지정했다면 실제 이미지 크기중 10%만 먼저 가져와서 흐릿하게 보여줍니다.
- asGif()
: 정적인 이미지 뿐만 아니라 GIF도 로딩할수 있습니다.
4. 다른 라이브러리들과의 성능 비교
출처: http://dev2.prompt.co.kr/31
메모리, 속도 값은 총 6장의 이미지를 리스트뷰에 띄우는 방식으로 3회 진행하여 평균값으로 계산했습니다.
반복 스크롤 부분은 50장 정도의 이미지를 리스트뷰에 띄웠고 메모리를 정리하기 직전 최대 사용량을 구했습니다.
Library 종류 |
이미지 |
최초 |
디스크 캐시 |
메모리 캐시 |
스크롤 반복 | |||
메모리(MB) |
속도(ms) |
메모리(MB) |
속도(ms) |
메모리(MB) |
속도(ms) |
최대 할당 메모리(MB) | ||
Glide |
301 |
4.6 |
2603 |
2.2 |
159 |
0.1 |
1 |
115 |
563 |
2.9 |
526 |
1.4 |
45 |
0.1 |
1 | ||
219 |
1.8 |
575 |
1.1 |
36 |
0 |
2 | ||
456 |
0.9 |
715 |
1.3 |
54 |
0.1 |
1 | ||
238 |
2.3 |
407 |
1.2 |
37 |
0.1 |
1 | ||
556 |
1.9 |
507 |
1.3 |
48 |
0.1 |
1 | ||
Picasso |
301 |
9.3 |
706 |
9.5 |
542 |
0.2 |
0 |
65 |
563 |
9.4 |
1021 |
9.4 |
355 |
0.1 |
1 | ||
219 |
9.5 |
496 |
9.5 |
333 |
0.1 |
0 | ||
456 |
9.4 |
566 |
9.4 |
344 |
0.1 |
1 | ||
238 |
9.6 |
1117 |
9.4 |
339 |
0.1 |
0 | ||
556 |
9.5 |
970 |
9.4 |
361 |
0.1 |
0 | ||
AUIL |
301 |
7.6 |
1924 |
7.4 |
169 |
7.4 |
113 |
65 |
563 |
7.2 |
2361 |
7.5 |
142 |
0 |
130 | ||
219 |
7.3 |
1084 |
7.5 |
99 |
7.5 |
134 | ||
456 |
7.4 |
2089 |
7.5 |
140 |
7.6 |
159 | ||
238 |
7.3 |
1030 |
7.4 |
136 |
7.4 |
122 | ||
556 |
7.4 |
1968 |
7.5 |
149 |
7.5 |
1 | ||
Volley |
301 |
2.4 |
964 |
2.2 |
267 |
0.1 |
188 |
100 |
563 |
3 |
795 |
2.4 |
227 |
0.1 |
382 | ||
219 |
2.4 |
481 |
2.2 |
178 |
0 |
1 | ||
456 |
2.8 |
1346 |
2.3 |
333 |
0.1 |
1 | ||
238 |
2.4 |
1436 |
2.1 |
333 |
0.1 |
0 | ||
556 |
3 |
1817 |
2.5 |
347 |
0.1 |
1 |
Library 종류 |
비고 |
Glide |
반복 스크롤 시 메모리를 많이 쓰는 만큼 빠른 속도와 안정성을 보장. 디스크 캐시에서 읽어오는 속도가 빨라 스크롤 시에도 이미지가 빠르게 뜸. |
AUIL |
메모리 캐시 히팅률이 낮음. 스크롤 시 이전 이미지가 보여지는 현상 발생. |
Volley |
가끔 OOM으로 죽는 현상 발생. 빠르게 상하 스크롤시 이미지 거의 안 뜸. |
이미지로딩 라이브러리및 Glide에 관련한 유용한 글들
- http://helloworld.naver.com/helloworld/textyle/429368
Glide를 사용하면서 이미지변형(프로필모양의 원형, 컬러 필터링,블러 등등의 작업)이 필요한경우 Transformations을 이용하셔도 좋습니다.
[안드로이드]유용한 라이브러리 - Glide-Transformations(이미지 변형)
출처: http://gun0912.tistory.com/17 [박상권의 삽질블로그]
출처: http://gun0912.tistory.com/17 [박상권의 삽질블로그]
출처: http://gun0912.tistory.com/17 [박상권의 삽질블로그]
'Android' 카테고리의 다른 글
URL 절대경로 가져오기 ( 갤러리에서 사용 ) (0) | 2018.04.25 |
---|---|
EditText 줄 제한 textMultiLine (0) | 2018.04.24 |
RecyclerView 사용하기 (0) | 2018.04.23 |
안드로이드 intent를 이용한 데이터 전달 (0) | 2018.04.21 |
카카오톡 로그인 연동하기 3 (1) | 2018.04.21 |