0

In my app, I make a network request for the image file and then try to reduce the generated bitmap size. I am building upon this documentation. Instead of a static resource, I have a file stream to be read and decoded to bitmap. As you can see in below code, I am using BufferredInputStream, so that before calling decodeStream second time, I can reset the stream. But the messages which I am logging after that statement are not getting printed and also no bitmap is created. It does not even throw any error. Here is how I am reading and decoding image from a url -

URL url = new URL(params[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();

InputStream inp = connection.getInputStream();
BufferedInputStream bufferedinp = new BufferedInputStream(inp);

BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
_BitMap = BitmapFactory.decodeStream(bufferedinp, null, options);

Log.d(TAG,"imageanalysis init width: " + Integer.toString(options.outWidth));
Log.d(TAG,"imageanalysis init height: " + Integer.toString(options.outHeight));

// get system height and width here --  fixed for now
int reqWidth = 250;
int reqHeight = 220;

options.inSampleSize = Common.getInSampleSize(options, reqWidth, reqHeight);

options.inJustDecodeBounds = false;

bufferedinp.reset(); // resetting the stream to read from start
_BitMap = BitmapFactory.decodeStream(bufferedinp, null, options);

Log.d(TAG,"imageanalysis fin width: " + Integer.toString(_BitMap.getWidth())); // doesn't get logged
Log.d(TAG,"imageanalysis fin height" + Integer.toString(_BitMap.getHeight())); // doesn't get logged

Just for reference, getInSampleSize is here and works fine (returns 2 in my case) -

public static int getInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight)
{
    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;

        Log.d("Common", "imageananalysis halfHeight: " + Integer.toString(halfHeight));
        Log.d("Common", "imageananalysis halfWidth: " + Integer.toString(halfWidth));

        while((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth)
        {
            Log.d("Common", "imageanalysis in loop samplesize: " + Integer.toString(inSampleSize));
            inSampleSize *= 2;
        }
    }

    Log.d("Common", "imageanalysis ret samplesize: " + Integer.toString(inSampleSize));

    return inSampleSize;
}

What can be the issue here? Any help will be appreciated.

Sam
  • 4,302
  • 12
  • 40
  • 74
  • Why do you need to read the stream again from a URL connection. That is an expensive way of doing it, instead of saving the steam to a local storage and reading again from the local storage. Reset may not work for a stream from a URL connection, you may need to disconnect and reconnect again using the same URL. If you look at the docs for reset(), it says the stream need to be marked, If markpos is -1 (no mark has been set or the mark has been invalidated), an IOException is thrown. Otherwise, pos is set equal to markpos – faljbour Apr 18 '15 at 21:37
  • I tried marking too, but it decoded the stream to null. So, I guess that doesn't work either for HttpUrlConnection. So, reset is useless. Is writing the stream to a temp file the only solution to this? – Sam Apr 18 '15 at 21:51
  • no, I think that is one solution, but if you prefer stream the file again, you can disconnect and reconnect to stream the file again – faljbour Apr 18 '15 at 21:52
  • But again I would be accessing the resource twice, which I want to avoid. – Sam Apr 18 '15 at 21:54
  • 1
    Correct, you do not want to stream twice this way, if the stream size is small, you can leave in memory and use again, but to be on the safe side it is better to save into a temp directory and reprocess – faljbour Apr 18 '15 at 21:56
  • @faljbour I implemented the same now - used getExternalCacheDir (rather than getCacheDir to avoid memory limitation), and deleting the file soon after decode occurs. Works fine now. – Sam Apr 18 '15 at 22:24
  • check out this post http://stackoverflow.com/questions/17839388/creating-a-scaled-bitmap-with-createscaledbitmap-in-android, using instead Bitmap.createScaledBitmap and using the original bitmap as an input so that you do not have to stream it again or even save it into storage – faljbour Apr 18 '15 at 22:24

0 Answers0