简体   繁体   中英

InputStream read twice when calculating sampled image?

im trying to adapt a method to prevent an outOfMemoryError when reading from an internet bitmap. Do I use it right? Isnt the stream read twice from internet?

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
URL url = new URL(imageUrl);
InputStream inputStream = url.openConnection().getInputStream();
BitmapFactory.decodeStream(inputStream, null, options);

// Calculate inSampleSize
int coverDimensions = CommonTasks.getDisplayMinSize(getActivity());
options.inSampleSize = calculateInSampleSize(options, coverDimensions, coverDimensions);

 // Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(inputStream, null, options);

private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
        // Raw height and width of image
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }

In the while use || to keep both width and height withing bounds. And no , you cannot reread an InputStream.

No. Theoretically you could use reset() but internet is sequential I/O:

boolen canReset = inputStream.markSupported();
if (canReset) {
    inputStream.mark(Integer.MAX_VALUE);
}
... first read
if (canReset) {
    inputStream.reset();
}
... second read

Instead of a boolean flag, catching an IOException on reset would be easier: it might be thrown anyway when the read limit is exceeded for instance.

Simply reread. The second time it might come from cache.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM