问题
I have looked all over for a solution to my problem and just can't seem to figure it out. I'm sure it is probably 1 or 2 simple lines and hopefully someone can steer me in the right direction.
In my app, a user can click a button that will open the gallery. Once they select an image, it will display that image in an ImageView within my app. That part is working perfectly fine. Originally, I just had it return a uri from the gallery and I would directly display that with this:
imageView1.setImageURI(myUri);
Well, obviously I am now running into the dreaded "Out Of Memory" error if the user reloads that page several times in a row so I'm having to clean up my code to scale down the image. I have done this by implementing a bitmap class that turns the image into a bitmap and scales it down for me. Now, my ImageView display code looks like this:
imageView1.setImageBitmap(bitmap1);
That part is working fine as well. HERE IS THE PROBLEM:
I convert the uri path to a string and then save that in a SharedPreference. This is so that when the user exits the application and the comes back later, the image that they set automatically displays. I convert the uri like this:
...
selectedImageUri = data.getData();
String selectedImagePath;
selectedImagePath = getPath(selectedImageUri);
...
The old method to retrieve the SharedPreference String, convert it to uri, then display it was working fine. (except for the Out Of Memory error of course) It looked like this:
Uri myUri = Uri.parse(selectedImagePath);
imageView1 = setImageURI(myUri);
"selectedImagePath" is obviously the String that I retrieved from the SharedPreference. Again, this worked fine but would throw the error if reloaded too many times.
The part that IS NOT WORKING now is when I try to implement the new Bitmap conversion so that I can scale the bitmap and not get the memory error. Here is the code for that:
Uri myUri = Uri.parse(selectedImagePath)
Bitmap bitmap = getThumbnail(myUri);
imageView1.setImageBitmap(bitmap);
This displays nothing. The original image choosing displays the image fine but when I return to this screen and it tries to parse the string from the SharedPreference and then convert it to the bitmap, nothing ever displays. The code for the "getThumbnail" method was taken directly from THIS POST --->
How to get Bitmap from an Uri?
It is the 3rd answer down.
Anyone have any ideas? Sorry for the super long post but I'd rather over explain my problem than not give enough info. Sorry if this was answered somewhere else. I've been hunting through other questions for hours and have just not found anything that solves my problem.
Thanks.
回答1:
I figured it out so here is what I did for anyone else having this unique problem. After the image is chosen from the gallery and it returns the intent, I got the data from that intent via this code:
selectedImageUri = data.getData();
Then I got the path from that via this:
selectedImagePath = getPath(selectedImageUri);
Which made a call to this "getPath" method:
public String getPath(Uri uri)
{
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx);
}
Then I saved "selectedImagePath" as a SharedPreference string.
Later, to retrieve that string and convert it back to showing an image, I first retrieved the SharedPreference string and converted it back to "selectedImagePath". Then, I set it in the ImageView like this:
targetImage = (ImageView)findViewById(R.id.imageView1);
targgetImage.setImageBitmap(decodeSampledBitmapFromResource(selectedImagePath, 200, 200));
which made a call to the following methods:
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 = 2;
if (height > reqHeight || width > reqWidth) {
if (width > height) {
inSampleSize = Math.round((float)height / (float)reqHeight);
} else {
inSampleSize = Math.round((float)width / (float)reqWidth);
}
}
return inSampleSize;
}
public static Bitmap decodeSampledBitmapFromResource(String resId,
int reqWidth, int reqHeight) {
// First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(resId, options);
// Calculate inSampleSize
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(resId, options);
}
It's a heck of a lot of code to do a fairly simple task but it works so I'm happy and moving on. Hopefully this will help someone else who needs to accomplish the same thing.
来源:https://stackoverflow.com/questions/11276579/converting-string-to-uri-to-bitmap-to-display-in-an-imageview