개인적으로 개발한 Application에 Podcast의 주소를 입력하면 Podcast 목록과

Podcast 대표 이미지을 보여주는 기능이 있는데, 개발 폰으로 사용하고 있는 Nexus S를

기준으로 Podcast 대표 이미지의 크기가 2000 x 2000 을 넘어가면 Out Of Memory가 발생한다.

폰마다 사정이 다를 수는 있지만 2000 x 2000 을 넘어가는 이미지에 대해서는 상당히 많은

단말에서 에러를 내뿜어내고 있었다. (가슴 아프게도 Developer Console에 30개가 넘는 리포트가 도착한 뒤에야 업데이트를 할 수 있었다;;;)

만약 Developer Console에 “bitmap size exceeds VM budget” 이런 문구가 보인다면

위 증상을 의심해 볼만하다!!!

 

만약 이미지의 사이즈를 ‘미리’ 알고 있다면 Bitmap 객체를 생성할 때

Down Sampling을 해서 Out Of Memory를 피할 수 있다.

아래는 Bitmap 객체를 생성하지 않고 이미지의 width, height 값을 얻어올 수 있는 함수다!

 

 

 

inJustDecodeBounds 필드의 속성은 아래와 같다.

If set to true, the decoder will return null (no bitmap), but the out… fields will still be set, allowing the caller to query the bitmap without having to allocate the memory for its pixels.

inJustDecodeBounds값이 true로 설정되면 decoder가 bitmap object에 대해 메모리를 할당하지 않고, 따라서 bitmap을 반환하지도 않는다. 다만 options fields는 값이 채워지기 때문에 Load 하려는 이미지의 크기를 포함한 정보들을 얻어올 수 있다.

이렇게 이미지의 크기를 미리 얻어왔다면 아래의 코드로 Down Sampling을 할 수 있다.

이미지의 크기가 내가 생각한 최대치보다 크면 scale 값을 구한다.

inSampleSize 필드의 속성은 아래와 같다.

If set to a value > 1, requests the decoder to subsample the original image, returning a smaller image to save memory. The sample size is the number of pixels in either dimension that correspond to a single pixel in the decoded bitmap. For example, inSampleSize == 4 returns an image that is 1/4 the width/height of the original, and 1/16 the number of pixels.

즉, 내가 최대치로 정한 이미지의 width가 128인데 실제 이미지의 width는 256일 경우

inSampleSize를 2로 설정해줘야 한다.

 

FULL SOURCE CODE (IOUtils의 toByteArray 함수는 Commons IO API 사용)