You can use the BitmapFactory to just get the bounds of the image and then load a smaller version of the image that fits in your current memory:
/**
* Decodes the given inputstream into a Bitmap, scales the bitmap to the
* required height and width if image dimensions are bigger. Note: the
* decoder will try to fulfill this request, but the resulting bitmap may
* have different dimensions that precisely what has been requested.
*
* @param _inputStreamJustDecode The input stream for bound decoding
* @param _inputStreamData The input stream for image decoding
* @param _preview true to generate a preview image, false to generate a high quality image
* @return
*/
private Bitmap decodeSampledBitmapFromResource(InputStream _inputStreamJustDecode,InputStream _inputStreamData) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(_inputStreamJustDecode, null, options);
float imageSize = options.outWidth * options.outHeight * 4;
float scaleFactor = 1;
long availableMem = getAvailableMemory(mContext);
//new image should not use more than 66% of the available memory
availableMem*=0.66f;
if(imageSize > availableMem){
scaleFactor = (float)availableMem / imageSize;
}
float maxDimen = options.outWidth > options.outHeight ? options.outWidth : options.outHeight;
//Don't let the image get to big.
if(maxDimen * scaleFactor > Constant.MAX_TEXTURE_SIZE ){
scaleFactor = Constant.MAX_TEXTURE_SIZE/maxDimen;
}
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, options.outWidth*scaleFactor,
options.outHeight*scaleFactor);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
// set other options
options.inPurgeable = true;
options.inPreferredConfig = Bitmap.Config.RGB_565;
return BitmapFactory.decodeStream(_inputStreamData,null,options);
}
/**
* Returns the currently available memory (ram) in bytes.
* @param _context The context.
* @return The available memory in bytes.
*/
public long getAvailableMemory(Context _context){
ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
ActivityManager activityManager = (ActivityManager) _context.getSystemService(Activity.ACTIVITY_SERVICE);
activityManager.getMemoryInfo(mi);
long availableMegs = mi.availMem;
return availableMegs;
}
Note: both input streams are from the same resource, but as you cant rewind the stream after decoding the bounds, you need a new stream.