Android:从图库加载的位图在 ImageView 中旋转
当我将媒体库中的图像加载到位图中时,一切工作正常,除了垂直握住手机时用相机拍摄的图片会旋转,因此我总是得到水平图片,即使它在图像中显示为垂直。画廊。 为什么会这样以及如何正确加载它?
When I load an image from the media gallery into a Bitmap, everything is working fine, except that pictures that were shot with the camera while holding the phone vertically, are rotated so that I always get a horizontal picture even though it appears vertical in the gallery.
Why is that and how can I load it correctly?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(20)
我已经融化了@Timmmm 的答案和@Manuel。如果您执行此解决方案,您将不会遇到内存不足异常。
此方法检索图像方向:
因此,您可以在将图像加载到内存之前使用此方法调整图像大小。这样,您就不会遇到内存异常。
这对我来说非常有效。我希望这对其他人有帮助
I have melted @Timmmm answer and @Manuel. If you do this solution, you will not get a Run Out Of Memory Exception.
This method retrieves the image orientation:
Therefore, you would use this method to resize image before load it on memory. In that way, you will not get a Memory Exception.
This works perfectly for me. I hope this helps somebody else
之前的所有答案都使用 android.media.ExifInterface,它已经过时了。
在较新的 Android 版本 (AndroidX) 中,您可以这样做:
您还必须将
implementation 'androidx.exifinterface:exifinterface:1.3.6'
添加到您的 build.gradle 依赖项中。确保导入
androidx.exifinterface.media.ExifInterface
而不是过时的android.media.ExifInterface
。All the previous answers use the android.media.ExifInterface, which is outdated.
In newer Android versions (AndroidX), this is how you do it:
You also have to add
implementation 'androidx.exifinterface:exifinterface:1.3.6'
to your build.gradle dependencies.Make sure you import
androidx.exifinterface.media.ExifInterface
and not the outdatedandroid.media.ExifInterface
.Timmmm 对上述解决方案进行了改进,在最后添加了一些额外的缩放,以确保图像适合边界内:
Improving on the solution above by Timmmm to add some extra scaling at the end to ensure that the image fits within the bounds:
使用以下代码正确旋转图像:
Use the following code to rotate an image correctly:
我通过以下解决方法解决了该问题。请注意,我还缩放了图像,这是避免 OutOfMemoryExceptions 所必需的。
请注意,此解决方案不适用于肖像图像或颠倒图像(感谢 Timmmmm 的注意)。如果需要的话,上面的 Timmmm 解决方案可能是更好的选择,而且看起来也更优雅:https://stackoverflow.com/a/ 8914291/449918
干杯
I solved the problem with the following workaround. Note that I am also scaling the image, which was necessary to avoid OutOfMemoryExceptions.
Beware that this solution will not work properly with portrait images or opside-down images (thank you Timmmm for noting). Timmmm's solution above might be the better choice if that is required and it looks more elegant, too: https://stackoverflow.com/a/8914291/449918
Cheers
因此,举个例子......
首先您需要创建一个 ExifInterface:
然后您可以获取图像的方向:
以下是方向值的含义:
http://sylvana.net/jpegcrop/exif_orientation.html
因此,最重要的值为 3 、 6 和 8。
例如,如果方向为
ExifInterface.ORIENTATION_ROTATE_90
(即 6),您可以像这样旋转图像:但这只是一个简单的示例。我确信还有其他方法可以执行实际的旋转。但您也可以在 StackOverflow 上找到这些内容。
So, as an example...
First you need to create an ExifInterface:
You can then grab the orientation of the image:
Here's what the orientation values mean:
http://sylvana.net/jpegcrop/exif_orientation.html
So, the most important values are 3, 6 and 8.
If the orientation is
ExifInterface.ORIENTATION_ROTATE_90
(which is 6), for example, you can rotate the image like this:That's just a quick example, though. I'm sure there are other ways of performing the actual rotation. But you will find those on StackOverflow as well.
在我的例子中,使用这篇文章的帮助,用这段代码解决了这个问题:
希望它可以节省某人的时间!
Solved it in my case with this code using help of this post:
Hope it saves someone's time!
这是一个完整的解决方案(可在 Facebook SDK 的 Hackbook 示例中找到)。它的优点是不需要访问文件本身。如果您从内容解析器加载图像(例如,如果您的应用程序响应共享照片意图),这非常有用。
然后你可以得到一个旋转的Bitmap,如下所示。此代码还将图像缩小(不幸的是)到 MAX_IMAGE_DIMENSION。否则你可能会耗尽内存。
This is a full solution (found in the Hackbook example from the Facebook SDK). It has the advantage of not needing access to the file itself. This is extremely useful if you are loading an image from the content resolver thingy (e.g. if your app is responding to a share-photo intent).
And then you can get a rotated Bitmap as follows. This code also scales down the image (badly unfortunately) to MAX_IMAGE_DIMENSION. Otherwise you may run out of memory.
使用实用程序来完成繁重的工作。
9re 创建了一个简单的实用程序来处理处理 EXIF 数据并将图像旋转到正确方向的繁重工作。
您可以在此处找到实用程序代码:https://gist.github.com/9re/1990019< /a>
只需下载它,将其添加到项目的
src
目录中,然后使用ExifUtil.rotateBitmap()
即可获得正确的方向,如下所示:Use a Utility to do the Heavy Lifting.
9re created a simple utility to handle the heavy lifting of dealing with EXIF data and rotating images to their correct orientation.
You can find the utility code here: https://gist.github.com/9re/1990019
Simply download this, add it to your project's
src
directory and useExifUtil.rotateBitmap()
to get the correct orientation, like so:你看过图像的 EXIF 数据吗?它可能知道拍摄照片时相机的方向。
Have you looked at the EXIF data of the images? It may know the orientation of the camera when the picture was taken.
科特林代码:
Kotlin code:
这是因为画廊正确显示旋转图像,但不能正确显示 ImageView
看这里:
你需要这个:
its because gallery correct displaying rotated images but not ImageView
look at here:
and you need this:
经过多次尝试后才开始工作,感谢我再也找不到的帖子:-(
Exif 似乎总是可以工作,困难在于获取文件路径。我发现的代码在 4.4 之前的 API 和 4.4 之后的 API 之间有所不同。基本上4.4+ 的图片 URI 包含“com.android.providers” 对于这种类型的 URI,代码使用 DocumentsContract 获取图片 id,然后使用 ContentResolver 运行查询,而对于较旧的 SDK,代码直接进行查询。带有 ContentResolver 的 URI
如下是代码(抱歉我无法注明是谁发布的):
Got it to work after many attempts thanks to a post I can no longer find :-(
Exif seems to work always, the difficulty was to get the filepath. The code I found makes a different between API older than 4.4 and after 4.4. Basically the picture URI for 4.4+ contains "com.android.providers". For this type of URI, the code uses DocumentsContract to get the picture id and then runs a query using the ContentResolver, while for older SDK, the code goes straight to query the URI with the ContentResolver.
Here is the code (sorry I cannot credit who posted it):
您只需从 SD 卡读取路径并执行以下代码...它将在旋转后替换现有照片..
不:Exif 不适用于大多数设备,它会提供错误的数据,因此最好很难在保存到您想要的任何角度之前对旋转进行编码,您只需将 postRotate 中的角度值更改为您想要的任何角度值。
You can just read the path from sd card and do the following code...it'll Replace the existing photo after rotating it..
Not: Exif doesnt work on most of the devices, it gives the wrong data so it's good to hard code the rotating before saving to any degree you want to,You just have to change the angle value in postRotate to any you want to.
我改进了 Teo Inke 的答案。除非确实有必要,否则它不再旋转图像。它也更容易阅读,并且运行得更快。
I improved upon the answer by Teo Inke. It no longer rotates the image unless it is actually necessary. It is also easier to read, and should run faster.
您首先需要的是真实的文件路径
如果你做得很好,如果你正在使用 URI,那么使用这个方法
获取真正的路径:
例如提取您的位图:
如果您愿意,您可以使用decodeFile()。
现在您已经有了位图,并且真实的路径获得了图像的方向:
最后将其旋转到正确的位置,如下所示:
就这样,您现在已经将位图旋转到了正确的位置。
干杯。
The first thing you need is the real File path
If you have it great, if you are using URI then use this method to
get the real Path:
extract your Bitmap for example:
you can use decodeFile() instead if you wish.
Now that you have the Bitmap and the real Path get the Orientation of the Image:
and finally rotate it to the right position like so:
That's it , you now have the bitmap rotated to the right position.
cheers.
这可行,但可能不是最好的方法,但它可能会对某人有所帮助。
This works, but probably not the best way to do it, but it might help someone.
也许这会有所帮助(旋转90度)(这对我有用)
maybe this will help (rotate 90 degree)(this worked for me)
下面的方法根据方向缩放和旋转位图:
示例:
The methods below scales AND rotates the bitmap according to the orientation:
Example:
打开光标后应将其关闭。
这是一个例子。
The cursor should be closed after opening it.
Here is an example.