Android 将字符串转换为 uri 到位图以在 ImageView 中显示
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11276579/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Converting string to uri to bitmap to display in an ImageView
提问by dcabal
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.
我四处寻找解决我的问题的方法,但似乎无法弄清楚。我敢肯定它可能是 1 或 2 条简单的线条,希望有人能引导我朝着正确的方向前进。
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:
在我的应用程序中,用户可以单击一个按钮来打开图库。一旦他们选择了一个图像,它就会在我的应用程序中的 ImageView 中显示该图像。那部分工作得很好。最初,我只是让它从画廊返回一个 uri,我会直接用这个显示它:
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:
好吧,显然,如果用户连续多次重新加载该页面,我现在会遇到可怕的“内存不足”错误,因此我必须清理代码以缩小图像。我通过实现一个位图类来实现这一点,该类将图像转换为位图并为我缩小它。现在,我的 ImageView 显示代码如下所示:
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:
我将 uri 路径转换为字符串,然后将其保存在 SharedPreference 中。这样当用户退出应用程序并稍后返回时,他们设置的图像会自动显示。我像这样转换uri:
...
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:
检索 SharedPreference 字符串,将其转换为 uri,然后显示它的旧方法工作正常。(当然内存不足错误除外)它看起来像这样:
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.
“selectedImagePath”显然是我从 SharedPreference 中检索到的字符串。同样,这工作正常,但如果重新加载太多次会引发错误。
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 --->
这不显示任何内容。原始图像选择显示图像很好,但是当我返回到此屏幕并尝试从 SharedPreference 解析字符串然后将其转换为位图时,没有任何显示。“getThumbnail”方法的代码直接取自这篇文章--->
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.
谢谢。
回答by dcabal
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:
其中调用了这个“getPath”方法:
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.
然后我将“selectedImagePath”保存为 SharedPreference 字符串。
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:
后来,为了检索该字符串并将其转换回显示图像,我首先检索了 SharedPreference 字符串并将其转换回“selectedImagePath”。然后,我像这样在 ImageView 中设置它:
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.
完成一项相当简单的任务需要大量代码,但它有效,所以我很高兴并继续前进。希望这会帮助需要完成同样事情的其他人。