안드로이드에는 이미지크기를 줄일때 Bitmap.createScaledBitmap() 이라는 유용한 함수를 제공해 줍니다.
함수원형을 보면 아래와 같습니다.


public static Bitmap createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)

여기서 문제는 Bitmap 소스가 들어가야 한다는 것입니다.
결국 저 함수를 쓰기위해서는 미리 디코딩 작업을해서 이미지소스를 메모리에 올려야 한다는 것이죠.


Bitmap tempBitmap = BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null, resizeOpts);
Bitmap finalBitmap = Bitmap.createScaledBitmap(tempBitmap, dimen[0], dimen[1], false);
위와 같이 사용해야 합니다.
이러한 형태라면 소스 이미지가 커진다면 메모리도 그만큼 커야하는데 모바일 환경이라 그만큼 큰 가용메모리를 가진디바이스가 별로 없습니다.
결국 OutOfMemoryError 를 벹어내면서 크래시가 나게 되는것이죠.

그래서 있는것이 inSampleSize 라는 옵션입니다.
이것은 decodeStream 을 이용해 이미지를 디코딩할때 애초에 줄여서 디코딩해주는 역할을 하죠.
단점은 정확한 크기를 지정할수 없다는것입니다.
사용법은 아래와 같습니다.

BitmapFactory.Options resizeOpts = new Options();
resizeOpts.inSampleSize = 2;
Bitmap tempBitmap = BitmapFactory.decodeStream(new FileInputStream(bitmapFile), null, resizeOpts);
Bitmap finalBitmap = Bitmap.createScaledBitmap(tempBitmap, dimen[0], dimen[1], false);
이것은 디코딩을 할때 원본크기의 1/2 로 디코딩하라는 말입니다.
즉 inSampleSize 의 역수만큼의 크기로 사이즈를 줄입니다.
예를들어 4 라면 1/4 로 이미지가 줄어서 디코딩 되게 되죠.

어차피 사이즈를 줄일껀데 소스이미지 전체를 메모리에 올릴필요가 없습니다.
결국 이미지를 줄이기 위해서는 inSampleSize 를 이용하여 줄이고자하는 크기의 최대한 근접한 값으로 줄인후에 createScaledBitmap 함수를 호출해서 정확하게 줄이는것이 OutOfMemoryError 를 피하는 방법입니다.

by cranix 2011. 10. 20. 17:58