안드로이드에서 이미지를 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.
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.
}
댓글 없음:
댓글 쓰기