I am currently pulling an image from the android gallery, which returns a uri to an activity for preview, then gets sent up to Parse database.
Images being sent up were far too big so I implemented the methods found in the android developer documentation
Here's what I'm working with
Uri selectedImage = data.getData();
InputStream imageStream = getContentResolver().openInputStream(selectedImage);
imageBitmap = getBitmapFromReturnedImage(imageStream, 800, 800);
// ByteArrayOutputStream stream = new ByteArrayOutputStream();
// LINE 2 imageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
// byte[] byteArray = stream.toByteArray();
//
// parseFile = new ParseFile("location_image.jpg", byteArray);
mImage.setImageBitmap(imageBitmap);
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;
}
public static Bitmap getBitmapFromReturnedImage(InputStream inputStream, int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(inputStream, null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(inputStream, null, options);
}
The commented "LINE 2", when that section isn't commented, returns a null pointer exception, which blows my mind. With that section commented, the imageview simply looks to be empty when I run the app.
Any clue what's going on?
You need to seek back to the start of the InputStream after reading the bounds before calling decodeStream for a second time, otherwise you will end up with an invalid Bitmap. The easiest way is just to close the stream and open it again.
Try this code (note function is no longer static to allow calling getContentResolver() and you have pass in a Uri not an InputStream):
public Bitmap getBitmapFromReturnedImage(Uri selectedImage, int reqWidth, int reqHeight) throws IOException {
InputStream inputStream = getContentResolver().openInputStream(selectedImage);
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(inputStream, null, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// close the input stream
inputStream.close();
// reopen the input stream
inputStream = getContentResolver().openInputStream(selectedImage);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeStream(inputStream, null, options);
}
call like this
Uri selectedImage = data.getData();
imageBitmap = getBitmapFromReturnedImage(selectedImage, 800, 800);