У меня есть проблемы с 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);
Проблема заключалась в том, что после того, как вы использовали InputStream из HttpUrlConnection для получения метаданных изображения, вы не могли перемотать назад и снова использовать тот же 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();
Я думаю, что проблема связана с логикой «вычислить масштабный коэффициент», потому что остальная часть кода мне кажется правильной (при условии, конечно, что входной поток не равен нулю).
Было бы лучше, если бы вы могли вынести всю логику вычисления размера из этой процедуры в метод (назовите его 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 {}, если это еще не сделано.