2012년 6월 22일 금요일

안드로이드 - 이미지 크기에 따라서 크기 재설정 후 불러오기(bitmap 생성)

 출처 : http://snowbora.com/417


안드로이드에서 이미지를 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
    
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.try
008.{
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.try
024.{
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.try
053.{
054.reInputStream = reEntity.getContent();
055.final Bitmap imgBitmap = BitmapFactory.decodeStream(new FlushedInputStream(reInputStream),null, bfo);
056. 
057.return imgBitmap;
058.}
059.finally
060.{
061.if (reInputStream != null)
062.{
063.reInputStream.close();
064.}
065. 
066.reEntity.consumeContent();
067.}
068.}
069.}
070.finally
071.{
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.finally
094.{
095.if ((client instanceof AndroidHttpClient))
096.{
097.((AndroidHttpClient)client).close();
098.}
099.}
100. 
101.return null;
102. 
103.}

댓글 없음:

댓글 쓰기