Android library is not so smart for loading images, so you have to create workarounds for this.
In my tests, Drawable.createFromStream
uses more memory than BitmapFactory.decodeStream
.
You may change the Color scheme to reduce memory (RGB_565), but the image will lose quality too:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Config.RGB_565;
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);
Reference: http://developer.android.com/reference/android/graphics/Bitmap.Config.html
You can also load a scaled image, which will decrease a lot the memory usage, but you have to know your images to not lose too much quality of it.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);
Reference: http://developer.android.com/reference/android/graphics/BitmapFactory.Options.html
To define the inSampleSize dynamically, you may want to know the image size to take your decision:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
bitmap = BitmapFactory.decodeStream(stream, null, options);
int imageHeight = options.outHeight;
int imageWidth = options.outWidth;
options.inJustDecodeBounds = false;
// recreate the stream
// make some calculation to define inSampleSize
options.inSampleSize = ?;
Bitmap bitmap = BitmapFactory.decodeStream(stream, null, options);
You can customize the inSampleSize according to the screen size of the device. To get the screen size, you can do:
DisplayMetrics metrics = new DisplayMetrics();
((Activity) activity).getWindowManager().getDefaultDisplay().getMetrics(metrics);
int screenWidth = metrics.widthPixels;
int screenHeight =metrics.heightPixels;
Other tutorials:
– http://developer.android.com/training/displaying-bitmaps/load-bitmap.html
– http://developer.android.com/training/displaying-bitmaps/index.html