If you read the tutorial here you'll see google gives you a very comprehensive guide on how to scale bitmaps without excessive memory usage.
In particular, these two methods (from the tutorial):
public static Bitmap decodeSampledBitmapFromResource(File file, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(file, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(file, options);
}
public static 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;
}
Will accomplish your scaling whilst preserving aspect ratio.
The trick with these two methods is that the first decode operation is set to only decode the image's properties (dimensions and other information) as set by:
options.inJustDecodeBounds = true;
in which the new scale factor is calculated proportionally by the method calculateInSampleSize().
Then the image is decoded again, this time with
options.inJustDecodeBounds = false;
as well as the scale factor set, so the bitmap factory automatically scales whilst decoding, reducing the memory footprint.
Regarding what resolution the image needs to be decoded to, that really depends on your use-case. But, if the particular image does not need to be zoomed in later, you need no more than the device's physical screen size, which can be obtained via:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getRealSize(size);
in which object size
will hold the device's screen size.