Saya mengalami masalah dengan BitmapFactory.decodeStream(inputStream)
. Saat menggunakannya tanpa opsi, itu akan mengembalikan gambar. Tetapi ketika saya menggunakannya dengan opsi seperti di .decodeStream(inputStream, null, options)
dalamnya tidak pernah mengembalikan Bitmap.
Apa yang saya coba lakukan adalah men-downsample Bitmap sebelum saya benar-benar memuatnya untuk menghemat memori. Saya telah membaca beberapa panduan bagus, tetapi tidak ada yang menggunakan .decodeStream
.
KARYA HANYA HALUS
URL url = new URL(sUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream is = connection.getInputStream();
Bitmap img = BitmapFactory.decodeStream(is, null, options);
TIDAK BEKERJA
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);
Jawaban:
Masalahnya adalah setelah Anda menggunakan InputStream dari HttpUrlConnection untuk mengambil metadata gambar, Anda tidak dapat memutar ulang dan menggunakan InputStream yang sama lagi.
Oleh karena itu, Anda harus membuat InputStream baru untuk pengambilan sampel gambar yang sebenarnya.
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();
sumber
Coba bungkus InputStream dengan BufferedInputStream.
InputStream is = new BufferedInputStream(conn.getInputStream()); is.mark(is.available()); // Do the bound decoding // inJustDecodeBounds =true is.reset(); // Do the actual decoding
sumber
Saya pikir masalahnya adalah dengan logika "menghitung-skala-faktor" karena sisa kode terlihat benar bagi saya (dengan asumsi tentu saja bahwa inputstream tidak null).
Akan lebih baik jika Anda dapat memfaktorkan semua logika kalkulasi ukuran dari rutinitas ini ke dalam sebuah metode (sebut saja kalkulasiScaleFactor () atau apa pun) dan uji metode itu secara independen terlebih dahulu.
Sesuatu seperti:
// 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);
dan uji getScaleFactor (...) secara independen.
Ini juga akan membantu untuk mengelilingi seluruh kode dengan blok try..catch {}, jika belum dilakukan.
sumber
Anda dapat mengonversi InputStream ke array byte, dan menggunakan decodeByteArray (). Sebagai contoh,
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; }
sumber