옵션이 설정되면 null을 반환하는 BitmapFactory.decodeStream
.NET에 문제가 BitmapFactory.decodeStream(inputStream)
있습니다. 옵션없이 사용하면 이미지가 반환됩니다. 그러나 사용하면 Bitmaps를 사용하지 .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();
InputStream을 BufferedInputStream으로 래핑하십시오.
InputStream is = new BufferedInputStream(conn.getInputStream());
is.mark(is.available());
// Do the bound decoding
// inJustDecodeBounds =true
is.reset();
// Do the actual decoding
문제는 "calculate-scale-factor"논리에 있다고 생각합니다. 나머지 코드가 나에게 맞아 보이기 때문입니다 (물론 inputstream이 null이 아니라고 가정).
이 루틴의 모든 크기 계산 논리를 하나의 메서드 (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;
}
'IT' 카테고리의 다른 글
사용자가 뒤로 버튼을 사용하여 페이지로 이동했는지 여부를 감지합니까? (0) | 2020.09.14 |
---|---|
내 로컬 저장소를 git-pull에 사용하려면 어떻게해야합니까? (0) | 2020.09.14 |
Java에서 cURL을 사용하는 방법은 무엇입니까? (0) | 2020.09.14 |
정적 메서드 대신 싱글 톤을 사용하는 이유는 무엇입니까? (0) | 2020.09.14 |
jquery .val ( 'xyz') 사용할 때 Knockout.js 바인딩 된 입력 값이 업데이트되지 않음 (0) | 2020.09.14 |