옵션이 설정된 경우 BitmapFactory.decodeStream이 null을 반환합니다.
에 문제가 있습니다.BitmapFactory.decodeStream(inputStream)
옵션 없이 사용하면 이미지가 반환됩니다.단, 옵션과 함께 사용할 경우.decodeStream(inputStream, null, options)
비트맵을 반환하지 않습니다.
메모리 절약을 위해 실제로 비트맵을 로드하기 전에 비트맵을 다운샘플링하려고 합니다.좋은 가이드는 읽어봤지만, 어떤 가이드도.decodeStream
.
정상적으로 동작
URL url = new URL(sUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream is = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is, null, options);
동작하지 않다
InputStream is = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is, null, options);
InputStream is = connection.getInputStream();
Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
Boolean scaleByHeight = Math.abs(options.outHeight - TARGET_HEIGHT) >= Math.abs(options.outWidth - TARGET_WIDTH);
if (options.outHeight * options.outWidth * 2 >= 200*100*2){
// Load, scaling to smallest power of 2 that'll get it <= desired dimensions
double sampleSize = scaleByHeight
? options.outHeight / TARGET_HEIGHT
: options.outWidth / TARGET_WIDTH;
options.inSampleSize =
(int)Math.pow(2d, Math.floor(
Math.log(sampleSize)/Math.log(2d)));
}
// Do the actual decoding
options.inJustDecodeBounds = false;
Bitmap img = BitmapFactory.decodeStream(is, null, options);
문제는 HttpUrlConnection의 InputStream을 사용하여 이미지 메타데이터를 가져오면 동일한 InputStream을 되감아 다시 사용할 수 없다는 것입니다.
따라서 이미지의 실제 샘플링을 위해 새로운 InputStream을 생성해야 합니다.
Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
Boolean scaleByHeight = Math.abs(options.outHeight - TARGET_HEIGHT) >= Math.abs(options.outWidth - TARGET_WIDTH);
if(options.outHeight * options.outWidth * 2 >= 200*200*2){
// Load, scaling to smallest power of 2 that'll get it <= desired dimensions
double sampleSize = scaleByHeight
? options.outHeight / TARGET_HEIGHT
: options.outWidth / TARGET_WIDTH;
options.inSampleSize =
(int)Math.pow(2d, Math.floor(
Math.log(sampleSize)/Math.log(2d)));
}
// Do the actual decoding
options.inJustDecodeBounds = false;
is.close();
is = getHTTPConnectionInputStream(sUrl);
Bitmap img = BitmapFactory.decodeStream(is, null, options);
is.close();
BufferedInputStream을 사용하여 InputStream 랩을 시도합니다.
InputStream is = new BufferedInputStream(conn.getInputStream());
is.mark(is.available());
// Do the bound decoding
// inJustDecodeBounds =true
is.reset();
// Do the actual decoding
나머지 코드는 올바른 것 같기 때문에(물론 입력 스트림이 null이 아니라고 가정하면) "calculate-scale-factor" 로직이 문제라고 생각합니다.
이 루틴에서 모든 크기 계산 로직을 인수하여 메서드(calculateScaleFactor() 또는 기타)로 만들고 먼저 그 메서드를 독립적으로 테스트하는 것이 좋습니다.
예를 들어 다음과 같습니다.
// Get the stream
InputStream is = mUrl.openStream();
// get the Image bounds
BitmapFactory.Options options=new BitmapFactory.Options();
options.inJustDecodeBounds = true;
bitmap = BitmapFactory.decodeStream(is,null,options);
//get actual width x height of the image and calculate the scale factor
options.inSampleSize = getScaleFactor(options.outWidth,options.outHeight,
view.getWidth(),view.getHeight());
options.inJustDecodeBounds = false;
bitmap=BitmapFactory.decodeStream(mUrl.openStream(),null,options);
getScaleFactor(...)를 개별적으로 테스트합니다.
또, 코드 전체를 try로 둘러싸는 것도 도움이 됩니다.catch{}블록(아직 완료되지 않은 경우)
InputStream을 바이트 배열로 변환하고 decodeByteArray()를 사용할 수 있습니다.예를들면,
public static Bitmap decodeSampledBitmapFromStream(InputStream inputStream, int reqWidth, int reqHeight) {
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
try {
int n;
byte[] buffer = new byte[1024];
while ((n = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, n);
}
return decodeSampledBitmapFromByteArray(outputStream.toByteArray(), reqWidth, reqHeight);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public static Bitmap decodeSampledBitmapFromByteArray(byte[] data, int reqWidth, int reqHeight) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeByteArray(data, 0, data.length, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeByteArray(data, 0, data.length, options);
}
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int
reqHeight) {
int width = options.outWidth;
int height = options.outHeight;
int inSampleSize = 1;
if (width > reqWidth || height > reqHeight) {
int halfWidth = width / 2;
int halfHeight = height / 2;
while (halfWidth / inSampleSize >= reqWidth && halfHeight / inSampleSize >= reqHeight) {
inSampleSize *= 2;
}
}
return inSampleSize;
}
언급URL : https://stackoverflow.com/questions/2503628/bitmapfactory-decodestream-returning-null-when-options-are-set
'programing' 카테고리의 다른 글
PHP: stdClass 개체 수 (0) | 2023.01.17 |
---|---|
!== "displicate" vs. != null 유형 (0) | 2023.01.17 |
Larabel - 웅변 또는 유창 랜덤 행 (0) | 2023.01.17 |
Python에서 "raise" 키워드를 사용하는 방법 (0) | 2022.12.24 |
서로 다른 데이터베이스 간의 MySQL InnoDB 외부 키 (0) | 2022.12.24 |