이 글은 PC 버전 TISTORY에 최적화 되어있습니다.
서론
안드로이드에서 사용하는 이미지들의 모양과 크기는 다양합니다. 많은 경우 이미지들은 User Interface에서 요구하는 것보다 큰 크기를 가지고 있죠. 예를 들어 '갤러리' 어플리케이션은 당신의 카메라로부터 당신의 디바이스보다 높은 해상도의 사진을 가져와 사용하게되죠. 당신은 주어진 메모리가 한정적이기 때문에, 이미지를 메모리에 로딩할 때 더 낮은 해상도의 이미지를 로딩해야하는 경우가 많습니다. 낮은 버젼의 이미지는 UI 컴포넌트의 사이즈와 맞춰져 디스플레이 되어야합니다. 고해상도를 사용하게 되면 오버헤드가 발생하게 되는 것 입니다.
비트맵의 치수와 타입 읽어들이기
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(getResources(), R.id.myimage, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
String imageType = options.outMimeType;
크기 줄인 이미지 메모리에 불러들이기
이제 당신이 이미지의 치수에 대해 알게 됬습니다. 그것은 풀 사이즈 이미지를 그대로 넣어버릴지, 또는 Subsampled 된 버전을 대신 넣어야 될지 결정합니다. 고려해야할 사항은 아래와 같습니다.
- 메모리에 전체 이미지를 로딩할 때 예상되는 메모리 사용량
- 이미지가 로딩될 이미지 뷰, UI 컴포넌트 요소의 면적
- 현재 디바이스 크기, 해상도
- 이미지 로딩을 제외한 다른 메모리 요구사항의 양
예를 들어 128x96 pixel의 썸네일 이미지가 필요한 뷰에 1024x768 pixel 이미지를 로딩하는 것은 가치 없는 행동입니다. 디코더가 이미지의 서브 버전 생성하기 위해, inSampleSize를 true로 설정하여 더 작은 크기의 이미지를 메모리에 로드 해야합니다. 2048x1536 해상도의 이미지를 4라는 값으로 inSampleSize로 설정하여 디코딩하면 512x384 크기의 비트맵이 생성됩니다. ARGB_8888을 기준으로 하면 Full size 이미지가 12MB를 사용하는 반면에 0.75MB 만 사용하면 되는 것이죠. 타겟의 너비와 높이를 기준으로 2의 지수 형태로 샘플의 사이즈를 계산하는 방법이 Android Developers에 나와있습니다.
public static int calculateInSampleSize(
BitmapFactory.Options options, int reqWidth, int reqHeight) {
// Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height / 2;
final int halfWidth = width / 2;
// Calculate the largest inSampleSize value that is a power of 2 and keeps both
// height and width larger than the requested height and width.
while ((halfHeight / inSampleSize) >= reqHeight
&& (halfWidth / inSampleSize) >= reqWidth) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
이미지 Resize 과정
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, 100, 100);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(url.openStream(), null, options);
참고사이트
'Frontend > Android' 카테고리의 다른 글
[안드로이드] Handler 사용법 (4) | 2016.07.16 |
---|---|
[안드로이드] 다른 액티비티의 함수 호출 방법(오류) -> 싱글톤 패턴 (2) | 2016.07.14 |
[안드로이드] RecyclerView 예제 (17) | 2016.07.12 |
[안드로이드] RecyclerView란? (RecyclerView와 ListView 차이) (6) | 2016.07.11 |
[안드로이드] 안드로이드 메모리 관리 (Weak Reference와 Soft Reference) (0) | 2016.07.08 |
[안드로이드] AsyncTask란? (개념 및 사용법) (3) | 2016.07.07 |