While Sridhar's answer will work, one thing to keep in mind is that it requires first decoding the InputStream at full size, increasing memory usage. This can be an issue if the InputStream represents a very large image, because it can cause OutOfMemoryExceptions. Here's a method that will go directly from InputStream to scaled bitmap:
public static Bitmap scaledBitmapFromStream(Context context, InputStream tempIs) {
// Buffer the InputStream so that it can be accessed twice.
InputStream is = new BufferedInputStream(tempIs);
// Find the dimensions of the input image, and calculate the sampleSize.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(is, null, options);
options.inJustDecodeBounds = false;
// Calculate the inSampleSize. This is the factor that the image will be rescaled by.
options.inSampleSize = calculateInSampleSize(context, options.outWidth, options.outHeight);
// Reset the input stream, so it can be read again.
try {
is.reset();
} catch (IOException e) {
throw new RuntimeException("BufferedInputStream.reset() failed.", e);
}
// The 'options' parameter here tells the BitmapFactory to downscale.
Bitmap output = BitmapFactory.decodeStream(is, null, options);
// Close the input stream.
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return output;
}
/**
* How much you want to downsample will vary based on your application, but this implementation
* calculates a safe display size based on devices screen resolution and OpenGL MAX_TEXTURE_SIZE.
*/
public static int calculateInSampleSize(Context context, int inputWidth, int inputHeight) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
final int maxWidth = Math.min(displayMetrics.widthPixels, GLES20.GL_MAX_TEXTURE_SIZE);
final int maxHeight = Math.min(displayMetrics.heightPixels, GLES20.GL_MAX_TEXTURE_SIZE);
int inSampleSize = 1;
if (inputWidth > maxWidth || inputHeight > maxHeight) {
// Calculate ratios of height and width to requested height and width
final int heightRatio = Math.round((float) inputHeight / (float) maxHeight);
final int widthRatio = Math.round((float) inputWidth / (float) maxWidth);
// Choose the smallest ratio as inSampleSize value, this will guarantee
// a final image with both dimensions larger than or equal to the
// requested height and width.
inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
}
return inSampleSize;
}
See https://developer.android.com/training/displaying-bitmaps/load-bitmap.html for more information on inJustDecodeBounds and Bitmap sampling.