We are working on an native Android app that handles large images (5MP+) from the phone’s gallery, eventually encoded base 64, JSONized and sent to an upstream server. We’ve used some of the guidance given in other StackOverflow questions. We’ve tried hard to keep memory usage to a minimum, following logcat closely, debugging, etc. And while we’ve gotten under control the “80% use case” we still are getting FATAL errors in certain cases (when the user picks a photo, then cancels, chooses a different one, for instance).
We’ve found that when importing a 5MP Bitmap, its size quadruples in the Heap (i.e. a 7Mb jpeg becomes 28Mb in memory). We’ve used tricks to convert to Base64 as efficiently as possible. We’ve made sure the JSON parser is not leaking and so forth.
So to get back to my original question, is there a way to circumvent Android’s Bitmap handling?
Rewrite your Web app to support binary payloads, so that you do not have to do ridiculous stuff like this. Upload JSON-encoded metadata in one request, then upload the image in its original format in a separate request, if need be. Or, use multipart upload to do both in one shot, leaving the image in its original format.
That is because PNGs, JPEGs, and the like are compressed, and the image needs to be uncompressed to be displayed.
You do not say if you are trying to display the image or not. If you are, use
BitmapFactorywith an appropriateBitmapFactory.Optionsto scale the image.If you are not trying to display the image, once you rewrite the Web app to accept a binary payload, you should not need to load the entire image into memory. Just upload it in the format that it already is in, reading in chunks at a time (e.g., 8KB) to write to the
OutputStremof yourHTTP PUT(or whatever) for the upload.