안드로이드에서 이미지를 BitmapFactory를 이용해서 불러오다가 다음과 같은 오류가 발생하는 경우가 있습니다.
java.lang.OutOfMemoryError: bitmap size exceeds VM budget
이 에러 메세지에 대해서는 다양한 원인이 있을 수가 있는데,
그 중 네트워크를 이용해 이미지를 다운로드하다가 해당 이미지의 사이즈가 너무 커서 위와 같은 에러가 발생하는 경우가 있습니다.
(안드로이드 플랫폼 레벨에서 알아서 해결해주는 것이 가장 좋겠지만, 현재로선 그렇지 않으므로)
이 경우에는 불러올 이미지의 가로/세로 크기를 미리 확인한다음 이미지를 줄여서 로딩하는 방법으로 해결할 수 있습니다.
BitmapFactory의 Options을 이용해서 이미지의 사이즈를 측정하거나 줄일 수 있습니다.
Options의 inJustDecodeBounds 속성을 이용해서 이미지의 크기만 미리 측정한 다음,
Options의 inSampleSize 속성을 이용해서 이미지의 크기를 줄일 수 있습니다.
다음은 간단한 예제입니다. (아래 코드만으로 수행이 되지 않습니다. 관련글을 참조하세요.)
[안드로이드] URL을 이용해서 이미지 다운로드 하기 - http://snowbora.com/402
[안드로이드] URL을 이용해서 이미지 다운로드 하기 (멀티 쓰레드 이용) - http://snowbora.com/403
[안드로이드] URL을 이용해서 이미지 다운로드 하기 (멀티 쓰레드 이용) - http://snowbora.com/403
001.Bitmap downloadBitmap(String strImageURL)002.{003.final HttpClient client = (mode == Mode.NO_ASYNC_TASK) ? new DefaultHttpClient() : AndroidHttpClient.newInstance("Android");004.final HttpGet getRequest = new HttpGet(strImageURL);005.final int IMAGE_MAX_SIZE = 1280;006. 007.try008.{009.HttpResponse response = client.execute(getRequest);010.final int statusCode = response.getStatusLine().getStatusCode();011. 012.if (statusCode != HttpStatus.SC_OK)013.{014.return null;015.}016. 017.final HttpEntity entity = response.getEntity();018. 019.if (entity != null)020.{021.InputStream inputStream = null;022. 023.try024.{025.inputStream = entity.getContent();026. 027.BitmapFactory.Options bfo = new BitmapFactory.Options();028.bfo.inJustDecodeBounds = true;029. 030.BitmapFactory.decodeStream(new FlushedInputStream(inputStream), null, bfo);031. 032.if(bfo.outHeight * bfo.outWidth >= IMAGE_MAX_SIZE * IMAGE_MAX_SIZE)033.{034.bfo.inSampleSize = (int)Math.pow(2, (int)Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(bfo.outHeight, bfo.outWidth)) / Math.log(0.5)));035.}036.bfo.inJustDecodeBounds = false;037. 038.response = client.execute(getRequest);039.final int nRetryStatusCode = response.getStatusLine().getStatusCode();040. 041.if (nRetryStatusCode != HttpStatus.SC_OK)042.{043.return null;044.}045. 046.final HttpEntity reEntity = response.getEntity();047. 048.if (reEntity != null)049.{050.InputStream reInputStream = null;051. 052.try053.{054.reInputStream = reEntity.getContent();055.final Bitmap imgBitmap = BitmapFactory.decodeStream(new FlushedInputStream(reInputStream),null, bfo);056. 057.return imgBitmap;058.}059.finally060.{061.if (reInputStream != null)062.{063.reInputStream.close();064.}065. 066.reEntity.consumeContent();067.}068.}069.}070.finally071.{072.if (inputStream != null)073.{074.inputStream.close();075.}076. 077.entity.consumeContent();078.}079.}080.}081.catch (IOException e)082.{083.getRequest.abort();084.}085.catch (IllegalStateException e)086.{087.getRequest.abort();088.}089.catch (Exception e)090.{091.getRequest.abort();092.}093.finally094.{095.if ((client instanceof AndroidHttpClient))096.{097.((AndroidHttpClient)client).close();098.}099.}100. 101.return null;102. 103.}
댓글 없음:
댓글 쓰기