根据方向旋转读取 EXIF 元数据来检查图像是否旋转,然后创建新的位图并将其设置为 ImageView 控件。
[C#]
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
ImageView image = new ImageView(this);
var bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.test);
ExifInterface originalMetadata;
using (var stream = new MemoryStream())
{
bitmap.Compress(Bitmap.CompressFormat.Jpeg, 0, stream);
originalMetadata = new ExifInterface(stream);
}
int orientation = GetRotation(originalMetadata);
Matrix matrix = new Matrix();
if (orientation != 0)
{
matrix.PreRotate(orientation);
bitmap = Bitmap.CreateBitmap(bitmap, 0, 0, bitmap.Width, bitmap.Height, matrix, true);
}
image.SetImageBitmap(bitmap);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
}
读取旋转图像ExifData以获取方向。基于方向旋转然后创建新的位图并设置到 ImageView 控件。
获取 ExifData 方向值为 0。
测试设备为华为PRA、Infinix Pro
Visual Studio 2019
有什么办法可以解决这个问题吗?
var bitmap = BitmapFactory.DecodeResource(Resources, Resource.Drawable.test);
现在你有了一个位图。
但是位图不包含 exif 标头或方向信息。
将该位图压缩到流中,然后让 Exifinterface 从该流中读取。
bitmap.Compress(Bitmap.CompressFormat.Jpeg, 0, 流);
originalMetadata = new ExifInterface(stream);
但是由于位图不包含 exif 信息或方向信息,因此流也没有它们。
所以没有有效的 exif 信息,也没有方向信息。没什么。
相反,您应该从原始资源文件中读取 exif 信息。
首先,正如blackapps上面所说,当你将图片解码为Bitmap后,Exif信息将会丢失。
其次,android中的
Resources/
通常指的是资源。ExifInterface
仅从文件系统加载文件,而不是资源。毕竟,开发人员想要在资源上使用 ExifInterface
是完全没有意义的。资源是只读的,因此您无法使用 ExifInterface
修改资源中的 EXIF 标头。开发人员不会浪费用户的时间、CPU 和电池读取只读图像文件来提取元数据,而是提前这样做,将数据放在其他地方。
所以你可以将
test.jpg
移动到Assets
文件夹中,然后使用你的方法获取其EXIF数据:
var stream = Assets.Open("test.jpg");
originalMetadata = new ExifInterface(stream);
int orientation = GetRotation(originalMetadata);
**Xamarin.Android Project: Retrieving Image Rotation Angle**
This code snippet demonstrates how to extract the image rotation angle from a stream using the ExifInterface class from the Xamarin.AndroidX.ExifInterface NuGet package:
public int GetImageRotationAngle(Stream stream)
{
try
{
var exif = new ExifInterface(stream);
int orientation = exif.GetAttributeInt(ExifInterface.TagOrientation, ExifInterface.OrientationUndefined);
switch (orientation)
{
case ExifInterface.OrientationRotate90:
return 90;
case ExifInterface.OrientationRotate180:
return 180;
case ExifInterface.OrientationRotate270:
return 270;
default:
return 0;
}
}
catch (Exception ex)
{
Console.WriteLine($"Error in GetImageRoatation -> {ex}");
return 0;
}
}
**Explanation:**
1. GetImageRotationAngle(Stream stream): This method takes a Stream object containing the image data as input.
2. var exif = new ExifInterface(stream);: Creates a new ExifInterface instance using the provided stream.
3. int orientation = exif.GetAttributeInt(ExifInterface.TagOrientation, ExifInterface.OrientationUndefined);: Retrieves the orientation value from the EXIF data using the TagOrientation constant. If the tag is not found, ExifInterface.OrientationUndefined (0) is returned.
4. switch (orientation): A switch statement interprets the retrieved orientation value:
ExifInterface.OrientationRotate90: Indicates a 90-degree clockwise rotation.
ExifInterface.OrientationRotate180: Indicates a 180-degree rotation.
ExifInterface.OrientationRotate270: Indicates a 270-degree clockwise rotation.
default: If the orientation value is not recognized, a 0-degree rotation is assumed.
5. Exception Handling: The code includes a try-catch block to handle potential exceptions during the EXIF data access. If an error occurs, it logs the error message and returns 0 for rotation angle.
**Important Note:**
Ensure you're using the Xamarin.AndroidX.ExifInterface NuGet package for compatibility with the latest AndroidX libraries. Avoid using the older Android.Media.ExifInterface as it might have compatibility issues.